--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/TestEngine/src/TestModuleController.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,3101 @@
+/*
+* 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
+* CTestModuleController class member functions.
+*
+*/
+
+// INCLUDE FILES
+#include <e32svr.h>
+#include <stifinternal/TestServerClient.h>
+#include <StifLogger.h>
+#include "TestEngine.h"
+#include "TestModuleController.h"
+#include "Logging.h"
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES
+// None
+
+// CONSTANTS
+// None
+
+// MACROS
+// None
+
+// LOCAL CONSTANTS AND MACROS
+// None
+
+// MODULE DATA STRUCTURES
+// None
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ==================== LOCAL FUNCTIONS =======================================
+// None
+
+#define LOGGER iEngine->Logger()
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: CTestModuleController
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController::CTestModuleController( CTestEngine* aEngine ) :
+ CActive( CActive::EPriorityStandard ),
+ iEngine( aEngine ),
+ iState( ETestModuleIdle )
+ {
+ CActiveScheduler::Add( this );
+ iTestScripterController = NULL;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: const TName& aName: in: Test module name
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if memory allocation for iConfigFiles fails
+ Leaves if memory allocation for iTestCaseArray fails
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::ConstructL(
+ const TName& aName,
+ TBool aAfterReboot,
+ CTestScripterController* aTestScripterController )
+ {
+ iTestScripterController = aTestScripterController;
+ iTestScripterIndicator = 0;
+
+ iAfterReboot = aAfterReboot;
+
+ __TRACE ( KInit, ( _L( "Creating CTestModuleController [%S]" ), &aName ) );
+
+ iTestCaseArray = RPointerArray<TTestCaseArray>();
+
+ // Check aName length
+ if( aName.Length() <= 0 )
+ {
+ iEngine->LeaveWithNotifyL( KErrArgument );
+ }
+
+ // Remove optional '.DLL' from file name
+ TName name = aName;
+ name.LowerCase();
+ TParse parse;
+ parse.Set( name, NULL, NULL );
+
+ if ( parse.Ext() == _L(".dll") )
+ {
+ const TInt len = parse.Ext().Length();
+ name.Delete ( name.Length()-len, len );
+ }
+
+ iName = name.AllocL();
+
+ // HBufC to TPtrC
+ TPtrC atsName;
+
+ TFileName newNameBuffer;
+ TInt check = GenerateModuleName( iName->Des(), newNameBuffer );
+ if( check == KErrNone )
+ {
+ // Load the module(TestScripter)
+ atsName.Set( newNameBuffer );
+ }
+ else
+ {
+ // Load the module(Others)
+ atsName.Set( iName->Des() );
+ }
+
+ // Moved the implementation to a new function, ConstructASTLoggerL, due to
+ // CW 3.0 compiler error with multiple TRAPDs
+ TRAPD(err, ConstructASTLoggerL( atsName, aAfterReboot));
+
+ if( err != KErrNone )
+ {
+ __TRACE ( KError, ( _L( "CTestModuleController[%S]::ConstructL: Creation of ATS logger failed" ), iName ) );
+ iEngine->LeaveWithNotifyL( err, _L("Creation of ATS logger failed") );
+ }
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: ConstructASTLoggerL
+
+ Description: Construct ATS logger
+
+ Parameters: TDesC& atsName, TBool& aAfterReboot
+
+ Return Values: TInt
+
+ Errors/Exceptions: Leaves if error got from ATS logger NewL
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+TInt CTestModuleController::ConstructASTLoggerL( TDesC& atsName, TBool& aAfterReboot )
+ {
+ TRAPD( err, iAtsLogger = CAtsLogger::NewL( atsName, aAfterReboot ); );
+ if( err == KErrNotFound && aAfterReboot )
+ {
+ // If file does not exist, create new
+ aAfterReboot = EFalse;
+ iAtsLogger = CAtsLogger::NewL( atsName, aAfterReboot );
+ }
+ User::LeaveIfError( err );
+ iAtsLogger->SetFullReporting( ETrue );
+ if( aAfterReboot )
+ {
+ iAtsLogger->ContinueAfterRebootL();
+ }
+ else
+ {
+ // Begin reporting
+ iAtsLogger->BeginTestReportL();
+
+ // Begin test set
+ iAtsLogger->BeginTestSetL();
+ }
+ return KErrNone;
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: InitL
+
+ Description: Initialize test module.
+
+ Parameters: TFileName& aIniFile: in: Initialization file of Test Module
+ const TDesC& aConfigFile: in: Test case(config) file name(Used
+ in TestScripter case).
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if error got from Test Server
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::InitL( TFileName& aIniFile,
+ const TDesC& aConfigFile )
+ {
+ __TRACE( KInit, (_L( "Initialising test module [%S] with initialization file [%S]" ),
+ iName, &aIniFile ) );
+
+ // HBufC to TPtrC
+ TPtrC name( iName->Des() );
+
+ // Connect to server
+ TInt r = iServer.Connect( name, aConfigFile );
+
+ if ( r != KErrNone )
+ {
+ __TRACE( KError, ( CStifLogger::ERed, _L( "Can't connect to test module [%S], IniFile [%S]" ), &name, &aIniFile ) );
+ LeaveWithNotifyL( r, _L( "Can't connect to test module" ) );
+ }
+
+ // Open session
+ r = iModule.Open( iServer, aIniFile );
+ if ( r != KErrNone )
+ {
+ __TRACE( KError, ( CStifLogger::ERed, _L( "Can't open session to test module [%S], IniFile=[%S]" ), &name, &aIniFile ) );
+ LeaveWithNotifyL( r, _L( "Can't open session to test module" ) );
+ }
+
+ iErrorPrinter = CErrorPrinter::NewL( iEngine );
+ iErrorPrinter->StartL( iModule );
+
+ iServerStateHandler = CServerStateHandler::NewL( iEngine, this );
+ iServerStateHandler->StartL( iServer );
+ __TRACE( KInit, (_L( "Initialising test module [%S] with initialization file [%S] done" ),
+ iName, &aIniFile ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: CTestEngine object.
+ const TName& aName: in: module name.
+ TBool aAfterReboot: in: reboot indicator.
+ TBool aCreateTestScripterCont: in: Indications to
+ TestModule or TestScripter creation
+ CTestScripterController* aTestScripterController: in:
+ CTestEngine object.
+
+
+ Return Values: CTestModuleController* : pointer to created object
+
+ Errors/Exceptions: Leaves if called ConstructL method leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController* CTestModuleController::NewL(
+ CTestEngine* aEngine,
+ const TName& aName,
+ TBool aAfterReboot,
+ TBool aCreateTestScripterCont,
+ CTestScripterController* aTestScripterController )
+ {
+ // Create CTestScripterController
+ if( aCreateTestScripterCont )
+ {
+ CTestScripterController* testScripterController = NULL;
+ testScripterController = CTestScripterController::NewL(
+ aEngine, aName, aAfterReboot );
+ return testScripterController;
+ }
+
+
+ CTestModuleController* self =
+ new ( ELeave ) CTestModuleController( aEngine );
+ CleanupStack::PushL( self );
+ self->ConstructL( aName, aAfterReboot, aTestScripterController );
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: ~CTestModuleController
+
+ Description: Destructor
+
+ Deallocate all allocated resources
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController::~CTestModuleController()
+ {
+
+ // If CTestScripterController is created there is deleted base class(
+ // CTestModuleController) also and this has no iName.
+ if( iName )
+ {
+ __TRACE(KVerbose, (_L( "Deleting CTestModuleController [%S]" ), iName ) );
+ }
+
+ Cancel();
+
+ // If CTestScripterController is created there is deleted base class(
+ // CTestModuleController) also and this has no iAtsLogger.
+ if( iAtsLogger )
+ {
+ // End test set
+ TRAPD( err, iAtsLogger->EndTestSetL() );
+ // End AtsLogger reporting, has to be trapped in destructor
+ TRAPD( err2, iAtsLogger->EndTestReportL() );
+ if( ( err != KErrNone ) || ( err2 != KErrNone ) )
+ {
+ // Print error if error got from trap
+ __TRACE( KError, (
+ _L( "Destructor of CTestModuleController [%S]: XML log closing failed" ),
+ iName ) );
+ }
+ }
+
+ // Delete Atslogger
+ delete iAtsLogger;
+
+ // Stop error printer
+ delete iErrorPrinter;
+ iErrorPrinter = NULL;
+ // Delete server state handler
+ delete iServerStateHandler;
+ iServerStateHandler = NULL;
+
+ // Close RTestModule session
+ iModule.Close();
+ // Close RTestServer session
+ iServer.Close();
+
+ // Release the test case array
+ iTestCaseArray.Close();
+
+ // Release the config file array
+ iConfigFiles.Close();
+
+ // Release the config file array
+ iFailedEnumerateConfig.Reset();
+ iFailedEnumerateConfig.Close();
+
+ // Release the children array
+ iChildrenControllers.ResetAndDestroy();
+ iChildrenControllers.Close();
+
+ delete iName;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: AddConfigFileL
+
+ Description: Add config file
+
+ Parameters: TFileName& aConfigFile: in: Config file for Test Module
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if AppendL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::AddConfigFileL( TFileName& aConfigFile )
+ {
+ __TRACE( KInit,
+ ( _L( "CTestModuleController::AddConfigFileL [%S] aConfigFile=[%S]" ),
+ iName, &aConfigFile ) );
+ // Check that this config file does not already exists
+ for ( TInt i = 0; i < iConfigFiles.Count(); i++ )
+ {
+ // HBufC to TPtrC
+ TPtrC name( iConfigFiles[i]->Des() );
+ if ( KErrNone == aConfigFile.CompareF( name ) )
+ {
+ LeaveWithNotifyL( KErrAlreadyExists,
+ _L( "Adding config file failed: Config file already exists" ) );
+ }
+ }
+ HBufC* configFile = aConfigFile.AllocLC();
+
+ User::LeaveIfError( iConfigFiles.Append( configFile ) );
+ CleanupStack::Pop( configFile );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: RemoveConfigFileL
+
+ Description: Remove config file
+
+ Parameters: TFileName& aConfigFile: in: Config file name
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::RemoveConfigFileL( TFileName& aConfigFile )
+ {
+ __TRACE( KInit, (
+ _L( "CTestModuleController::RemoveConfigFileL [%S] aConfigFile=[%S]" ),
+ iName, &aConfigFile ) );
+ // Find config file
+ for ( TInt i = 0; i < iConfigFiles.Count(); i++ )
+ {
+ // HBufC to TPtrC
+ TPtrC name( iConfigFiles[i]->Des() );
+ if ( KErrNone == aConfigFile.CompareF( name ) )
+ {
+ HBufC* configFile = iConfigFiles[i];
+ iConfigFiles.Remove(i);
+ delete configFile;
+ // Cancel enumerate and free test cases
+ Cancel();
+ FreeTestCases();
+ return;
+ }
+ }
+
+ LeaveWithNotifyL( KErrNotFound,
+ _L( "Removing config file failed: Config file not found" ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: StartEnumerateL
+
+ Description: Start test case enumeration
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::StartEnumerateL()
+ {
+ __TRACE( KVerbose, (
+ _L( "CTestModuleController::StartEnumerateL [%S]" ), iName ) );
+ iTestCaseCount = 0;
+ iEnumerateCount = 0;
+ iFailedEnumerateCount = 0;
+ iFailedEnumerateConfig.Reset();
+ iEnumerateComplete = EFalse;
+
+ iState = ETestModuleEnumerateCases;
+
+ if ( iConfigFiles.Count() > 0 )
+ {
+ // HBufC to TPtrC
+ iEnumConfigFile.Set( iConfigFiles[0]->Des() );
+ }
+
+ __TRACE( KInit, (
+ _L( "Getting testcases from module [%S], test case file [%S]" ),
+ iName, &iEnumConfigFile ) );
+
+ SetActive();
+ iModule.EnumerateTestCases( iEnumConfigFile, iEnumResultPackage, iStatus );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: RunL
+
+ Description: RunL handles completed requests.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if iStatus is not KErrNone
+ Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::RunL()
+ {
+
+ // If CTestScripterController is used then move execution to the
+ // CTestScripterController size
+ if( iTestScripterController )
+ {
+ iTestScripterController->RunLEmulator( this );
+ return;
+ }
+
+ __TRACE( KVerbose, ( _L( "CTestModuleController::RunL [%S] [iStatus = %d]"),
+ iName, iStatus.Int() ) );
+
+ // Note:
+ // If test case not found there may be existing cases from previous
+ // enumerations, so those cases are valid. e.g. case: "add test case file",
+ // "add test case file that not exist" and "get test cases".
+
+ TInt ret( KErrNone );
+ // Check that request was successful
+ if( iStatus.Int() == KErrNone )
+ {
+ // Get enumerated test cases and append them to array
+ CFixedFlatArray<TTestCaseInfo>* testCases =
+ CFixedFlatArray<TTestCaseInfo>::NewL( iEnumResultPackage() );
+ CleanupStack::PushL( testCases );
+ ret = iModule.GetTestCases( *testCases );
+ __TRACE( KInit, ( _L( "RunL()'s GetTestCases method returns: %d" ), ret ) );
+
+ iTestCaseCount += testCases->Count();
+
+ if ( testCases->Count() == 0 )
+ {
+
+ if (iConfigFiles.Count() > 0)
+ {
+ __TRACE( KInit, ( CStifLogger::EBold,
+ _L( "Module [%S], test case file [%S] returned 0 cases" ),
+ iName, iConfigFiles[iEnumerateCount] ) );
+ }
+ else
+ {
+ __TRACE( KInit, ( CStifLogger::EBold,
+ _L( "Module [%S] without test case file, returned 0 cases" ),
+ iName ) );
+ }
+ iEngine->ErrorPrint( 1, _L("Someone returned 0 test cases. Check testengine log"));
+ iAtsLogger->CommentL( _L("Test module returned 0 test cases") );
+ }
+
+ // Store test cases for later use
+ User::LeaveIfError( iTestCaseArray.Append( testCases ) );
+ CleanupStack::Pop( testCases );
+
+ }
+ else
+ {
+ // Calculate failed enumeration count
+ iFailedEnumerateCount++;
+ // Add failed config(test case) file to array for later removing
+ if( iConfigFiles.Count() != NULL )
+ {
+ __TRACE( KError, (
+ CStifLogger::ERed,
+ _L( "Test case[%S] enumeration fails with error: %d" ),
+ iConfigFiles[iEnumerateCount], iStatus.Int() ) );
+ // Append
+ iFailedEnumerateConfig.Append( iConfigFiles[iEnumerateCount] );
+ }
+ }
+
+ iEnumerateCount++;
+
+ if ( iEnumerateCount < iConfigFiles.Count() )
+ {
+ // Continue enumeration
+ __TRACE( KInit, (
+ _L( "Getting testcases from module [%S], test case file [%S]" ),
+ iName, iConfigFiles[iEnumerateCount] ) );
+ SetActive();
+ iModule.EnumerateTestCases( *iConfigFiles[iEnumerateCount],
+ iEnumResultPackage, iStatus );
+ }
+ else if( iTestCaseCount == 0 )
+ {
+ // Total count of succesfully enumerations
+ iEnumerateCount -= iFailedEnumerateCount;
+ User::Leave( KErrNotFound );
+ }
+ else
+ {
+ // Total count of succesfully enumerations
+ iEnumerateCount -= iFailedEnumerateCount;
+ // Remove faulty config (test case) file(s)
+ for( TInt a= 0; a < iFailedEnumerateConfig.Count(); a++ )
+ {
+ TInt index( 0 );
+ // Find removed config(test case) file
+ index = iConfigFiles.Find( iFailedEnumerateConfig[a] );
+ if( index != KErrNotFound )
+ {
+ __TRACE( KInit, ( _L( "Removing test case file[%S]" ),
+ iConfigFiles[index] ) );
+ // Remove
+ iConfigFiles.Remove( index );
+ }
+ }
+
+ // All test cases enumerated
+ iState = ETestModuleEnumerateCasesCompleted;
+ iEnumerateComplete = ETrue;
+
+ iEngine->EnumerationCompleted( iTestCaseCount );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: TestCasesL
+
+ Description: Return Test Cases
+
+ Parameters: None
+
+ Return Values: CFixedFlatArray<TTestInfo>* :Pointer to created array
+
+ Errors/Exceptions: Leaves if NewL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CFixedFlatArray<TTestInfo>* CTestModuleController::TestCasesL()
+ {
+ CFixedFlatArray<TTestInfo>* testCases =
+ CFixedFlatArray<TTestInfo>::NewL( iTestCaseCount );
+
+ CleanupStack::PushL( testCases );
+
+ // Loop through all test cases from all config files
+ TInt totalCount = 0;
+ // HBufC to TPtrC
+ TPtrC name( iName->Des() );
+ for ( TInt i = 0; i < iEnumerateCount; i++ )
+ {
+ TTestInfo tmpInfo;
+ tmpInfo.iModuleName = name;
+ if ( iConfigFiles.Count() > 0 )
+ {
+ tmpInfo.iConfig = *iConfigFiles[i];
+ }
+
+ // Get test cases from iTestCaseArray at [i]
+ //if( (iTestCaseArray)[i] )
+ if ( iTestCaseArray.Count() > 0)
+ {
+ CFixedFlatArray<TTestCaseInfo>* tempTestCases = (iTestCaseArray)[i];
+ for ( TInt j = 0; j < tempTestCases->Count(); j++ )
+ {
+ tmpInfo.iTestCaseInfo = (*tempTestCases)[j];
+ // Set TestCaseInfo to testCases array
+ testCases->Set( totalCount, tmpInfo );
+ totalCount++;
+ }
+ }
+ }
+
+ CleanupStack::Pop( testCases );
+
+ return testCases;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: FreeTestCases
+
+ Description: Free memory used for test cases
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::FreeTestCases()
+ {
+ // Reset and destroy test cases
+ iTestCaseArray.ResetAndDestroy();
+ iTestCaseArray.Close();
+
+ iTestCaseCount = 0;
+ iEnumerateComplete = EFalse;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: DoCancel
+
+ Description: Cancel active request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::DoCancel()
+ {
+
+ // If CTestScripterController is used then move execution to the
+ // CTestScripterController size
+ if( iTestScripterController )
+ {
+ iTestScripterController->DoCancelEmulator( this );
+ return;
+ }
+
+ __TRACE( KVerbose, ( _L( "CTestModuleController::DoCancel [%S]" ), iName ) );
+
+ switch ( iState )
+ {
+ case ETestModuleEnumerateCases:
+ iModule.CancelAsyncRequest( ETestModuleEnumerateTestCases );
+ iEnumerateComplete = ETrue;
+ // Enumeration canceled, complete with KErrCancel
+ iEngine->EnumerationCompleted( 0, KErrCancel );
+
+ // Free allocated test cases because EnumerateTestCases was
+ // canceled
+ FreeTestCases();
+ break;
+ case ETestModuleIdle:
+ case ETestModuleEnumerateCasesCompleted:
+ default:
+ // DoCancel called in wrong state => Panic
+ _LIT( KTestModuleController, "CTestModuleController" );
+ User::Panic( KTestModuleController, EDoCancelDisorder );
+ break;
+ }
+
+ iAtsLogger->ErrorL( _L("Test case enumeration cancelled") );
+
+ iState = ETestModuleIdle;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: RunError
+
+ Description: Handle errors.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestModuleController::RunError( TInt aError )
+ {
+
+ // If CTestScripterController is used then move execution to the
+ // CTestScripterController size
+ if( iTestScripterController )
+ {
+ return iTestScripterController->RunErrorEmulator( aError, this );
+ }
+
+ __TRACE( KError, ( CStifLogger::ERed,
+ _L( "CTestModuleController::RunError [%S] aError=[%d]" ),
+ iName, aError ) );
+ if( aError == KErrNoMemory )
+ {
+ __TRACE( KError, ( CStifLogger::ERed,
+ _L( "No memory available. Test case file's size might be too big." ) ) );
+ }
+
+ iEnumerateComplete = ETrue;
+
+ iAtsLogger->ErrorL( _L("Test module did not return any test cases") );
+
+ _LIT( KErrorText, " did not return any test cases [error: ");
+ if( KErrorText().Length() + iName->Length() + 1 < KMaxName )
+ {
+ // Enumeration failed, print warning and complete with KErrNone
+ TName error( iName->Des() );
+ error.Append( KErrorText );
+ error.AppendNum( aError );
+ error.Append( _L("]") );
+ iEngine->ErrorPrint ( 0, error );
+
+ iEngine->EnumerationCompleted( 0, KErrNone );
+ }
+ else
+ {
+ // Cannot only print warning, complete with error
+ iEngine->EnumerationCompleted( 0, aError );
+ }
+
+ // Free allocated test cases because EnumerateTestCases failed
+ FreeTestCases();
+ iEnumerateComplete = ETrue;
+
+ return KErrNone;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: Server
+
+ Description: Return handle to Test Server
+
+ Parameters: TTestInfo& aTestInfo: in: Test info for this test case
+
+ Return Values: RTestServer& : Reference to RTestServer
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+RTestServer& CTestModuleController::Server( TTestInfo& /*aTestInfo*/ )
+ {
+ return iServer;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: GetFreeOrCreateModuleControllerL
+
+ Description: Return pointer to module controller.
+ Find module controller which does not run test case
+ and if this is not possible then create new one.
+ (Only for test scripter).
+
+ Parameters: TTestInfo& aTestInfo: in: Test info for this test case
+ TBool aUITestingSupport: in: Is UI testing mode enabled
+
+ Return Values: CTestModuleController* : pointer to module controller
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController* CTestModuleController::GetFreeOrCreateModuleControllerL(TTestInfo& /*aTestInfo*/, TBool /*aUItestingSupport*/)
+ {
+ return NULL;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: ModuleName
+
+ Description: Return the name of Test Module
+
+ Parameters: const TDesC& aModuleName: in Modulename
+
+ Return Values: const TDesC : Name of Test Module
+
+ Errors/Exceptions: None
+
+ Status: proposal
+
+-------------------------------------------------------------------------------
+*/
+const TDesC& CTestModuleController::ModuleName( const TDesC& /*aModuleName*/ )
+ {
+ return *iName;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: EnumerationComplete
+
+ Description: Is enumeration of test cases complete.
+
+ Parameters: None
+
+ Return Values: TBool ETrue: Enumeration of test cases is complete
+ EFalse: Enumeration is not complete
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestModuleController::EnumerationComplete()
+ {
+ return iEnumerateComplete;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: LeaveWithNotifyL
+
+ Description: Print out info and leave.
+
+ Parameters: TInt aCode: in: Error code
+ const TDesC& aText: in: Test info
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::LeaveWithNotifyL( TInt aCode, const TDesC& aText )
+ {
+
+ __TRACE( KError, ( CStifLogger::ERed, aText ) );
+ if( iAtsLogger )
+ {
+ iAtsLogger->ErrorL( aText );
+ }
+ iEngine->LeaveWithNotifyL( aCode );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: CaseCreated
+
+ Description: Increases the value of iTestCaseCounter
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::CaseCreated()
+ {
+ // Number of ongoing testcases
+ iTestCaseCounter++;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: CaseFinished
+
+ Description: Decreases the value of iTestCaseCounter and deletes this pointer
+ only in test module crash situations (KErrServerTerminated -15)
+
+ Parameters: None:
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::CaseFinished()
+ {
+ // Number of ongoing testcases
+ iTestCaseCounter--;
+
+ // iTestModuleCrashDetected tells is TestModuleController cloned or not
+ // TestModuleController is cloned only when testmodule is crashed with KErrServerTerminated -15
+ if (iTestCaseCounter == 0 && iTestModuleCrashDetected)
+ {
+ // Delete this in case where it has been replaced with it clone
+ // and no one have pointer to this. This happens only when test module
+ // crashes
+ delete this;
+ // Mem::Fill(this, sizeof(CTestModuleController), 0xa1a1a1a1);
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: CloneL
+
+ Description:
+
+ Parameters:
+
+ Return Values:
+
+ Errors/Exceptions:
+
+ Status:
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController* CTestModuleController::CloneL(
+ CTestModuleController* aTestModuleController,
+ TBool aAfterReset,
+ CTestScripterController* aTestScripterController )
+ {
+ __TRACE( KInit, ( _L( "Cloning CTestModuleController" ) ) );
+
+
+ TName crashModuleName;
+ crashModuleName = aTestModuleController->ModuleName( crashModuleName );
+
+ CTestModuleController* clone = CTestModuleController::NewL( iEngine, crashModuleName, aAfterReset, EFalse, aTestScripterController );
+
+ clone->InitL( aTestModuleController->iInifile, KNullDesC );
+
+ // Give ATS logger to clone
+ clone->iAtsLogger = iAtsLogger;
+ iAtsLogger = NULL;
+
+ for ( TInt i = 0; i < aTestModuleController->iConfigFiles.Count(); i++ )
+ {
+ TPtrC configFile = aTestModuleController->iConfigFiles[i]->Des();
+ TFileName config = configFile;
+ clone->AddConfigFileL( config );
+ }
+
+ iTestModuleCrashDetected = ETrue;
+
+ __TRACE( KVerbose, ( _L( "Cloning of CTestModuleController finished " ) ) );
+ return clone;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: DeleteModuleController
+
+ Description: In that class this method does nothing. It is implemented
+ in CTestScripterController.
+
+ Parameters: CTestModuleController* aRealModuleController: not used
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status:
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::DeleteModuleController(CTestModuleController* /*aRealModuleController*/)
+ {
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: RemoveModuleController
+
+ Description: In that class this method does nothing. It is implemented
+ in CTestScripterController.
+
+ Parameters: CTestModuleController* aRealModuleController: not used
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status:
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::RemoveModuleController(CTestModuleController* /*aRealModuleController*/)
+ {
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestModuleController
+
+ Method: EnumerateSynchronously
+
+ Description: Enumerates test module controller. Used only when new
+ test module controller is created during test case
+ execution.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status:
+
+-------------------------------------------------------------------------------
+*/
+void CTestModuleController::EnumerateSynchronously(void)
+ {
+ TInt i;
+ TInt cfgfiles = iConfigFiles.Count();
+ __TRACE(KInit, (_L("Module controller will enumerate synchronously [%d] config files"), cfgfiles));
+
+ for(i = 0; i < cfgfiles; i++)
+ {
+ TRequestStatus status;
+ iModule.EnumerateTestCases(*iConfigFiles[i],
+ iEnumResultPackage,
+ status);
+ User::WaitForRequest(status);
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CTestScripterController class member
+ functions.
+
+-------------------------------------------------------------------------------
+*/
+#define LOGGER iEngine->Logger()
+
+// ================= MEMBER FUNCTIONS =========================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: CTestScripterController
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to CTestEngine
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestScripterController::CTestScripterController( CTestEngine* aEngine ) :
+ CTestModuleController( aEngine )
+ {
+ // None
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: const TName& aName: in: Test module name
+ TBool aAfterReboot: in: Reboot indication
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::ConstructL( const TName& aName,
+ TBool aAfterReboot )
+ {
+ __TRACE( KInit, (
+ _L( "NOTE: Test module is TestScripter and each test case(config) file(s) will have own server(s)" ) ) );
+
+ // Remove optional '.DLL' from file name
+ TName name = aName;
+ name.LowerCase();
+ TParse parse;
+ parse.Set( name, NULL, NULL );
+
+ if ( parse.Ext() == _L(".dll") )
+ {
+ const TInt len = parse.Ext().Length();
+ name.Delete ( name.Length()-len, len );
+ }
+
+ iName = name.AllocL();
+
+ iAfterReboot = aAfterReboot;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: InitL
+
+ Description: Initialize test module.
+
+ Parameters: TFileName& aIniFile: in: Initialization file of Test Module
+ const TDesC& aConfigFile: in: Test case(config) file name(Used
+ in TestScripter case).
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::InitL( TFileName& aIniFile,
+ const TDesC& /*aConfigFile*/ )
+ {
+ // Take initialization file of Test Module
+ iInifile = aIniFile;
+
+ // Just empty, don't create TestServer operations. TestServer
+ // creation will be do in AddTestCaseFile()-method.
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: CTestEngine* aEngine: in: CTestEngine object
+ const TName& aName: in: Test module name
+ TBool aAfterReboot: in: Reboot indication
+
+ Return Values: CTestScripterController* : pointer to created object
+
+ Errors/Exceptions: Leaves if called ConstructL method leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestScripterController* CTestScripterController::NewL( CTestEngine* aEngine,
+ const TName& aName,
+ TBool aAfterReboot )
+ {
+ CTestScripterController* self =
+ new ( ELeave ) CTestScripterController( aEngine );
+ CleanupStack::PushL( self );
+ self->ConstructL( aName, aAfterReboot );
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: ~CTestScripterController
+
+ Description: Destructor
+
+ Deallocate all allocated resources. Delete CTestScripterController's
+ CTestModuleController(s). After this is deleted base class also, see:
+ CTestModuleController::~CTestModuleController().
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestScripterController::~CTestScripterController()
+ {
+ // Delete CTestScripterController(s).
+ iTestScripter.ResetAndDestroy();
+ iTestScripter.Close();
+
+ // After this is deleted base class also, see:
+ // CTestModuleController::~CTestModuleController().
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: AddConfigFileL
+
+ Description: Add config file.
+ - Creates CTestModuleController(Gives test case file name)
+ - Initializes CTestModuleController( creates a server session)
+ - Adds config file
+
+ Parameters: TFileName& aConfigFile: in: Config file for TestScripter
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if AppendL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::AddConfigFileL( TFileName& aConfigFile )
+ {
+ // Check that this config file does not already exists
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ for ( TInt i = 0; i < iTestScripter[a]->iConfigFiles.Count(); i++ )
+ {
+ // HBufC to TPtrC
+ TPtrC name( iTestScripter[a]->iConfigFiles[i]->Des() );
+ if ( KErrNone == aConfigFile.CompareF( name ) )
+ {
+ LeaveWithNotifyL( KErrAlreadyExists,
+ _L( "Adding config file failed: Config file already exists" ) );
+ }
+ }
+ }
+
+ __TRACE( KInit, (
+ _L( "CTestScripterController::AddConfigFileL aConfigFile=[%S]" ) ,
+ &aConfigFile ) );
+
+ HBufC* testScripterAndTestCaseFile = NULL; // InitL() takes TFileName
+ testScripterAndTestCaseFile = CreateTestScripterNameL(
+ aConfigFile,
+ testScripterAndTestCaseFile );
+ // Add to cleanup stack here, because CreateTestScripterNameL needs to be
+ // trapped in other methods.
+ CleanupStack::PushL( testScripterAndTestCaseFile );
+
+ //Create server and active object(This uses CTestModuleController::InitL())
+ CTestModuleController* module = CTestModuleController::NewL(
+ iEngine,
+ testScripterAndTestCaseFile->Des(),
+ iAfterReboot, EFalse, this );
+ CleanupStack::PopAndDestroy( testScripterAndTestCaseFile );
+ CleanupStack::PushL( module );
+
+ User::LeaveIfError( iTestScripter.Append( module ) );
+
+ // Now is used TestScripter so give test case file also(used
+ // in caps modifier cases).
+ TRAPD ( err, module->InitL( iInifile, aConfigFile ) );
+ if( err != KErrNone )
+ {
+ __TRACE( KInit, ( _L( "InitL fails with error: %d" ), err ) );
+ User::Leave( err );
+ }
+
+ module->AddConfigFileL( aConfigFile );
+
+ CleanupStack::Pop( module );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: RemoveConfigFileL
+
+ Description: Remove config file
+
+ Parameters: TFileName& aConfigFile: in: Config file name
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::RemoveConfigFileL( TFileName& aConfigFile )
+ {
+ __TRACE( KInit, ( _L( "CTestScripterController::RemoveConfigFileL" ) ) );
+
+ HBufC* testScripterAndTestCaseFile = NULL;
+ testScripterAndTestCaseFile = CreateTestScripterNameL( aConfigFile,
+ testScripterAndTestCaseFile );
+ // Add to cleanup stack here, because CreateTestScripterNameL needs to be
+ // trapped in other methods.
+ CleanupStack::PushL( testScripterAndTestCaseFile );
+
+ // Get correct iTestScripter
+ TInt index( -1 );
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ if( ( iTestScripter[a]->iName->CompareF(
+ testScripterAndTestCaseFile->Des() ) == KErrNone ) )
+ {
+ index = a;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( testScripterAndTestCaseFile );
+
+ if( index == -1 )
+ {
+ LeaveWithNotifyL( KErrNotFound,
+ _L( "Removing config file failed: Config file not found" ) );
+ }
+
+ __TRACE( KInit, (
+ _L( "CTestScripterController[%S]::RemoveConfigFileL aConfigFile=[%S]"),
+ iTestScripter[index]->iName, &aConfigFile ) );
+
+ // Find config file
+ for ( TInt i = 0; i < iTestScripter[index]->iConfigFiles.Count(); i++ )
+ {
+ // HBufC to TPtrC
+ TPtrC name( iTestScripter[index]->iConfigFiles[i]->Des() );
+ if ( KErrNone == aConfigFile.CompareF( name ) )
+ {
+ HBufC* configFile = iTestScripter[index]->iConfigFiles[i];
+ iTestScripter[index]->iConfigFiles.Remove(i);
+ delete configFile;
+ // Cancel enumerate and free test cases
+ Cancel();
+ FreeTestCases();
+ // Testcasefile(config) is found, so we can return
+ return;
+ }
+ }
+
+ LeaveWithNotifyL( KErrNotFound,
+ _L( "Removing config file failed: Config file not found" ) );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: StartEnumerateL
+
+ Description: Start test case enumeration
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: LeaveWithNotifyL if no test case added.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::StartEnumerateL()
+ {
+ if( iTestScripter.Count() <= 0 )
+ {
+ RDebug::Print(
+ _L( "There is no test case file for TestScripter registered yet. Enumeraton aborted." ) );
+ LeaveWithNotifyL( KErrNotFound,
+ _L( "There is no test case file for TestScripter registered yet. Enumeraton aborted." ) );
+ return;
+ }
+
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ __TRACE( KVerbose, (
+ _L( "CTestScripterController[%S]::StartEnumerateL" ),
+ iTestScripter[a]->iName ) );
+ iTestScripter[a]->iTestCaseCount = 0;
+ iTestScripter[a]->iEnumerateCount = 0;
+ iTestScripter[a]->iFailedEnumerateCount = 0;
+ iTestScripter[a]->iFailedEnumerateConfig.Reset();
+ iTestScripter[a]->iEnumerateComplete = EFalse;
+
+ iTestScripter[a]->iState = ETestModuleEnumerateCases;
+
+ if ( iTestScripter[a]->iConfigFiles.Count() > 0 )
+ {
+ // HBufC to TPtrC
+ iTestScripter[a]->iEnumConfigFile.Set(
+ iTestScripter[a]->iConfigFiles[0]->Des() );
+ }
+
+ __TRACE( KInit, (
+ _L( "Getting testcases from module [%S], test case file[%S]" ),
+ iTestScripter[a]->iName, &iTestScripter[a]->iEnumConfigFile ) );
+
+ iTestScripter[a]->SetActive();
+ iTestScripter[a]->iModule.EnumerateTestCases(
+ iTestScripter[a]->iEnumConfigFile,
+ iTestScripter[a]->iEnumResultPackage,
+ iTestScripter[a]->iStatus );
+ } // End of for-loop
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: GetCurrentIndex
+
+ Description: Get current CTestScripterController.
+
+ Parameters: CTestModuleController* aTestModuleController: in:
+ Pointer current to CTestModuleController
+
+ Return Values: KErrNotFound returned if CTestModuleController not found
+ else current index returned.
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestScripterController::GetCurrentIndex( CTestModuleController*
+ aTestModuleController )
+ {
+ // Get correct iTestScripter
+ return iTestScripter.Find( aTestModuleController );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: RunL
+
+ Description: RunL handles completed requests.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::RunL()
+ {
+ // Should never come here because one TestScripter have one test case
+ // file per server session.
+ // CTestScripterController's base class is an active object but this class
+ // not used as an active object. So there not used RunL => Panic.
+
+ User::Panic( _L( "CTestScripterController::RunL()" ), KErrCorrupt );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: RunLEmulator
+
+ Description: RunLEmulator handles completed requests(Emulates RunL()).
+ This is called from CTestModuleController::RunL.
+
+ Parameters: CTestModuleController* aTestModuleController: in: pointer to
+ CTestModuleController.
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::RunLEmulator( CTestModuleController*
+ aTestModuleController )
+ {
+ iTestScripterIndicator++;
+ TInt index = GetCurrentIndex( aTestModuleController );
+ if( index < KErrNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ __TRACE( KVerbose, (
+ _L( "CTestScripterController[%S]::RunLEmulator [iStatus = %d]"),
+ iTestScripter[index]->iName, iTestScripter[index]->iStatus.Int() ) );
+
+ // Note:
+ // If test case not found there may be existing cases from previous
+ // enumerations, so those cases are valid. e.g. case: "add test case file",
+ // "add test case file that not exist" and "get test cases".
+
+ TInt ret( KErrNone );
+
+ // Check that request was successful
+ if( iTestScripter[index]->iStatus.Int() == KErrNone )
+ {
+ // Get enumerated test cases and append them to array
+ CFixedFlatArray<TTestCaseInfo>* testCases =
+ CFixedFlatArray<TTestCaseInfo>::NewL(
+ iTestScripter[index]->iEnumResultPackage() );
+ CleanupStack::PushL( testCases );
+ ret = iTestScripter[index]->iModule.GetTestCases( *testCases );
+ __TRACE( KInit, (
+ _L( "RunL()'s GetTestCases method returns: %d" ), ret ) );
+
+ iTestScripter[index]->iTestCaseCount += testCases->Count();
+
+ if ( testCases->Count() == 0 )
+ {
+
+ if (iTestScripter[index]->iConfigFiles.Count() > 0)
+ {
+ __TRACE( KInit, (
+ CStifLogger::EBold,
+ _L( "Module [%S], test case file[%S] returned 0 cases" ),
+ iTestScripter[index]->iName,
+ iTestScripter[index]->iConfigFiles[iTestScripter[index]->iEnumerateCount] ) );
+ }
+ else
+ {
+ __TRACE( KInit, ( CStifLogger::EBold,
+ _L("Module [%S] without test case file, returned 0 cases"),
+ iTestScripter[index]->iName ) );
+ }
+ iTestScripter[index]->iEngine->ErrorPrint( 1,
+ _L("Someone returned 0 test cases. Check testengine log"));
+ iTestScripter[index]->iAtsLogger->CommentL(
+ _L("Test module returned 0 test cases") );
+ }
+
+ // Store test cases for later use
+ User::LeaveIfError( iTestScripter[index]->iTestCaseArray.Append(
+ testCases ) );
+ CleanupStack::Pop( testCases );
+
+ }
+ else
+ {
+ // Calculate failed enumeration count
+ iTestScripter[index]->iFailedEnumerateCount++;
+ // Add failed config(test case) file to array for later removing
+ if( iTestScripter[index]->iConfigFiles.Count() != NULL )
+ {
+ __TRACE( KError, (
+ CStifLogger::ERed,
+ _L( "Test case[%S] enumeration fails with error: %d" ),
+ iTestScripter[index]->iConfigFiles[iTestScripter[index]->iEnumerateCount],
+ iTestScripter[index]->iStatus.Int() ) );
+ // Append
+ iTestScripter[index]->iFailedEnumerateConfig.Append(
+ iTestScripter[index]->iConfigFiles[iTestScripter[index]->iEnumerateCount] );
+ }
+ }
+
+ TInt count = iTestScripter.Count();
+
+ // All TestScripter enumerations is finished for cleaning if necessarily
+ // and complete request up to engine.
+ if( count == iTestScripterIndicator )
+ {
+ TInt testCaseCount( 0 );
+ for( TInt a = 0; a < count; a++ )
+ {
+ // Remove faulty config (test case) file(s) and
+ // iEnumerateCount not increased.
+ if( iTestScripter[a]->iTestCaseCount == 0 )
+ {
+ // Check that test case file is not allready removed.
+ if( iTestScripter[a]->iConfigFiles.Count() != 0 )
+ {
+ iTestScripter[a]->iConfigFiles.Remove( 0 );
+ }
+ }
+ else
+ {
+ iTestScripter[a]->iEnumerateCount++;
+ testCaseCount += iTestScripter[a]->iTestCaseCount;
+ }
+
+ // All test cases enumerated
+ iTestScripter[a]->iState = ETestModuleEnumerateCasesCompleted;
+ iTestScripter[a]->iEnumerateComplete = ETrue;
+ }
+
+ iTestScripterIndicator = 0; // Initialization back to 0, enumerations
+ // are done at this run.
+ iEngine->EnumerationCompleted( testCaseCount );
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: TestCasesL
+
+ Description: Return Test Cases
+
+ Parameters: None
+
+ Return Values: CFixedFlatArray<TTestInfo>*: Pointer to created array
+
+ Errors/Exceptions: Leaves if NewL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CFixedFlatArray<TTestInfo>* CTestScripterController::TestCasesL()
+ {
+ TInt testCaseCount( 0 );
+ for( TInt i = 0; i < iTestScripter.Count(); i++ )
+ {
+ testCaseCount += iTestScripter[i]->iTestCaseCount;
+ }
+
+ CFixedFlatArray<TTestInfo>* testCases =
+ CFixedFlatArray<TTestInfo>::NewL( testCaseCount );
+
+ CleanupStack::PushL( testCases );
+
+ // Loop through all test cases from all config files
+ TInt totalCount = 0;
+ // HBufC to TPtrC
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ TPtrC name( iTestScripter[a]->iName->Des() );
+ for ( TInt i = 0; i < iTestScripter[a]->iEnumerateCount; i++ )
+ {
+ TTestInfo tmpInfo;
+ tmpInfo.iModuleName = name;
+ if ( iTestScripter[a]->iConfigFiles.Count() > 0 )
+ {
+ tmpInfo.iConfig = *iTestScripter[a]->iConfigFiles[i];
+ }
+
+ // Get test cases from iTestCaseArray at [i]
+ if( (iTestScripter[a]->iTestCaseArray)[i] )
+ {
+ CFixedFlatArray<TTestCaseInfo>* tempTestCases =
+ (iTestScripter[a]->iTestCaseArray)[i];
+ for ( TInt j = 0; j < tempTestCases->Count(); j++ )
+ {
+ tmpInfo.iTestCaseInfo = (*tempTestCases)[j];
+ // Set TestCaseInfo to testCases array
+ testCases->Set( totalCount, tmpInfo );
+ totalCount++;
+ }
+ }
+ }
+ }
+
+ CleanupStack::Pop( testCases );
+
+ return testCases;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: FreeTestCases
+
+ Description: Free memory used for test cases
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::FreeTestCases()
+ {
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ // Reset and destroy test cases
+ iTestScripter[a]->iTestCaseArray.ResetAndDestroy();
+ iTestScripter[a]->iTestCaseArray.Close();
+
+ iTestScripter[a]->iTestCaseCount = 0;
+ iTestScripter[a]->iEnumerateComplete = EFalse;
+ }
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: DoCancel
+
+ Description: Cancel active request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::DoCancel()
+ {
+ // Should never come here because one TestScripter have one test case
+ // file per server session.
+ // CTestScripterController's base class is an active object but this class
+ // not used as an active object. So there not used DoCancel => Panic.
+
+ User::Panic( _L( "CTestScripterController::DoCancel()" ), KErrCorrupt );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: DoCancelEmulator
+
+ Description: Cancel active request(Emulates DoCancel)
+ This is called from CTestModuleController::DoCancel.
+
+ Parameters: CTestModuleController* aTestModuleController: in: pointer to
+ CTestModuleController.
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::DoCancelEmulator(
+ CTestModuleController* aTestModuleController )
+ {
+ TInt index = GetCurrentIndex( aTestModuleController );
+ if( index < KErrNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ __TRACE( KVerbose, (
+ _L( "CTestScripterController[%S]::RunDoCancelEmulator" ),
+ iTestScripter[index]->iName ) );
+
+ switch ( iTestScripter[index]->iState )
+ {
+ case ETestModuleEnumerateCases:
+ iTestScripter[index]->iModule.CancelAsyncRequest(
+ ETestModuleEnumerateTestCases );
+ iTestScripter[index]->iEnumerateComplete = ETrue;
+ // Enumeration canceled, complete with KErrCancel
+ iTestScripter[index]->iEngine->EnumerationCompleted(
+ 0, KErrCancel );
+
+ // Free allocated test cases because EnumerateTestCases was
+ // canceled
+ FreeTestCases();
+ break;
+ case ETestModuleIdle:
+ case ETestModuleEnumerateCasesCompleted:
+ default:
+ // DoCancel called in wrong state => Panic
+ _LIT( KTestModuleController, "CTestModuleController" );
+ User::Panic( KTestModuleController, EDoCancelDisorder );
+ break;
+ }
+
+ iTestScripter[index]->iAtsLogger->ErrorL(
+ _L("Test case enumeration cancelled") );
+ iTestScripter[index]->iState = ETestModuleIdle;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: RunError
+
+ Description: Handle errors.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestScripterController::RunError( TInt /*aError*/ )
+ {
+ // Should never come here because one TestScripter have one test case
+ // file per server session.
+ // CTestScripterController's base class is an active object but this class
+ // not used as an active object. So there not used RunError => Panic.
+
+ User::Panic( _L( "CTestScripterController::RunError()" ), KErrCorrupt );
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: RunErrorEmulator
+
+ Description: Handle errors(Emulates RunError).
+ This is called from CTestModuleController::RunError.
+
+ Parameters: TInt aError: in: Symbian OS error: Error code.
+ CTestModuleController* aTestModuleController: in: pointer to
+ CTestModuleController.
+
+ Return Values: TInt KErrNone: Always returned KErrNone
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CTestScripterController::RunErrorEmulator( TInt aError,
+ CTestModuleController* aTestModuleController )
+ {
+ TInt index = GetCurrentIndex( aTestModuleController );
+ if( index < KErrNone )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ __TRACE( KError, ( CStifLogger::ERed,
+ _L( "CTestScripterController[%S]::RunErrorEmulator aError=[%d]" ),
+ iTestScripter[index]->iName, aError ) );
+ if( aError == KErrNoMemory )
+ {
+ __TRACE( KError, ( CStifLogger::ERed,
+ _L( "No memory available. Test case file's size might be too big." ) ) );
+ }
+
+ iTestScripter[index]->iEnumerateComplete = ETrue;
+
+ iTestScripter[index]->iAtsLogger->ErrorL(
+ _L("Test module did not return any test cases") );
+
+ _LIT( KErrorText, " did not return any test cases [error: ");
+ if( KErrorText().Length() +
+ iTestScripter[index]->iName->Length() +
+ 1 < KMaxName )
+ {
+ // Enumeration failed, print warning and complete with KErrNone
+ TName error( iTestScripter[index]->iName->Des() );
+ error.Append( KErrorText );
+ error.AppendNum( aError );
+ error.Append( _L("]") );
+ iEngine->ErrorPrint ( 0, error );
+
+ iTestScripter[index]->iEngine->EnumerationCompleted( 0, KErrNone );
+ }
+ else
+ {
+ // Cannot only print warning, complete with error
+ iTestScripter[index]->iEngine->EnumerationCompleted( 0, aError );
+ }
+
+ // Free allocated test cases because EnumerateTestCases failed
+ FreeTestCases();
+ iTestScripter[index]->iEnumerateComplete = ETrue;
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: EnumerationComplete
+
+ Description: Is enumeration of test cases complete.
+
+ Parameters: None
+
+ Return Values: TBool ETrue: Enumeration of test cases is complete
+ EFalse: Enumeration is not complete
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TBool CTestScripterController::EnumerationComplete()
+ {
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ if( !iTestScripter[a]->iEnumerateComplete )
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: Server
+
+ Description: Return handle to Test Server
+
+ Parameters: TTestInfo& aTestInfo: in: Test info for this test case
+
+ Return Values: RTestServer& : Reference to RTestServer
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+RTestServer& CTestScripterController::Server( TTestInfo& aTestInfo )
+ {
+ HBufC* testScripterAndTestCaseFile = NULL;
+ TRAPD( ret, testScripterAndTestCaseFile = CreateTestScripterNameL(
+ aTestInfo.iConfig,
+ testScripterAndTestCaseFile ) );
+ // Add to cleanup stack here, because CreateTestScripterNameL needs to be
+ // trapped in other methods.
+ CleanupStack::PushL( testScripterAndTestCaseFile );
+ if( ret != KErrNone )
+ {
+ User::Panic(
+ _L( "CTestScripterController::Server(): CreateTestScripterNameL" ),
+ ret );
+ }
+
+ // Get correct handle
+ TInt index( KErrNotFound );
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ if( testScripterAndTestCaseFile->Des() ==
+ iTestScripter[a]->iName->Des() )
+ {
+ index = a;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( testScripterAndTestCaseFile );
+
+ if( index == KErrNotFound )
+ {
+ User::Panic(
+ _L( "CTestScripterController::Server(): Index not found" ),
+ KErrNotFound );
+ }
+
+ // Return handle
+ return iTestScripter[index]->iServer;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: GetFreeOrCreateModuleControllerL
+
+ Description: Return pointer to test module controller.
+ Find controller which does not run test case
+ and if this is not possible then create new one.
+
+ Parameters: TTestInfo& aTestInfo: in: Test info for this test case
+ TBool aUITestingSupport: in: Is UI testing mode enabled
+
+ Return Values: CTestModuleController* : pointer to controller
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CTestModuleController* CTestScripterController::GetFreeOrCreateModuleControllerL(TTestInfo& aTestInfo, TBool aUITestingSupport)
+ {
+ HBufC* testScripterAndTestCaseFile = NULL;
+ TRAPD(ret, testScripterAndTestCaseFile = CreateTestScripterNameL(aTestInfo.iConfig, testScripterAndTestCaseFile));
+
+ // Add to cleanup stack here, because CreateTestScripterNameL needs to be trapped in other methods.
+ CleanupStack::PushL(testScripterAndTestCaseFile);
+ if(ret != KErrNone)
+ {
+ User::Panic(_L("CTestScripterController::GetFreeOrCreateModuleControllerL(): CreateTestScripterNameL"), ret);
+ }
+
+ CTestModuleController* resultController = NULL;
+ CTestModuleController* parentController = NULL;
+ TInt j;
+
+ __TRACE(KInit, (_L("Find free real module controller (or create new one)")));
+
+ // Get handle to correct "parent" module controller
+ __TRACE(KInit, (_L("Searching for parent module controller named [%S]"), testScripterAndTestCaseFile));
+ for(TInt a = 0; a < iTestScripter.Count(); a++)
+ {
+ //Check if module name matches to given name
+ if(iTestScripter[a]->iName->Des() == testScripterAndTestCaseFile->Des())
+ {
+ parentController = iTestScripter[a];
+ __TRACE(KInit, (_L("Parent module controller [%S] has been found. Checking its %d children"), parentController->iName, parentController->iChildrenControllers.Count()));
+ //Now check all its children and find free one
+ //In UI testing mode always create new module controller
+ if(!aUITestingSupport)
+ {
+ for(j = 0; j < parentController->iChildrenControllers.Count(); j++)
+ {
+ if(parentController->iChildrenControllers[j]->iTestCaseCounter == 0)
+ {
+ resultController = parentController->iChildrenControllers[j];
+ __TRACE(KInit, (_L("Free real module controller found [%S]"), resultController->iName));
+ break;
+ }
+ else
+ {
+ __TRACE(KInit, (_L("Module controller found [%S] but is not free (it runs %d test cases)"), parentController->iChildrenControllers[j]->iName, parentController->iChildrenControllers[j]->iTestCaseCounter));
+ }
+ }
+ }
+ else
+ {
+ __TRACE(KInit, (_L("In UITestingSupport mode new module controller will be always created")));
+ }
+ }
+ }
+
+ //Append underscore to name
+ TPtr ptr = testScripterAndTestCaseFile->Des();
+ ptr.Append(_L("@"));
+
+ //Create new module controller if free one has not been found
+ if(!resultController)
+ {
+ TBuf<10> ind;
+ ind.Format(_L("%d"), iEngine->GetIndexForNewTestModuleController());
+ TPtr ptr = testScripterAndTestCaseFile->Des();
+ ptr.Append(ind);
+ __TRACE(KInit, (_L("Free real module controller not found. Creating new one [%S]."), testScripterAndTestCaseFile));
+
+ //Create server and active object (This uses CTestModuleController::InitL())
+ CTestModuleController* module = CTestModuleController::NewL(
+ iEngine,
+ testScripterAndTestCaseFile->Des(),
+ iAfterReboot, EFalse, this);
+ CleanupStack::PushL(module);
+ parentController->iChildrenControllers.AppendL(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));
+ }
+
+ // Now is used TestScripter so give test case file also(used
+ // in caps modifier cases).
+ TRAPD(err, module->InitL(iInifile, aTestInfo.iConfig));
+ if(err != KErrNone)
+ {
+ __TRACE(KVerbose, (_L("InitL fails with error: %d" ), err));
+ User::Leave(err);
+ }
+
+ module->AddConfigFileL(aTestInfo.iConfig);
+
+ __TRACE(KInit, (_L("New module controller created [%S]."), testScripterAndTestCaseFile));
+
+ //Enumerate test cases
+ module->EnumerateSynchronously();
+
+ CleanupStack::Pop(module);
+ resultController = module;
+ }
+
+ CleanupStack::PopAndDestroy(testScripterAndTestCaseFile);
+
+ // Return handle
+ return resultController;
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: ModuleName
+
+ Description: Return the name of Test Scripter
+
+ Parameters: const TDesC& aModuleName: in: Module name
+
+ Return Values: const TDesC : Name of Test Scripter
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+const TDesC& CTestScripterController::ModuleName( const TDesC& aModuleName )
+ {
+ // If test case file not added yet.
+ if( iTestScripter.Count() == 0 || aModuleName == KTestScripterName )
+ {
+ return *iName;
+ }
+
+ // Test case(s) is(are) added. Scan the name from corrent TestScripter
+ // session
+ for( TInt a = 0; a < iTestScripter.Count(); a++ )
+ {
+ if( aModuleName == iTestScripter[a]->iName->Des() )
+ {
+ return *iTestScripter[a]->iName;
+ }
+ }
+
+ return KNullDesC;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: CreateTestScripterNameL
+
+ Description: Create name according to TestScripter and Test case file.
+
+ Parameters: TFileName& aTestCaseFile: in: Test case file with path and name
+ TFileName& aCreatedName: inout: Created name
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves is test case file is too long
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+HBufC* CTestScripterController::CreateTestScripterNameL(
+ TFileName& aTestCaseFile,
+ HBufC* aCreatedName )
+ {
+ TParse parse;
+ parse.Set( aTestCaseFile, NULL, NULL );
+
+ TInt length( 0 );
+ length = parse.Name().Length();
+ length += ( KTestScripterNameLength + 1 );
+ length += 10; //this will be used to add unique identifier (when run test case in separate process is on)
+
+ // aCreatedName to CleanupStack
+ aCreatedName = HBufC::NewLC( length );
+ TPtr ptr = aCreatedName->Des();
+
+ // Maximum length of TestScripter's name(Max limitation from
+ // CTestModuleController creation)
+ TInt maximumLength = KMaxName - ( KTestScripterNameLength + 1 );
+
+ // Start create name. Format is testscripter_testcasefile
+ ptr.Copy( KTestScripterName );
+ ptr.Append( _L( "_" ) );
+ if( parse.Name().Length() < maximumLength )
+ {
+ ptr.Append( parse.Name() );
+ ptr.LowerCase();
+ }
+ else
+ {
+ __TRACE( KInit, ( CStifLogger::ERed,
+ _L( "TestScripter test case file(config)'s name is too long. Current length[%d], allowed max length[%d]. Cannot continue" ),
+ parse.Name().Length(), maximumLength ) );
+ User::Leave( KErrArgument );
+ }
+
+ // Pop here because this method can be trapped and trap panics with
+ // E32USER-CBase if cleap up stack is not empty.
+ CleanupStack::Pop( aCreatedName );
+
+ return aCreatedName;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: DeleteModuleController
+
+ Description: Finds specified module controller and deletes it.
+
+ Parameters: CTestModuleController* aRealModuleController: module controller
+ to be deleted.
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status:
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::DeleteModuleController(CTestModuleController* aRealModuleController)
+ {
+ __TRACE(KInit, (_L("Attempting to delete real module controller [%S]"), aRealModuleController->iName));
+
+ TInt i, j, k;
+ TInt children;
+ TInt subcontrollers = iTestScripter.Count();
+
+ for(k = 0; k < subcontrollers; k++)
+ {
+ children = iTestScripter[k]->iChildrenControllers.Count();
+ __TRACE(KInit, (_L("...checking controller [%S] which has %d children"), iTestScripter[k]->iName, children));
+
+ for(i = 0; i < children; i++)
+ {
+ if(iTestScripter[k]->iChildrenControllers[i] == aRealModuleController)
+ {
+ __TRACE(KInit, (_L("Real module controller found... deleting")));
+ delete iTestScripter[k]->iChildrenControllers[i];
+ iTestScripter[k]->iChildrenControllers.Remove(i);
+
+ __TRACE(KInit, (_L("Child removed from [%S] controller. Currently it has %d children:"), iTestScripter[k]->iName, iTestScripter[k]->iChildrenControllers.Count()));
+ for(j = 0; j < iTestScripter[k]->iChildrenControllers.Count(); j++)
+ {
+ __TRACE(KInit, (_L(" %d. [%S]"), j + 1, iTestScripter[k]->iChildrenControllers[j]->iName));
+ }
+
+ return;
+ }
+ }
+ }
+ __TRACE(KInit, (_L("Real module controller NOT found... NOT deleting")));
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CTestScripterController
+
+ Method: RemoveModuleController
+
+ Description: Finds specified module controller and removes it from children list.
+
+ Parameters: CTestModuleController* aRealModuleController: module controller
+ to be removed.
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status:
+
+-------------------------------------------------------------------------------
+*/
+void CTestScripterController::RemoveModuleController(CTestModuleController* aRealModuleController)
+ {
+ __TRACE(KInit, (_L("Attempting to remove real module controller [%x]"), aRealModuleController));
+
+ TInt i, j, k;
+ TInt children;
+ TInt subcontrollers = iTestScripter.Count();
+
+ for(k = 0; k < subcontrollers; k++)
+ {
+ children = iTestScripter[k]->iChildrenControllers.Count();
+ __TRACE(KInit, (_L("...checking controller [%S] which has %d children"), iTestScripter[k]->iName, children));
+
+ for(i = 0; i < children; i++)
+ {
+ if(iTestScripter[k]->iChildrenControllers[i] == aRealModuleController)
+ {
+ __TRACE(KInit, (_L("Real module controller found... removing")));
+ iTestScripter[k]->iChildrenControllers.Remove(i);
+
+ __TRACE(KInit, (_L("Child removed from [%S] controller. Currently it has %d children:"), iTestScripter[k]->iName, iTestScripter[k]->iChildrenControllers.Count()));
+ for(j = 0; j < iTestScripter[k]->iChildrenControllers.Count(); j++)
+ {
+ __TRACE(KInit, (_L(" %d. [%S]"), j + 1, iTestScripter[k]->iChildrenControllers[j]->iName));
+ }
+
+ return;
+ }
+ }
+ }
+ __TRACE(KInit, (_L("Real module controller NOT found... NOT removing")));
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ DESCRIPTION
+
+ This module contains implementation of CErrorPrinter class member
+ functions.
+
+-------------------------------------------------------------------------------
+*/
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: NewL
+
+ Description: Create a testcase runner.
+
+ Parameters: CTestEngine* aMain: in: Pointer to console main
+
+ Return Values: CErrorPrinter* : pointer to created object
+
+ Errors/Exceptions: Leaves if memory allocation for object fails
+ Leaves if ConstructL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CErrorPrinter* CErrorPrinter::NewL( CTestEngine* aTestEngine )
+ {
+ CErrorPrinter* self = new ( ELeave ) CErrorPrinter();
+ CleanupStack::PushL( self );
+ self->ConstructL( aTestEngine );
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: ConstructL
+
+ Description: Second level constructor.
+
+ Parameters: CTestEngine* aEngine: in: Pointer to Engine
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CErrorPrinter::ConstructL( CTestEngine* aEngine )
+ {
+ iEngine = aEngine;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: CErrorPrinter
+
+ Description: Constructor.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CErrorPrinter::CErrorPrinter( ) : CActive( EPriorityStandard ),
+ iErrorPckg( iError )
+ {
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: ~CErrorPrinter
+
+ Description: Destructor.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CErrorPrinter::~CErrorPrinter( )
+ {
+ Cancel();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: StartL
+
+ Description: Starts a test case and sets the active object to active.
+
+ Parameters: RTestModule& aServer: in: Reference to the server object
+
+ Return Values: None
+
+ Errors/Exceptions: TInt: Return KErrNone
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CErrorPrinter::StartL( RTestModule& aServer )
+ {
+ iServer = aServer;
+
+ CActiveScheduler::Add ( this );
+
+ SetActive();
+ aServer.ErrorNotification ( iErrorPckg, iStatus );
+
+ return KErrNone;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: RunL
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CErrorPrinter::RunL()
+ {
+
+ if ( iStatus.Int() != KErrNone )
+ {
+ __TRACE( KVerbose, ( _L( "In CErrorPrinter::RunL [iStatus = %d]" ), iStatus.Int() ) );
+ }
+ else
+ {
+ // Forward error print to UI and set request again active.
+ iEngine->ErrorPrint( iErrorPckg );
+ SetActive();
+ iServer.ErrorNotification ( iErrorPckg, iStatus );
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: DoCancel
+
+ Description: Cancels the asynchronous request
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CErrorPrinter::DoCancel()
+ {
+ iServer.CancelAsyncRequest ( ETestModuleErrorNotification );
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CErrorPrinter
+
+ Method: RunError
+
+ Description: Handles errors. RunL can't leave so just forward error
+ and let framework handle error.
+
+ Parameters: TInt aError: in: Error code
+
+ Return Values: TInt: Error code
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CErrorPrinter::RunError( TInt aError )
+ {
+ return aError;
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: NewL
+
+ Description: Constructs a new CServerStateHandler object.
+
+ Parameters: CTestEngine* aMain
+
+ Return Values: CServerStateHandler*: New undertaker
+
+ Errors/Exceptions: Leaves if memory allocation or ConstructL leaves.
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CServerStateHandler* CServerStateHandler::NewL( CTestEngine* aTestEngine,
+ CTestModuleController* aTestModuleController )
+ {
+
+ CServerStateHandler* self =
+ new( ELeave ) CServerStateHandler( aTestEngine, aTestModuleController );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: ConstructL
+
+ Description: Second level constructor.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CServerStateHandler::ConstructL()
+ {
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: CServerStateHandler
+
+ Description: Constructor
+
+ Parameters: CTestEngine* aMain
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CServerStateHandler::CServerStateHandler( CTestEngine* aTestEngine,
+ CTestModuleController* aTestModuleController ) :
+ CActive( CActive::EPriorityStandard ),
+ iEngine( aTestEngine ),
+ iTestModuleController( aTestModuleController )
+ {
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: ~CServerStateHandler
+
+ Description: Destructor.
+ Cancels active request.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+CServerStateHandler::~CServerStateHandler()
+ {
+
+ Cancel();
+
+ iServerThread.Close();
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: StartL
+
+ Description: Starts to monitor server thread.
+
+ Parameters: RTestServer& aServer
+
+ Return Values: TInt:
+
+ Errors/Exceptions:
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CServerStateHandler::StartL( RTestServer& aServer )
+ {
+
+ __TRACE( KVerbose, ( _L( "CServerStateHandler::StartL" ) ) );
+
+ TThreadId serverThreadId;
+
+ iStatus = KRequestPending;
+
+ // Asks from server its thread ID value
+ User::LeaveIfError( aServer.GetServerThreadId ( serverThreadId ) );
+
+ // Opens handle to thread
+ User::LeaveIfError( iServerThread.Open( serverThreadId ) );
+
+ CActiveScheduler::Add( this );
+
+ // Requests notification when this thread dies, normally or otherwise
+ iServerThread.Logon( iStatus ); // Miten RThread hanska ko serveriin..
+
+ SetActive();
+
+ return KErrNone;
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: RunL
+
+ Description: Handles thread death.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CServerStateHandler::RunL()
+ {
+
+ // something went badly wrong!
+ __TRACE( KInit, ( CStifLogger::ERed,
+ _L( "Test case execution fails. Possible reason: KErrServerTerminated" ) ) );
+
+ RDebug::Print( _L("Test case execution fails. Possible reason: KErrServerTerminated") );
+
+ // Note:
+ // More Info about STIF panic with KErrServerTerminated
+ // will be informed to the user via testengine log and testreport
+ // in CTestCaseController::RunL() method
+
+ // TestModuleCrash is called for doing all needed recovering operations for enabling STIF
+ // to continue test case execution
+ iEngine->TestModuleCrash( iTestModuleController );
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: DoCancel
+
+ Description: Stops listening TestServer status.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CServerStateHandler::DoCancel()
+ {
+
+ __TRACE( KVerbose, ( _L( "CServerStateHandler::DoCancel" ) ) );
+
+ // Cancels an outstanding request for notification of the death of this thread.
+ iServerThread.LogonCancel( iStatus );
+
+ }
+/*
+-------------------------------------------------------------------------------
+
+ Class: CServerStateHandler
+
+ Method: RunError
+
+ Description: Handle errors. RunL function does not leave, so one should
+ never come here.
+
+ Print trace and let framework handle error( i.e to do Panic )
+
+ Parameters: TInt aError: in: Error code
+
+ Return Values: TInt: Error code
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+TInt CServerStateHandler::RunError( TInt aError )
+ {
+ __TRACE( KError,( _L( "CServerStateHandler::RunError" ) ) );
+ return aError;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: -
+
+ Method: GenerateModuleName
+
+ Description: Check is module TestScripter. Does parsing and returns new
+ module name and error codes(Needed operations when creating
+ server sessions to TestScripter).
+
+ Parameters: const TFileName& aModuleName: in: Module name for checking.
+ TFileName& aNewModuleName: inout: Parsed module name.
+
+ Return Values: KErrNone if TestScripter releated module.
+ KErrNotFound if not TestScripter releated module.
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+
+TInt GenerateModuleName(const TDesC& aModuleName,
+ TDes& aNewModuleName)
+ {
+ // Check that length is greated than KTestScripterNameLength
+ if( aModuleName.Length() < KTestScripterNameLength )
+ {
+ return KErrNotFound;
+ }
+ // Check is TestScripter
+ TPtrC check( aModuleName.Mid( 0, KTestScripterNameLength ) );
+ TInt ret = check.CompareF( KTestScripterName );
+ if( ret == KErrNone )
+ {
+ aNewModuleName.Copy( aModuleName.Mid( 0, KTestScripterNameLength ) );
+ aNewModuleName.LowerCase();
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+
+ return KErrNone;
+
+ }
+
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+// None
+
+// End of File