diff -r bbd31066657e -r 8bb370ba6d1d testexecfw/stf/stfext/testmodules/scriptermod/src/SubTestCaseRunner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testexecfw/stf/stfext/testmodules/scriptermod/src/SubTestCaseRunner.cpp Fri Apr 09 10:46:28 2010 +0800 @@ -0,0 +1,950 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This file contains TestScripter implementation. +* +*/ + +// INCLUDE FILES +#include "SubTestCaseRunner.h" +#include +#include "TestScripter.h" +#include "Logging.h" +// EXTERNAL DATA STRUCTURES +// None + +// EXTERNAL FUNCTION PROTOTYPES +// None + +// CONSTANTS +// None + +// MACROS +#ifdef LOGGER +#undef LOGGER +#endif +#define LOGGER iTestRunner->GetLogger() + +// LOCAL CONSTANTS AND MACROS +// None + +// MODULE DATA STRUCTURES +// None + +// LOCAL FUNCTION PROTOTYPES +// None + +// FORWARD DECLARATIONS +// None + +// ==================== LOCAL FUNCTIONS ======================================= + +// ================= MEMBER FUNCTIONS ========================================= + +/* +------------------------------------------------------------------------------- + + Class: CSubTestCaseRunner + + Method: CSubTestCaseRunner + + Description: Constructor + + Constructor. + + Parameters: CTestRunner* aTestRunner : in: Pointer to test runner which + should be notified about test case end + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CSubTestCaseRunner::CSubTestCaseRunner() +:CActive( EPriorityStandard ), iState( ESTSIdle ) + { + } + +CSubTestCaseRunner::TSubTestCaseState CSubTestCaseRunner::GetState() const + { + return iState; + } + + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: NewLC + + Description: Two-phased constructor. + + Two-phased constructor. + + Parameters: CTestRunner* aTestRunner : in: Pointer to test runner which + should be notified about test case end + + Return Values: Pointer to newly created CLocalSubTestCaseRunner object. + + Errors/Exceptions: Leaves if there is some problem during method execution + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CLocalSubTestCaseRunner* CLocalSubTestCaseRunner::NewLC( CTestRunner* aTestRunner ) + { + CLocalSubTestCaseRunner* self = new(ELeave)CLocalSubTestCaseRunner( aTestRunner ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: NewL + + Description: Two-phased constructor. + + Two-phased constructor. + + Parameters: CTestRunner* aTestRunner : in: Pointer to test runner which + should be notified about test case end + + Return Values: Pointer to newly created CLocalSubTestCaseRunner object. + + Errors/Exceptions: Leaves if there is some problem during method execution + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CLocalSubTestCaseRunner* CLocalSubTestCaseRunner::NewL( CTestRunner* aTestRunner ) + { + CLocalSubTestCaseRunner* self = NewL( aTestRunner ); + CleanupStack::Pop( self ); + return self; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: CLocalSubTestCaseRunner + + Description: Destructor + + Destructor + + Parameters: none + + Return Values: none + + Errors/Exceptions: none + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CLocalSubTestCaseRunner::~CLocalSubTestCaseRunner() + { + CancelSubTestCaseL(); + + delete iStartInfo; + iTestCase.Close(); + iTestEngine.Close(); + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: CLocalSubTestCaseRunner + + Description: Constructor + + Constructor. + + Parameters: CTestRunner* aTestRunner : in: Pointer to test runner which + should be notified about test case end + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +CLocalSubTestCaseRunner::CLocalSubTestCaseRunner( CTestRunner* aTestRunner ) +:iTestRunner( aTestRunner ), iResultPckg( iResult ) + { + CActiveScheduler::Add( this ); + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: ConstructL + + Description: Second phase of two-phased constructor. + + Second phase of two-phased constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CLocalSubTestCaseRunner::ConstructL() + { + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: NewL + + Description: Handles test case execution end. + + Handles test case execution end and pass test case execution result to + proper CTestCaseRunner. + + Parameters: None + + Return Values: None + + Errors/Exceptions: Leaves if there is some problem during method execution + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CLocalSubTestCaseRunner::RunL() + { + // Store run result + iRunResult = iStatus.Int(); + + iTestCase.Close(); + iTestEngine.Close(); + + iState = ESTSIdle; + + // Report sub test case result to CTestRunner + iTestRunner->SubTestCaseFinishedL( this ); + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: DoCancel + + Description: Cancels test case execution + + Cancels test case execution + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CLocalSubTestCaseRunner::DoCancel() + { + TInt ret = iTestCase.CancelAsyncRequest( RTestCase::ERunTestCase ); + if ( ret != KErrNone ) + { + // There was some error during sub test case cancel + // Only put message to log. + __TRACE( KMessage, ( _L( "Unexpected error during sub test case testid=%S cancel." ), &iStartInfo->GetTestId() ) ); + } + + iTestCase.Close(); + iTestEngine.Close(); + + // Mart test case as canceled + iResult.iTestResult.SetResult( KErrNone, KNullDesC ); + iResult.iCaseExecutionResultCode = KErrCancel; + iResult.iCaseExecutionResultType = TFullTestResult::ECaseCancelled; + iState = ESTSIdle; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: RunSubTestCaseL + + Description: Starts test case execution. + + Starts test case execution. + + Parameters: CStartInfo* aStartInfo : in: Pointer to structure which hold + information about test case which should be executed. + + Return Values: None + + Errors/Exceptions: Leaves if there is some problem during method execution + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CLocalSubTestCaseRunner::RunSubTestCaseL( CStartInfo& aStartTestCaseInfo ) + { + // Check if this AO is already running some sub test case + if ( IsActive() ) + { + User::Leave( KErrInUse ); + } + + // Reset runner internal state + Reset(); + + // Copy sub test case startup information + CStartInfo* startInfo = CStartInfo::NewL(); + CleanupStack::PushL( startInfo ); + startInfo->CopyL( aStartTestCaseInfo ); + CleanupStack::Pop( startInfo ); + iStartInfo = startInfo; + + // Connect to TestEngine + TInt ret = iTestEngine.Connect(); + if ( ret != KErrNone ) + { + User::Leave( ret ); + } + + // Initialize TestEngine session + CleanupClosePushL( iTestEngine ); + ret = iTestEngine.LoadConfiguration( KNullDesC() ); + if ( ret != KErrNone ) + { + User::Leave( ret ); + } + + // Load selected test module with specified ini file + ret = iTestEngine.AddTestModule( iStartInfo->GetModuleName(), + iStartInfo->GetIniFile() ); + if ( ret != KErrNone ) + { + User::Leave( ret ); + } + + // Set optional cfg file + if ( iStartInfo->GetConfig() != KNullDesC ) + { + ret = iTestEngine.AddConfigFile( iStartInfo->GetModuleName(), + iStartInfo->GetConfig() ); + if ( ret != KErrNone ) + { + User::Leave( ret ); + } + } + + // Get list of available test cases from test engine + TRequestStatus enumerationRequestStatus; + TCaseCount testCasesCount; + iTestEngine.EnumerateTestCases( testCasesCount, enumerationRequestStatus ); + User::WaitForRequest( enumerationRequestStatus ); + if ( enumerationRequestStatus.Int() != KErrNone ) + { + User::Leave( enumerationRequestStatus.Int() ); + } + + CFixedFlatArray* testCasesList = CFixedFlatArray::NewL( testCasesCount() ); + CleanupStack::PushL( testCasesList ); + + ret = iTestEngine.GetTestCases( *testCasesList ); + if ( ret != KErrNone ) + { + User::Leave( ret ); + } + + // Find requested test case in test cases enumerated from TestEngine + TBool findByTitle = ( iStartInfo->GetTitle() != KNullDesC ); + TTestInfo testInfo; + TBool foundTestCase = EFalse; + if ( findByTitle ) + { + iStartInfo->SetTestCaseNumber( -1 ); + } + for ( TInt i = 0; i < testCasesList->Count(); i++ ) + { + if ( ( findByTitle && ( (*testCasesList)[ i ].iTestCaseInfo.iTitle == iStartInfo->GetTitle() ) ) || + ( (*testCasesList)[ i ].iTestCaseInfo.iCaseNumber == iStartInfo->GetTestCaseNumber() ) ) + { + testInfo = (*testCasesList)[ i ]; + foundTestCase = ETrue; + } + } + + // Store test case title + iStartInfo->SetTitleL( testInfo.iTestCaseInfo.iTitle ); + + // Check if requested test case is availabe or not + if ( !foundTestCase ) + { + User::Leave( KErrNotFound ); + } + + CleanupStack::PopAndDestroy( testCasesList ); + + // Open test case subsession + TTestInfoPckg testInfoPckg( testInfo ); + ret = iTestCase.Open( iTestEngine, testInfoPckg ); + if ( ret != KErrNone ) + { + User::Leave( ret ); + } + + // Run sub test case + CleanupClosePushL( iTestCase ); + iTestCase.RunTestCase( iResultPckg, iStatus ); + SetActive(); + CleanupStack::Pop(); // Remove iTestCase from cleanup stack + CleanupStack::Pop(); // Remove iTestEngine from cleanup stack + iState = ESTSRunning; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: PauseSubTestCaseL + + Description: Pauses selected sub test case. + + Pauses selected sub test case. + + Parameters: None + + Return Values: None + + Errors/Exceptions: Leaves if sub test case is not running + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CLocalSubTestCaseRunner::PauseSubTestCaseL() + { + // Check if sub test case is running + if ( !IsActive() ) + { + User::Leave( KErrNotReady ); + } + + User::LeaveIfError( iTestCase.Pause() ); + iState = ESTSPaused; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: ReasumeSubTestCaseL + + Description: Reasume selected sub test case. + + Reasume selected sub test case. + + Parameters: None + + Return Values: None + + Errors/Exceptions: Leaves if sub test case is not running + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CLocalSubTestCaseRunner::ResumeSubTestCaseL() + { + // Check if sub test case is running + if ( !IsActive() ) + { + User::Leave( KErrNotReady ); + } + + User::LeaveIfError( iTestCase.Resume() ); + iState = ESTSRunning; + } + +void CLocalSubTestCaseRunner::CancelSubTestCaseL() + { + Cancel(); + } + + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: Reset + + Description: Resets sub test case runner internal state. + + Resets sub test case runner internal state. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +void CLocalSubTestCaseRunner::Reset() + { + delete iStartInfo; + iStartInfo = NULL; + + iRunResult = KErrNone; + + iResult.iCaseExecutionResultCode = KErrNone; + iResult.iCaseExecutionResultType = TFullTestResult::ECaseOngoing; + iResult.iTestResult.SetResult( KErrNone, KNullDesC ); + + iState = ESTSIdle; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: GetRunResult + + Description: Returns execution result. + + Returns execution result. + + Parameters: None + + Return Values: Execution result + + Errors/Exceptions: + + Status: Draft + +------------------------------------------------------------------------------- +*/ +TInt CLocalSubTestCaseRunner::GetRunResult() const + { + return iRunResult; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: GetTestCaseResult + + Description: Returns test case execution result. + + Returns test case execution result. + + Parameters: None + + Return Values: Test case execution result. + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +const TFullTestResult& CLocalSubTestCaseRunner::GetTestCaseResult() const + { + return iResult; + } + +/* +------------------------------------------------------------------------------- + + Class: CLocalSubTestCaseRunner + + Method: GetStartInfo + + Description: Returns informations about started test case. + + Returns informations about started test case. + + Parameters: None + + Return Values: Returns information about started test case. + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +const CStartInfo* CLocalSubTestCaseRunner::GetStartInfo() const + { + return iStartInfo; + } + +CSubTestCaseRunner::TSubTestCaseType CLocalSubTestCaseRunner::GetType() const + { + return ESTTLocal; + } + + + + +CRemoteSubTestCaseRunner* CRemoteSubTestCaseRunner::NewL( CTestRunner* aTestRunner, + CSlave* aSlave, CRemoteCallsProxy* aRemoteCallsProxy ) + { + CRemoteSubTestCaseRunner* self = new(ELeave)CRemoteSubTestCaseRunner( + aTestRunner, aSlave, aRemoteCallsProxy ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +CRemoteSubTestCaseRunner* CRemoteSubTestCaseRunner::NewLC( CTestRunner* aTestRunner, + CSlave* aSlave, CRemoteCallsProxy* aRemoteCallsProxy ) + { + CRemoteSubTestCaseRunner* self = new(ELeave)CRemoteSubTestCaseRunner( + aTestRunner, aSlave, aRemoteCallsProxy ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +CRemoteSubTestCaseRunner::~CRemoteSubTestCaseRunner() + { + Cancel(); + + iTimeoutTimer.Close(); + + delete iNestedASLoop; + iNestedASLoop = NULL; + + delete iStartInfo; + iStartInfo = NULL; + + TRAPD( err, iSlave->UnregisterSubTestCaseL( this ) ); + if ( err != KErrNone ) + { + RDebug::Print( _L("Unexpected error during slave subtestcase deregistration %d"), err ); + } + } + +void CRemoteSubTestCaseRunner::RunSubTestCaseL( CStartInfo& aStartTestCaseInfo ) + { + // Check if this AO is already running some sub test case + if ( IsActive() || ( iState != ESTSIdle ) ) + { + User::Leave( KErrInUse ); + } + + // Reset runner internal state + Reset(); + + // Copy sub test case startup information + CStartInfo* startInfo = CStartInfo::NewL(); + CleanupStack::PushL( startInfo ); + startInfo->CopyL( aStartTestCaseInfo ); + CleanupStack::Pop( startInfo ); + iStartInfo = startInfo; + + // Connect to TestEngine + iRemoteCallsProxy->RunTestCaseL( iSlave->GetMasterId(), iSlave->GetSlaveId(), iStartInfo ); + + iCurrentOperation = ECORunSubtestCase; + + iTimeoutTimer.After( iStatus, iOperationTimeout ); + SetActive(); + + iNestedASLoop->Start(); + + User::LeaveIfError( iOperationResult ); + iState = ESTSRunning; + } + +void CRemoteSubTestCaseRunner::PauseSubTestCaseL() + { + // Check if sub test case is running + if ( IsActive() || ( iState != ESTSRunning ) ) + { + User::Leave( KErrNotReady ); + } + + iRemoteCallsProxy->PauseTestCaseL( iSlave->GetMasterId(), iSlave->GetSlaveId(), iTestCaseId ); + + iCurrentOperation = ECOPauseSubtestCase; + + iTimeoutTimer.After( iStatus, iOperationTimeout ); + SetActive(); + + iNestedASLoop->Start(); + + User::LeaveIfError( iOperationResult ); + iState = ESTSPaused; + } + +void CRemoteSubTestCaseRunner::ResumeSubTestCaseL() + { + // Check if sub test case is running + if ( IsActive() || ( iState != ESTSPaused ) ) + { + User::Leave( KErrNotReady ); + } + + iRemoteCallsProxy->ResumeTestCaseL( iSlave->GetMasterId(), iSlave->GetSlaveId(), iTestCaseId ); + + iCurrentOperation = ECOResumeSubtestCase; + + iTimeoutTimer.After( iStatus, iOperationTimeout ); + SetActive(); + + iNestedASLoop->Start(); + + User::LeaveIfError( iOperationResult ); + iState = ESTSRunning; + } + +void CRemoteSubTestCaseRunner::CancelSubTestCaseL() + { + // Check if sub test case is running + if ( IsActive() || ( iState != ESTSIdle ) ) + { + User::Leave( KErrNotReady ); + } + + iRemoteCallsProxy->CancelTestCaseL( iSlave->GetMasterId(), iSlave->GetSlaveId(), iTestCaseId ); + + iCurrentOperation = ECOCancelSubtestCase; + + iTimeoutTimer.After( iStatus, iOperationTimeout ); + SetActive(); + + iNestedASLoop->Start(); + + User::LeaveIfError( iOperationResult ); + + iRunResult = KErrCancel; + // Mart test case as canceled + iResult.iTestResult.SetResult( KErrNone, KNullDesC ); + iResult.iCaseExecutionResultCode = KErrCancel; + iResult.iCaseExecutionResultType = TFullTestResult::ECaseCancelled; + + iState = ESTSIdle; + } + +TInt CRemoteSubTestCaseRunner::GetRunResult() const + { + return iRunResult; + } + +const TFullTestResult& CRemoteSubTestCaseRunner::GetTestCaseResult() const + { + return iResult; + } + +const CStartInfo* CRemoteSubTestCaseRunner::GetStartInfo() const + { + return iStartInfo; + } + +CSubTestCaseRunner::TSubTestCaseType CRemoteSubTestCaseRunner::GetType() const + { + return ESTTRemote; + } + +CRemoteSubTestCaseRunner::CRemoteSubTestCaseRunner( CTestRunner* aTestRunner, + CSlave* aSlave, CRemoteCallsProxy* aRemoteCallsProxy ) +:iTestRunner( aTestRunner ), iSlave( aSlave ), + iRemoteCallsProxy( aRemoteCallsProxy ), iOperationTimeout( 30000000 ) + { + CActiveScheduler::Add( this ); + } + +void CRemoteSubTestCaseRunner::ConstructL() + { + User::LeaveIfError( iTimeoutTimer.CreateLocal() ); + iNestedASLoop = new(ELeave)CActiveSchedulerWait; + iSlave->RegisterSubTestCaseL( this ); + } + +void CRemoteSubTestCaseRunner::RunL() + { + // Test case timeouted. + iCurrentOperation = ECONone; + iOperationResult = KErrTimedOut; + iNestedASLoop->AsyncStop(); + } + +void CRemoteSubTestCaseRunner::DoCancel() + { + if ( GetState() == ESTSRunning ) + { + TRAPD( err, CancelSubTestCaseL() ); + if ( err != KErrNone ) + { + RDebug::Print( _L("Unexpected error during slave subtestcase cancel %d"), err ); + } + } + + iTimeoutTimer.Cancel(); + } + +void CRemoteSubTestCaseRunner::Reset() + { + delete iStartInfo; + iStartInfo = NULL; + iTestCaseId = 0; + iRunResult = 0; + iResult = TFullTestResult(); + } + +CSlave* CRemoteSubTestCaseRunner::GetSlave() + { + return iSlave; + } + +TUint16 CRemoteSubTestCaseRunner::GetTestCaseId() const + { + return iTestCaseId; + } + +void CRemoteSubTestCaseRunner::NotifyTestCaseStartedL( TUint16 aTestCaseId ) + { + if ( !iNestedASLoop->IsStarted() || ( iCurrentOperation != ECORunSubtestCase ) ) + { + User::Leave( KErrNotReady ); + } + + iTestCaseId = aTestCaseId; + + Cancel(); + + iNestedASLoop->AsyncStop(); + iCurrentOperation = ECONone; + iOperationResult = KErrNone; + } + +void CRemoteSubTestCaseRunner::NotifyTestCaseRunError( const TFullTestResult& aTestCaseResult ) + { + if ( !iNestedASLoop->IsStarted() || ( iCurrentOperation != ECORunSubtestCase ) ) + { + User::Leave( KErrNotReady ); + } + + Cancel(); + + iResult = aTestCaseResult; + + iNestedASLoop->AsyncStop(); + iCurrentOperation = ECONone; + iOperationResult = iResult.iCaseExecutionResultCode; + } + +void CRemoteSubTestCaseRunner::NotifyTestCasePausedL() + { + if ( !iNestedASLoop->IsStarted() || ( iCurrentOperation != ECOPauseSubtestCase ) ) + { + User::Leave( KErrNotReady ); + } + + Cancel(); + + iNestedASLoop->AsyncStop(); + iCurrentOperation = ECONone; + iOperationResult = KErrNone; + } + +void CRemoteSubTestCaseRunner::NotifyTestCaseResumedL() + { + if ( !iNestedASLoop->IsStarted() || ( iCurrentOperation != ECOResumeSubtestCase ) ) + { + User::Leave( KErrNotReady ); + } + + Cancel(); + + iNestedASLoop->AsyncStop(); + iCurrentOperation = ECONone; + iOperationResult = KErrNone; + } + +void CRemoteSubTestCaseRunner::NotifyTestCaseCancelledL() + { + if ( !iNestedASLoop->IsStarted() || ( iCurrentOperation != ECOCancelSubtestCase ) ) + { + User::Leave( KErrNotReady ); + } + + Cancel(); + + iNestedASLoop->AsyncStop(); + iCurrentOperation = ECONone; + iOperationResult = KErrNone; + } + +void CRemoteSubTestCaseRunner::NotifyTestCaseFinishedL( const TFullTestResult& aTestCaseResult ) + { + iRunResult = KErrNone; + iResult = aTestCaseResult; + + iState = ESTSIdle; + + // Report sub test case result to CTestRunner + iTestRunner->SubTestCaseFinishedL( this ); + } + +TBool CRemoteSubTestCaseRunner::IsRunSubTestCaseRequestOngoing() const + { + if ( iCurrentOperation == ECORunSubtestCase ) + { + return ETrue; + } + return EFalse; + } + +// EOF