/*
* 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 CUIStore
* and CModule class member functions.
*
*/
// INCLUDE FILES
#include <e32base.h>
#include <e32svr.h>
#include <f32file.h>
#include <e32uid.h>
#include <collate.h>
#include <StifLogger.h>
#include "Logging.h"
#include <stifinternal/UIStore.h>
#include <stifinternal/UIEngine.h>
#include <stifinternal/UIStoreContainer.h>
#include "UIStorePopup.h"
#include <stifinternal/UIEngineContainer.h>
// EXTERNAL DATA STRUCTURES
// EXTERNAL FUNCTION PROTOTYPES
// CONSTANTS
//@spe _LIT(KNameTxt,"TEST FRAMEWORK");
//@spe _LIT(KNameBase,"BASE");
_LIT( KUIStore, "CUiStore" );
_LIT( KUIStoreIf, "CUiStoreIf" );
//_LIT( KUIStoreDefaultDir, "C:\\TestFramework\\" );
_LIT( KUIStoreSetStart, "[TestSetStart]" );
_LIT( KUIStoreSetEnd, "[TestSetEnd]" );
_LIT( KUIStoreSetCaseStart, "[TestSetCaseStart]" );
_LIT( KUIStoreSetCaseEnd, "[TestSetCaseEnd]" );
_LIT( KUIStoreCaseModuleName, "ModuleName=" );
_LIT( KUIStoreTestCaseTitle, "Title=" );
_LIT( KUIStoreTestCaseFile, "TestCaseFile=");
_LIT( KUIStoreTestCaseNum, "TestCaseNum=");
_LIT( KUIStoreCaseExpectedResult, "ExpectedResult=");
_LIT( KUIStoreCasePriority, "Priority=");
_LIT( KUIStoreCaseTimeout, "Timeout=");
_LIT( KUIStoreLastStartedCaseIndex, "LastStartedCaseIndex=");
_LIT( KUIStoreDefaultRebootFile, "TestFrameworkUIReboot.txt" );
_LIT( KUIStoreStartTest, "[StartTestCase]" );
_LIT( KUIStoreStartTestEnd, "[StartTestCaseEnd]" );
_LIT( KUIStoreCaseStatus, "TestCaseStatus=");
_LIT( KUIStoreCaseExecutionResult, "TestCaseExecutionResult=");
_LIT( KUIStoreCaseResult, "TestCaseResult=");
_LIT( KUIStoreCaseStartTime, "TestCaseStartTime=");
_LIT( KUIStoreCaseEndTime, "TestCaseEndTime=");
const TInt KRcpHeaderLen = 16;
const TInt KFixedStartedCaseIndex = 10;
// MACROS
#ifdef LOGGER
#undef LOGGER
#endif
#define LOGGER iLogger
// LOCAL CONSTANTS AND MACROS
static const TUid KUidTestModule = { 0x101FB3E7 };
// MODULE DATA STRUCTURES
// LOCAL FUNCTION PROTOTYPES
// FORWARD DECLARATIONS
// ==================== LOCAL FUNCTIONS =======================================
// None
// ================= MEMBER FUNCTIONS =========================================
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: NewL
Description: Construct the CUIStore class
Parameters: None
Return Values: CUIStore* New object
Errors/Exceptions: Leaves if memory allocation fails or
ConstructL leaves.
Status: Draft
-------------------------------------------------------------------------------
*/
CUIStore* CUIStore::NewL( CUIStoreIf* aUIStoreIf )
{
CUIStore* self = new ( ELeave ) CUIStore( aUIStoreIf );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ConstructL
Description: Second level constructor.
Construct the console
Construct module and case containers
Retrieve command line parameters
Connect to test engine
Parameters: None
Return Values: None
Errors/Exceptions: Leaves if memory allocation fails or fileserver or
test engine can't be connected.
Status: Draft
-------------------------------------------------------------------------------
*/
void CUIStore::ConstructL( )
{
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: CUIStore
Description: Constructor.
Initialize non-zero member variables.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
CUIStore::CUIStore( CUIStoreIf* aUIStoreIf ):
iUIStoreIf( aUIStoreIf ),
iUpdateNeeded( ETrue ),
iActivePopupPriority( EPopupPriorityLow )
{
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ~CUIStore
Description: Destructor
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
CUIStore::~CUIStore( )
{
iFileList.ResetAndDestroy();
iFileList.Close();
iStartedTestSets.ResetAndDestroy();
iStartedTestSets.Close();
iStartedTestCases.ResetAndDestroy();
iStartedTestCases.Close();
iTestSets.ResetAndDestroy();
iTestSets.Close();
iTestCases.ResetAndDestroy();
iTestCases.Close();
iPopups.ResetAndDestroy();
iPopups.Close();
delete iUIEngine;
iUIEngine = 0;
}
/*
-------------------------------------------------------------------------------
Class: CStifTFwIf
Method: Open
Description: Open test engine.
Parameters: TDesC& aTestFrameworkIni: in: Initialization file to Test Framework
Return Values: Symbian OS error: Error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::Open( const TDesC& aTestFrameworkIni )
{
if( aTestFrameworkIni.Length() > KMaxFileName )
{
return KErrArgument;
}
TRAPD( err,
iUIEngine = CUIEngine::NewL( this );
);
if( err != KErrNone )
{
return err;
}
TFileName ini( aTestFrameworkIni );
// Check given ini file
TRAP( err, CheckIniL( ini ) );
// Store folder of initialization file to open it again when looking for filters
RDebug::Print(_L("CUIStore stores name of ini file [%S]"), &ini);
iTestFrameworkIni.Copy(ini);
return iUIEngine->Open( ini );
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: Close
Description: Close test engine.
Parameters: None
Return Values: TInt KErrNone: Always returned KErrNone
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::Close()
{
TInt ret = KErrNone;
if( iUIEngine != NULL )
{
ret = iUIEngine->Close();
delete iUIEngine;
iUIEngine = 0;
}
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: AddTestModule
Description: Add test module to module list of test engine
Parameters: TDesC& aModuleName: in: Testmodule, which is added to module list
TDesC& aIniFile: in: Initialization file to the test module
Return Values: Symbian OS error: Error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::AddTestModule( const TDesC& aModuleName,
const TDesC& aIniFile )
{
TInt ret = iUIEngine->AddTestModule( aModuleName, aIniFile );
RefreshAllCases();
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: RemoveTestModule
Description: Add test module to module list of test engine
Parameters: TDesC& aModuleName: in: Testmodule, which is removed of module list
Return Values: Symbian OS error: Error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::RemoveTestModule( const TDesC& aModuleName )
{
TInt ret = iUIEngine->RemoveTestModule( aModuleName );
RefreshAllCases();
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: AddTestCaseFile
Description: Add test case file to test case file list of test engine
Parameters: TDesC& aModuleName: in: Testmodule, which own test cases of test case list.
TDesC& aCaseFile: in: Test case list, which is added to test case list
Return Values: Symbian OS error: Error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::AddTestCaseFile( const TDesC& aModuleName,
const TDesC& aCaseFile )
{
TInt ret = iUIEngine->AddTestCaseFile( aModuleName, aCaseFile );
RefreshAllCases();
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: RemoveTestCaseFile
Description: Remove test case file of test case file list of test engine
Parameters: TDesC& aModuleName: in: Testmodule, which own test cases of test case list
TDesC& aCaseFile: in: Test case list, which is removed of test case list
Return Values: Symbian OS error: Error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::RemoveTestCaseFile( const TDesC& aModuleName,
const TDesC& aCaseFile )
{
TInt ret = iUIEngine->RemoveTestCaseFile( aModuleName, aCaseFile );
RefreshAllCases();
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: StartTestCase
Description: Start selected test case identified with CTestInfo.
anIndex contains index in StartedTestCase array,
which is valid only during execution of calling
function.
Parameters: const CTestInfo& aTestInfo: in: Test case info
TInt& anIndex: out: Index to StartedTestCaseArray returned
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::StartTestCase( const CTestInfo& aTestInfo,
TInt& anIndex )
{
CUIEngineContainer* container = NULL;
TInt ret = iUIEngine->StartTestCase( container, aTestInfo );
if( ret != KErrNone )
{
return ret;
}
CStartedTestCase* testCase = NULL;
TRAP( ret,
testCase = CStartedTestCase::NewL( aTestInfo, *container );
);
if( ret != KErrNone )
{
iUIEngine->AbortStartedTestCase( container );
return ret;
}
ret = iStartedTestCases.Append( testCase );
if( ret != KErrNone )
{
iUIEngine->AbortStartedTestCase( container );
delete testCase;
return ret;
}
anIndex = iStartedTestCases.Find( testCase );
if( anIndex < 0 )
{
User::Panic( KUIStore, KErrNotFound );
}
iUIStoreIf->Update( testCase, testCase->Status() );
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: TestCases
Description: Return array of existing test cases.
Parameters: RRefArray<CTestInfo>& aTestCases: out: Array of test cases
TDesC& aTestModule: in: Test module name (optional)
TDesC& aTestCaseFile: in: Test case file name (optional)
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::TestCases( RRefArray<CTestInfo>& aTestCases,
const TDesC& aTestModule,
const TDesC& aTestCaseFile )
{
TInt ret = UpdateCases();
if( ret != KErrNone )
{
return ret;
}
TInt count = iTestCases.Count();
for( TInt i = 0; i < count; i++ )
{
if( ( aTestModule.Length() > 0 ) &&
( iTestCases[i]->ModuleName() != aTestModule ) )
{
continue;
}
else if( ( aTestCaseFile.Length() > 0 ) &&
( iTestCases[i]->TestCaseFile() != aTestCaseFile ) )
{
continue;
}
aTestCases.Append( *iTestCases[i] );
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: StartedTestCaseL
Description: Return started (running/runned) test case
Parameters: CStartedTestCase& aTestCase: out: Test case information
TInt anIndex: in: test case index in StartedTestCaseArray
Return Values: Reference to CStartedTestCase object
Errors/Exceptions: Leaves if anIndex out of range
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C CStartedTestCase& CUIStore::StartedTestCaseL( TInt anIndex )
{
TInt count = iStartedTestCases.Count();
if( ( anIndex >= count ) ||
( anIndex < 0 ) )
{
User::Leave( KErrNotFound );
}
return *iStartedTestCases[anIndex];
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: StartedTestCases
Description: Return started (running/runned) test cases
Parameters: RRefArray<CStartedTestCase>& aTestCases: out: array of test cases
TExecutionStatus aStatus: in: test case status (optional)
TDesC& aTestModule: in: test module name (optional)
TDesC& aTestCaseFile: in: test case file name (optional)
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::StartedTestCases( RRefArray<CStartedTestCase>& aTestCases,
TInt aStatus,
const TDesC& aTestModule,
const TDesC& aTestCaseFile )
{
TInt count = iStartedTestCases.Count();
for( TInt i = 0; i < count; i++ )
{
if( ( aTestModule.Length() > 0 ) &&
( iStartedTestCases[i]->TestInfo().ModuleName() != aTestModule ) )
{
continue;
}
else if( ( aTestCaseFile.Length() > 0 ) &&
( iStartedTestCases[i]->TestInfo().TestCaseFile() != aTestCaseFile ) )
{
continue;
}
else if( ( aStatus != CUIStoreIf::EStatusAll) &&
!( iStartedTestCases[i]->Status() & aStatus ) )
{
continue;
}
if( aTestCases.Append( *iStartedTestCases[i] ) != KErrNone )
{
return KErrNoMemory;
}
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: Modules
Description: Return modules array
Parameters: RRefArray<CModule>& aTestModules: out: modules array
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::Modules( RRefArray<TDesC>& aTestModules )
{
TInt ret = UpdateCases();
if( ret != KErrNone )
{
return ret;
}
// Go through test cases and search if there are new modules
// and add them to aTestModules array
TInt caseCount = iTestCases.Count();
TInt moduleCount = 0;
TInt caseIndex = 0;
TInt moduleIndex = 0;
for ( caseIndex = 0; caseIndex < caseCount; caseIndex++ )
{
// First check modules
moduleCount = aTestModules.Count();
for ( moduleIndex = 0; moduleIndex < moduleCount; moduleIndex++ )
{
if( iTestCases[caseIndex]->ModuleName() ==
aTestModules[moduleIndex] )
{
break;
}
}
if ( moduleIndex == moduleCount )
{
// New module found
if( aTestModules.Append( iTestCases[caseIndex]->ModuleName() ) !=
KErrNone )
{
return KErrNoMemory;
}
}
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: TestCaseFiles
Description: Return test case files
Parameters: RRefArray<TDesC>& aTestCaseFiles: out: Array of test case files
TDesC& aTestModule: in: test module name (optional)
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::TestCaseFiles( RRefArray<TDesC>& aTestCaseFiles,
const TDesC& aTestModule )
{
TInt ret = UpdateCases();
if( ret != KErrNone )
{
return ret;
}
// Go through test cases and search if there are new test case files
// for specified test module and add them to aTestCaseFiles array
TInt caseCount = iTestCases.Count();
TInt fileCount = 0;
TInt caseIndex = 0;
TInt fileIndex = 0;
for ( caseIndex = 0; caseIndex < caseCount; caseIndex++ )
{
if( ( aTestModule.Length() > 0 ) &&
( aTestModule != iTestCases[caseIndex]->ModuleName() ) )
{
// Test case file is not for specified module
continue;
}
// First check modules
fileCount = aTestCaseFiles.Count();
for ( fileIndex = 0; fileIndex < fileCount; fileIndex++ )
{
if( iTestCases[caseIndex]->TestCaseFile() ==
aTestCaseFiles[fileIndex] )
{
break;
}
}
if ( fileIndex == fileCount )
{
// New test case file found
if( aTestCaseFiles.Append( iTestCases[caseIndex]->TestCaseFile() ) !=
KErrNone )
{
return KErrNoMemory;
}
}
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: LoadAllModules
Description: Loads all TestFramework test modules from \system\libs\ directories
of all drives. In Secure Platform from \sys\bin directories.
Parameters: None
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::LoadAllModules()
{
RPointerArray<TDesC> testModules;
TInt ret = ListAllModules( testModules );
if( ret == KErrNone )
{
for (TInt i= 0; i < testModules.Count(); i++)
{
iLogger->Log( _L("Add test module: %S"), testModules[i] );
ret = iUIEngine->AddTestModule( *testModules[i], KNullDesC );
if( ret != KErrNone )
{
iLogger->Log( _L("Add test module %S failed %d"),
testModules[i], ret );
break;
}
}
}
RefreshAllCases();
testModules.ResetAndDestroy();
testModules.Close();
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ListAllModules
Description: Lists all TestFramework test modules from \system\libs\ directories
of all drives. In Secure Platform from \sys\bin directories.
Parameters: None
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::ListAllModules( RPointerArray<TDesC>& aModuleNames )
{
TRAPD( err, ListAllModulesL( aModuleNames ); );
return err;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ListAllModulesL
Description: Lists all TestFramework test modules from \system\libs\ directories
of all drives. In Secure Platform from \sys\bin directories.
Parameters: None
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
void CUIStore::ListAllModulesL( RPointerArray<TDesC>& aModuleNames )
{
TFileName libDirectory;
RFs fsSession;
TFileName fullName;
// Connect to file server
User::LeaveIfError( fsSession.Connect() ); // Start session
CleanupClosePushL( fsSession );
TDriveList drivelist;
User::LeaveIfError( fsSession.DriveList(drivelist) );
// A TDriveList (the list of available drives), is an array of
// 26 bytes. Each byte with a non zero value signifies that the
// corresponding drive is available.
// 0x10000079, 0x1000008d, 0x101FB3E7
TUidType anEntryUid( KDynamicLibraryUid,
KSharedLibraryUid,
KUidTestModule );
TInt driveNumber;
TChar driveLetter;
CDir* testModules = NULL;
for( driveNumber=EDriveA; driveNumber<=EDriveZ; driveNumber++ )
{
if( !drivelist[driveNumber] )
{
// If drive-list entry is zero, drive is not available
continue;
}
User::LeaveIfError(fsSession.DriveToChar(driveNumber,driveLetter));
libDirectory.Zero();
libDirectory.Append( driveLetter );
libDirectory.Append( _L(":\\sys\\bin\\*") );
iLogger->Log( _L("Searching modules from %S"), &libDirectory );
fsSession.GetDir( libDirectory, anEntryUid, ESortNone, testModules );
if( !testModules )
{
// Continue if no test modules found
continue;
}
TInt count = testModules->Count();
for (TInt i= 0; i < count; i++)
{
fullName = (*testModules)[i].iName;
fullName.LowerCase();
// Remove optional '.DLL' from file name
TParse parse;
parse.Set( fullName, NULL, NULL );
if ( parse.Ext() == _L(".dll") )
{
const TInt len = parse.Ext().Length();
fullName.Delete( fullName.Length()-len, len );
}
// Exclude internal test modules (testcombiner, testscripter, suevent)
_LIT(KTestCombiner, "testcombiner");
_LIT(KTestScripter, "testscripter");
_LIT(KSUEvent, "suevent");
if(fullName != KTestCombiner && fullName != KSUEvent && fullName != KTestScripter)
{
HBufC* name = fullName.AllocLC();
iLogger->Log( _L("Found: %S"), name );
User::LeaveIfError( aModuleNames.Append( name ) );
CleanupStack::Pop( name );
}
}
delete testModules;
testModules = NULL;
}
CleanupStack::PopAndDestroy(); // fsSession
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: CreateTestSet
Description: Create new test set.
Parameters: TDesC& aSetName: in: test set name (Max length is KMaxName)
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::CreateTestSet( const TDesC& aSetName )
{
TPtrC setName;
TFileName tmp;
TInt ret = ParseTestSetName( aSetName, setName, tmp );
if( ret != KErrNone )
{
return ret;
}
CTestSetInfo* setInfo = NULL;
if( FindSetByName( setName, setInfo ) == KErrNone )
{
return KErrAlreadyExists;
}
TRAPD( err,
setInfo = CTestSetInfo::NewL( setName );
);
if( err != KErrNone )
{
return err;
}
if( iTestSets.Append( setInfo ) != KErrNone )
{
delete setInfo;
return KErrNoMemory;
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: RemoveTestSet
Description: Remove active test set.
Parameters: TDesC& aSetName: in: test set name (Max length is KMaxName)
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::RemoveTestSet( const TDesC& aSetName )
{
TInt err = UnloadTestSet( aSetName );
if ( err != KErrNone )
{
return err;
}
TFileName setfile;
setfile.Append(KUIStoreDefaultDir);
setfile.Append(aSetName);
RFs fs;
err = fs.Connect();
if( err != KErrNone )
{
fs.Close();
return err;
}
err = fs.Delete( setfile );
if ( err != KErrNone )
{
fs.Close();
return err;
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: UnloadTestSet
Description: Unloads active test set.
Parameters: TDesC& aSetName: in: test set name (Max length is KMaxName)
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::UnloadTestSet( const TDesC& aSetName )
{
TPtrC setName;
TFileName tmp;
TInt ret = ParseTestSetName( aSetName, setName, tmp );
if( ret != KErrNone )
{
return ret;
}
TInt count = iTestSets.Count();
TInt index = 0;
for( ; index < count; index++ )
{
if( iTestSets[index]->Name() == setName )
{
break;
}
}
if( index == count )
{
return KErrNotFound;
}
CTestSetInfo* setInfo = iTestSets[index];
iTestSets.Remove( index );
// If started test set keeps info about currently removed test set
// then remove also this info
CStartedTestSet *stset;
for(index = 0; index < iStartedTestSets.Count(); index++)
{
stset = iStartedTestSets[index];
if(stset->GetOriginalTestSet() == setInfo)
{
stset->NullOriginalTestSet();
}
}
delete setInfo;
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: TestSets
Description: Query test sets.
Parameters:RRefArray<CTestSetInfo>& aSetInfos: out: list of test sets
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::TestSets( RRefArray<CTestSetInfo>& aSetInfos )
{
TInt count = iTestSets.Count();
for( TInt i=0; i<count; i++ )
{
if( aSetInfos.Append( *iTestSets[i] ) != KErrNone )
{
return KErrNoMemory;
}
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: TestSets
Description: Query test sets.
Parameters:RRefArray<CTestSetInfo>& aSetInfos: out: list of test sets
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C const CTestSetInfo& CUIStore::TestSetL( const TDesC& aSetName )
{
TPtrC setName;
TFileName tmp;
User::LeaveIfError( ParseTestSetName( aSetName, setName, tmp ) );
CTestSetInfo* setInfo = NULL;
User::LeaveIfError( FindSetByName( setName, setInfo ) );
return *setInfo;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: AddToTestSet
Description: Add test case to test set.
Parameters: TDesC& aSetName: out: test set name
CTestInfo& aTestInfo: in: test case to add
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::AddToTestSet( const TDesC& aSetName,
const CTestInfo& aTestInfo )
{
TPtrC setName;
TFileName tmp;
TInt ret = ParseTestSetName( aSetName, setName, tmp );
if( ret != KErrNone )
{
return ret;
}
CTestSetInfo* setInfo = NULL;
ret = FindSetByName( setName, setInfo );
if( ret != KErrNone )
{
return ret;
}
return setInfo->AddTestCase( aTestInfo );
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: InsertToTestSet
Description: Insert test case to test set.
Parameters: TDesC& aSetName: out: test set name
CTestInfo& aTestInfo: in: test case to add
TInt aPos: in: position to add
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::InsertToTestSet( const TDesC& aSetName,
const CTestInfo& aTestInfo,
TInt aPos )
{
TPtrC setName;
TFileName tmp;
TInt ret = ParseTestSetName( aSetName, setName, tmp );
if( ret != KErrNone )
{
return ret;
}
CTestSetInfo* setInfo = NULL;
ret = FindSetByName( setName, setInfo );
if( ret != KErrNone )
{
return ret;
}
return setInfo->InsertTestCase( aTestInfo, aPos );
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: RemoveFromTestSet
Description: Remove test case from test set.
Parameters: TDesC& aSetName: out: test set name
CTestInfo& aTestInfo: in: test case to remove
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::RemoveFromTestSet( const TDesC& aSetName,
const CTestInfo& aTestInfo )
{
TPtrC setName;
TFileName tmp;
TInt ret = ParseTestSetName( aSetName, setName, tmp );
if( ret != KErrNone )
{
return ret;
}
CTestSetInfo* setInfo = NULL;
ret = FindSetByName( setName, setInfo );
if( ret != KErrNone )
{
return ret;
}
return setInfo->RemoveTestCase( aTestInfo );
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: SaveTestSet
Description: Save test set. Deprecated, SaveTestSet2 to be used instead
Parameters: TDesC&: out: test set name
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::SaveTestSet( const TDesC& /* aSetName */ )
{
return KErrNotSupported;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: SaveTestSet2
Description: Save test set.
Parameters: TDes& aSetName: out: test set name
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::SaveTestSet2( TDes& aSetName )
{
RRefArray<TDesC> testsets;
GetTestSetsList(testsets);
TBool isexist(EFalse);
for(TInt i=0;i<testsets.Count();i++)
{
if(testsets[i]==aSetName)
{
isexist=ETrue;
break;
}
}
testsets.Reset();
if(!isexist)
{
TTime current;
TDateTime date_rep;
current.HomeTime();
date_rep = current.DateTime();
TBuf<32> currSetName;
_LIT(f_ext,".set");
//create "test set name" string
currSetName.AppendNum(date_rep.Year());
currSetName.Append('_');
currSetName.AppendNum(date_rep.Month()+1); // Incrimination necessary, because Day and Month fields of TDateTime class are 0 based
currSetName.Append('_');
currSetName.AppendNum(date_rep.Day()+1);
currSetName.Append('_');
currSetName.AppendNum(date_rep.Hour());
currSetName.Append('_');
currSetName.AppendNum(date_rep.Minute());
currSetName.Append('_');
currSetName.AppendNum(date_rep.Second());
currSetName.Append(f_ext);
for(TInt i=0;i<iTestSets.Count();i++)
{
if(iTestSets[i]->Name()==aSetName)
{
iTestSets[i]->RenameTestSet(currSetName);
}
}
aSetName.Zero();
aSetName.Copy(currSetName);
}
TPtrC setName;
TFileName tmp;
TInt ret = ParseTestSetName( aSetName, setName, tmp );
if( ret != KErrNone )
{
return ret;
}
CTestSetInfo* setInfo = NULL;
ret = FindSetByName( setName, setInfo );
if( ret != KErrNone )
{
return ret;
}
TRAPD( err,
SaveTestSetL( *setInfo, aSetName );
);
return err;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: LoadTestSet
Description: Load test set.
Parameters: TDesC& aSetName: out: test set name
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::LoadTestSet( const TDesC& aSetName )
{
TPtrC setName;
TFileName tmp;
TInt ret = ParseTestSetName( aSetName, setName, tmp );
if( ret != KErrNone )
{
return ret;
}
CTestSetInfo* setInfo= NULL;
FindSetByName( setName, setInfo );
if(setInfo != NULL)
{
return KErrNone;
}
TRAPD( err,
setInfo = CTestSetInfo::NewL( aSetName );
);
if( err != KErrNone )
{
return err;
}
if( iTestSets.Append( setInfo ) != KErrNone )
{
delete setInfo;
return KErrNoMemory;
}
TRAP( err,
LoadTestSetL( setName, aSetName );
);
if( err != KErrNone && err != KErrAlreadyExists )
{
RemoveTestSet( setName );
}
return err;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: UpdateTestSet
Description: Updates (on storage) earlier saved test set.
Parameters: CTestSetInfo& aSetInfo: in: test set
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::UpdateTestSet(CTestSetInfo& aSetInfo)
{
TRAPD(err,
UpdateTestSetL(aSetInfo, aSetInfo.Name());
);
return err;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: StartTestSet
Description: Start selected test set identified with CTestSetInfo.
Parameters: const CTestSetInfo& aTestSetInfo: in: Started test set
TInt& anIndex: out index in StartedTestSet array,
which is valid only during execution of calling
function.
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::StartTestSet( const CTestSetInfo& aTestSetInfo,
TInt& anIndex,
CStartedTestSet::TSetType aType )
{
return StartTestSet(aTestSetInfo, anIndex, aType, EFalse);
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: StartTestSet
Description: Start selected test set identified with CTestSetInfo.
Parameters: const CTestSetInfo& aTestSetInfo: in: Started test set
TInt& anIndex: out index in StartedTestSet array,
which is valid only during execution of calling
function.
TSetType aType: sequential or paraller
TBool aNotExecutedCasesMode: only test case which haven't been
executed yet
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::StartTestSet( const CTestSetInfo& aTestSetInfo,
TInt& anIndex,
CStartedTestSet::TSetType aType,
TBool aNotStartedCasesMode )
{
TInt ret = KErrNone;
CStartedTestSet* set = NULL;
TRAPD( err,
set = CStartedTestSet::NewL( this, aTestSetInfo, aType );
);
if( err != KErrNone )
{
return err;
}
if( iStartedTestSets.Append( set ) != KErrNone )
{
delete set;
return KErrNoMemory;
}
// Set mode in which only still not executed test cases will be run.
// It applies only to sequential execution.
set->SetNotStartedCasesMode(aNotStartedCasesMode);
ret = set->StartNext();
anIndex = iStartedTestSets.Find( set );
if( anIndex < 0 )
{
User::Panic( KUIStore, KErrNotFound );
}
// Check that testset starting was successful
if( ret != KErrNone )
{
iStartedTestSets.Remove( anIndex );
anIndex = KErrNotFound; // safety
delete set;
return ret;
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: AbortTestSet
Description: Abort running test set.
Parameters: None
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::AbortTestSet( CStartedTestSet& aSetInfo )
{
return aSetInfo.Abort();
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: StartedTestSetL
Description: Return started (running/runned) test set.
Parameters: TInt anIndex: out index in StartedTestSet array
Return Values: CStartedTestSet&: reference to test set
Errors/Exceptions: Leaves on error.
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C CStartedTestSet& CUIStore::StartedTestSetL( TInt anIndex)
{
if( anIndex < 0 ||
anIndex >= iStartedTestSets.Count() )
{
User::Leave( KErrNotFound );
}
return *iStartedTestSets[ anIndex ];
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: StartedTestSets
Description: Return started (running/runned) test cases
Parameters: RRefArray<CStartedTestSet>& aTestCases: out: list of test sets
TInt aStatus: in: status of queried sets
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::StartedTestSets( RRefArray<CStartedTestSet>& aTestSets,
TInt aStatus )
{
TInt count = iStartedTestSets.Count();
for( TInt i = 0; i < count; i++ )
{
if( ( aStatus != CUIStoreIf::ESetAll) &&
!( iStartedTestSets[i]->Status() & aStatus ) )
{
continue;
}
if( aTestSets.Append( *iStartedTestSets[i] ) != KErrNone )
{
return KErrNoMemory;
}
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: LoadSavedTestCases
Description: Load saved testcases.
Parameters: None
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::LoadSavedTestCases()
{
TRAPD( err,
LoadExecutedTestCasesL();
);
return err;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: GetTestSetsList
Description: Returns menu item text.
Parameters: const TInt :in: Menu index
Return Values: const TDesC& Menu line text
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C TInt CUIStore::GetTestSetsList( RRefArray<TDesC>& aArray )
{
RFs fileReader;
CDir* dirContents = NULL;
_LIT(KSetPattern,".set");
TInt entNum = 0;
TInt ret = 0;
HBufC* fName = NULL;
ret = fileReader.Connect();
if (ret != KErrNone)
return ret;
ret = fileReader.GetDir(KUIStoreDefaultDir,
KEntryAttNormal | KEntryAttHidden | KEntryAttSystem,
ESortByName | EDirsFirst | EAscending,
dirContents);
fileReader.Close();
if (ret != KErrNone)
{
delete dirContents;
return ret;
}
entNum = dirContents->Count();
for (int i = 0;i<entNum;i++)
{
if ((!dirContents->operator[](i).IsDir())&&
dirContents->operator[](i).iName.Find(KSetPattern)!=KErrNotFound)
{
TRAPD( err, fName = HBufC::NewL(64) );
if( err != KErrNone )
{
delete dirContents;
return err;
}
*fName = dirContents->operator[](i).iName;
ret = iFileList.Append(fName);
if (ret != KErrNone)
{
delete fName;
delete dirContents;
return ret;
}
ret = aArray.Append(*fName);
if (ret != KErrNone)
{
delete fName;
delete dirContents;
return ret;
}
}
}
delete dirContents;
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: FindSetByName
Description: Finds test set by name.
Parameters: const TDesC& aSetName: in: set name
CTestSetInfo*& aSetInfo: out: pointer to test set
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::FindSetByName( const TDesC& aSetName,
CTestSetInfo*& aSetInfo )
{
TInt count = iTestSets.Count();
for( TInt i=0; i<count; i++ )
{
if( iTestSets[i]->Name() == aSetName )
{
aSetInfo = iTestSets[i];
return KErrNone;
}
}
return KErrNotFound;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: FindSetByCase
Description: Finds test set by name.
Parameters: const CStartedTestCase* aTestCase: in: running test case
CStartedTestSet*& aSet: out: set running test case
Return Values: KErrNotFound: test case is not runned by any test set
KErrNone: test case was runned by aSet
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::FindStartedSetByCase( const CStartedTestCase* aTestCase,
CStartedTestSet*& aSet )
{
TInt count = iStartedTestSets.Count();
for( TInt i=0; i<count; i++ )
{
if( iStartedTestSets[i]->IsRunning( aTestCase ) )
{
aSet = iStartedTestSets[i];
return KErrNone;
}
}
return KErrNotFound;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: LoadTestSetL
Description: Load test set.
Parameters: TDesC& aSetName: out: test set name
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
void CUIStore::LoadTestSetL( const TDesC& aSetName, const TDesC& /*aSetFileName*/ )
{
TPtrC tmp;
TInt num;
TInt high;
TInt64 interval;
CStifParser* parser = CStifParser::NewL( KUIStoreDefaultDir, aSetName );
CleanupStack::PushL( parser );
CStifSectionParser* section =
parser->SectionL( KUIStoreSetStart, KUIStoreSetEnd );
CleanupStack::PushL( section );
CStifItemParser* item;
// Get started test case (if possible)
TUint lastStartedCaseIndex = 0;
item = section->GetItemLineL(KUIStoreLastStartedCaseIndex);
if(item)
{
CleanupStack::PushL(item);
TInt r = item->GetInt(KUIStoreLastStartedCaseIndex, lastStartedCaseIndex);
CleanupStack::PopAndDestroy(item);
if(r != KErrNone)
{
__TRACE(KInit, (_L("Could not read [%S] from test set file. Result [%d]."), &KUIStoreLastStartedCaseIndex, r));
}
}
else
{
__TRACE(KInit, (_L("Could not find [%S] from test set file."), &KUIStoreLastStartedCaseIndex));
}
CTestSetInfo* setInfo = NULL;
User::LeaveIfError( FindSetByName( aSetName, setInfo ) );
// Update started case
setInfo->SetLastStartedCaseIndex(lastStartedCaseIndex);
CTestInfo* testInfo = CTestInfo::NewL();
CleanupStack::PushL( testInfo );
CStifSectionParser* subSection =
section->SubSectionL( KUIStoreSetCaseStart, KUIStoreSetCaseEnd );
while( subSection )
{
CleanupStack::PushL( subSection );
// Get module name
// Mandatory, leave if not found
User::LeaveIfError(
subSection->GetLine( KUIStoreCaseModuleName, tmp, ENoTag ) );
testInfo->SetModuleName( tmp );
// Get test case title
// Mandatory, leave if not found
User::LeaveIfError(
subSection->GetLine( KUIStoreTestCaseTitle, tmp, ENoTag ) );
testInfo->SetTestCaseTitle( tmp );
// Get test case file
num = subSection->GetLine( KUIStoreTestCaseFile, tmp, ENoTag );
if( ( num == KErrNone ) &&
( tmp.Length() > 0 ) )
{
// Optional
testInfo->SetTestCaseFile( tmp );
}
// Get test case number
item = subSection->GetItemLineL( KUIStoreTestCaseNum );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreTestCaseNum, num ));
testInfo->SetTestCaseNumber( num );
CleanupStack::PopAndDestroy( item );
// Get test case priority
item = subSection->GetItemLineL( KUIStoreCasePriority );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreCasePriority, num ));
testInfo->SetPriority( num );
CleanupStack::PopAndDestroy( item );
// Get test case timeout
item = subSection->GetItemLineL( KUIStoreCaseTimeout );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreCaseTimeout, num ));
User::LeaveIfError( item->GetNextInt( high ));
//@js<--remove--> interval.Set( high, num );
interval = MAKE_TINT64( high, num );
TTimeIntervalMicroSeconds timeout( interval );
testInfo->SetTimeout( timeout );
CleanupStack::PopAndDestroy( item );
User::LeaveIfError( setInfo->AddTestCase( *testInfo ) );
CleanupStack::PopAndDestroy( subSection );
subSection =
section->NextSubSectionL( KUIStoreSetCaseStart, KUIStoreSetCaseEnd );
}
CleanupStack::PopAndDestroy( testInfo );
CleanupStack::PopAndDestroy( section );
CleanupStack::PopAndDestroy( parser );
const RRefArray<const CTestInfo>& testCases = setInfo->TestCases();
LoadTestModulesAndTestCaseFilesL( testCases );
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: SaveTestSetL
Description: Save test set.
Parameters: CTestSetInfo& aSetInfo: in: test set
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
void CUIStore::SaveTestSetL( CTestSetInfo& aSetInfo, const TDesC& aSetFileName )
{
//Extract path
TParse p;
p.Set(aSetFileName, NULL, NULL);
TPtrC path = p.DriveAndPath(); // gives path for test set
TPtrC fn = p.NameAndExt(); // gives filename with extension
if(path.Length() == 0)
{
path.Set(KUIStoreDefaultDir);
}
//Create file server
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
//Create or open file
RFile file;
TFileName filename = path;
filename.Append(fn);
TInt r = file.Replace(fs, filename, EFileWrite);
if(r != KErrNone)
{
User::Leave(r);
}
else
{
CleanupClosePushL(file);
RBuf buffer;
buffer.Create(256);
CleanupClosePushL(buffer);
// Saving
buffer.Format(_L("%S"), &KUIStoreSetStart);
WriteLineL(file, buffer);
// Saving test set causes reset of index
aSetInfo.SetLastStartedCaseIndex(0);
buffer.Format(_L("%S "), &KUIStoreLastStartedCaseIndex);
buffer.AppendNumFixedWidth(aSetInfo.GetLastStartedCaseIndex(), EDecimal, KFixedStartedCaseIndex);
WriteLineL(file, buffer);
// Saving test cases
TInt count = aSetInfo.TestCases().Count();
for(TInt i = 0; i < count; i++)
{
WriteLineL(file, KNullDesC);
buffer.Format(_L("%S"), &KUIStoreSetCaseStart);
WriteLineL(file, buffer);
buffer.Format(_L("%S %S"), &KUIStoreCaseModuleName, &aSetInfo.TestCases()[i].ModuleName());
WriteLineL(file, buffer);
buffer.Format(_L("%S %S"), &KUIStoreTestCaseTitle, &aSetInfo.TestCases()[i].TestCaseTitle());
WriteLineL(file, buffer);
if(aSetInfo.TestCases()[i].TestCaseFile().Length() > 0)
{
buffer.Format(_L("%S %S"), &KUIStoreTestCaseFile, &aSetInfo.TestCases()[i].TestCaseFile());
WriteLineL(file, buffer);
}
buffer.Format(_L("%S %d"), &KUIStoreTestCaseNum, aSetInfo.TestCases()[i].TestCaseNum());
WriteLineL(file, buffer);
buffer.Format(_L("%S %d"), &KUIStoreCasePriority, aSetInfo.TestCases()[i].Priority());
WriteLineL(file, buffer);
buffer.Format(_L("%S %d %d"), &KUIStoreCaseTimeout, I64LOW(aSetInfo.TestCases()[i].Timeout().Int64()),
I64HIGH(aSetInfo.TestCases()[i].Timeout().Int64()));
WriteLineL(file, buffer);
buffer.Format(_L("%S %d"), &KUIStoreCaseExpectedResult, aSetInfo.TestCases()[i].ExpectedResult());
WriteLineL(file, buffer);
buffer.Format(_L("%S"), &KUIStoreSetCaseEnd);
WriteLineL(file, buffer);
}
WriteLineL(file, KNullDesC);
buffer.Format(_L("%S"), &KUIStoreSetEnd);
WriteLineL(file, buffer);
CleanupStack::PopAndDestroy(&buffer);
CleanupStack::PopAndDestroy(&file);
}
CleanupStack::PopAndDestroy(&fs);
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: UpdateTestSetL
Description: Updates information in test set file.
Parameters: CTestSetInfo& aSetInfo: in: test set
Return Values: Symbian OS error code
Errors/Exceptions: Leaves when writing to file fails
Leaves when file.seek fails
Leaves when can't connect to file server
Status: Approved
-------------------------------------------------------------------------------
*/
void CUIStore::UpdateTestSetL(CTestSetInfo& aSetInfo, const TDesC& aSetFileName)
{
// Get path
TParse p;
p.Set(aSetFileName, NULL, NULL);
TPtrC path = p.DriveAndPath(); // gives path for test set
TPtrC fn = p.NameAndExt(); // gives filename with extension
if(path.Length() == 0)
{
path.Set(KUIStoreDefaultDir);
}
//Create file server
RFs fs;
User::LeaveIfError(fs.Connect());
CleanupClosePushL(fs);
//Create or open file
RFile file;
TFileName filename = path;
filename.Append(fn);
TInt foundpos = KErrNotFound;
TInt r = file.Open(fs, filename, EFileWrite);
if(r != KErrNone)
{
User::Leave(r);
}
else
{
CleanupClosePushL(file);
//Search for line
RBuf buffer;
buffer.Create(256);
CleanupClosePushL(buffer);
//Prepare file
TInt pos = 0;
User::LeaveIfError(file.Seek(ESeekStart, pos));
//Read file
ReadLineL(file, buffer);
while(buffer.Length() > 0)
{
// Keep remembering current position
if(buffer.Find(KUIStoreLastStartedCaseIndex) == 0)
{
foundpos = pos;
break;
}
// What is current position
pos = 0;
User::LeaveIfError(file.Seek(ESeekCurrent, pos));
// Read next line from file
ReadLineL(file, buffer);
}
if(foundpos != KErrNotFound)
{
// Position was found. Just update that line (save index of last
// started test case)
RBuf8 b;
b.Create(40);
CleanupClosePushL(b);
b.Copy(KUIStoreLastStartedCaseIndex);
b.Append(_L8(" "));
b.AppendNumFixedWidth(aSetInfo.GetLastStartedCaseIndex(), EDecimal, KFixedStartedCaseIndex);
User::LeaveIfError(file.Seek(ESeekStart, foundpos));
User::LeaveIfError(file.Write(b));
CleanupStack::PopAndDestroy(&b);
}
CleanupStack::PopAndDestroy(&buffer);
CleanupStack::PopAndDestroy(&file);
}
CleanupStack::PopAndDestroy(&fs);
if(foundpos == KErrNotFound)
{
// Position of KUIStoreLastStartedCaseIndex could not be found.
// Store the whole file.
SaveTestSetL(aSetInfo, aSetFileName);
}
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ReadLineL
Description: Read the whole line from the file. If there is enough space,
the whole content of line will be returned in buffer.
Parameters: RFile& file: in: file to be read
TDes8& buffer: out: buffer to be returned
Return Values: None
Errors/Exceptions: Leaves if RFile::Read method fails
Status: Approved
-------------------------------------------------------------------------------
*/
void CUIStore::ReadLineL(RFile &file, TDes& buffer)
{
TBuf8<1> c;
TBuf<1> c16;
buffer.Copy(KNullDesC);
User::LeaveIfError(file.Read(c));
while(c.Length() > 0)
{
// There is still place to write to the dest buffer
if(buffer.Length() < buffer.MaxLength())
{
c16.Copy(c);
buffer.Append(c16);
}
// Stop reading if end of line
if(c[0] == 0x0A)
{
break;
}
User::LeaveIfError(file.Read(c));
}
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: WriteLineL
Description: Write given line to the file and adds end of line.
Parameters: RFile& file: in: file to be written
TDesC& buffer: in: buffer to be written
Return Values: None
Errors/Exceptions: Leaves if RFile::Write method fails
Status: Approved
-------------------------------------------------------------------------------
*/
void CUIStore::WriteLineL(RFile &file, const TDesC& buffer)
{
if(buffer.Length() > 0)
{
// Create 8-bit buffer
RBuf8 buf;
buf.Create(buffer.Length());
CleanupClosePushL(buf);
buf.Copy(buffer);
// Write buffer to file + end of line
User::LeaveIfError(file.Write(buf));
// Delete 8-bit buffer
CleanupStack::PopAndDestroy(&buf);
}
// Write end of line
TBuf8<2> eoline;
eoline.Copy(_L("\r\n"));
User::LeaveIfError(file.Write(eoline));
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: LoadTestModulesL
Description: Load test modules.
Parameters: CTestSetInfo& aSetInfo: in: test set
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
void CUIStore::LoadTestModulesAndTestCaseFilesL(
const RRefArray<const CTestInfo>& aTestCases )
{
RRefArray<TDesC> testCaseFiles;
RRefArray<TDesC> testModules;
CleanupClosePushL( testCaseFiles );
CleanupClosePushL( testModules );
User::LeaveIfError( Modules( testModules ) );
TInt cCount = aTestCases.Count();
TInt mCount = 0;
TInt mInd=0;
TInt fCount = 0;
TInt fInd=0;
for( TInt cInd=0; cInd<cCount; cInd++ )
{
mCount = testModules.Count();
for( mInd=0; mInd<mCount; mInd++ )
{
if( aTestCases[cInd].ModuleName() == testModules[mInd] )
{
// Test module already loaded
break;
}
}
if( mInd == mCount )
{
// Not found, load test module
if( AddTestModule( aTestCases[cInd].ModuleName() ) == KErrNone )
{
User::LeaveIfError(
testModules.Append( aTestCases[cInd].ModuleName() ) );
}
}
if( aTestCases[cInd].TestCaseFile().Length() == 0 )
{
// Test case file is not used, continue
continue;
}
testCaseFiles.Reset();
User::LeaveIfError(
TestCaseFiles( testCaseFiles, aTestCases[cInd].ModuleName() ));
fCount = testCaseFiles.Count();
for( fInd=0; fInd<fCount; fInd++ )
{
if( aTestCases[cInd].TestCaseFile() == testCaseFiles[fInd] )
{
// Testcasefile already loaded
break;
}
}
if( fInd == fCount )
{
// Load test module
if( AddTestCaseFile( aTestCases[cInd].ModuleName(),
aTestCases[cInd].TestCaseFile() ) == KErrNone )
{
User::LeaveIfError(
testCaseFiles.Append( aTestCases[cInd].TestCaseFile() ) );
}
}
}
CleanupStack::PopAndDestroy(); // testModules
CleanupStack::PopAndDestroy(); // testCaseFiles
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: TestExecuted
Description: Test case executed callback from UI engine.
Parameters: CUIEngineContainer* const aContainer: in: Execution container
TFullTestResult& aFullTestResult: in: test result
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
void CUIStore::TestExecuted ( CUIEngineContainer* aContainer,
TFullTestResult& aFullTestResult )
{
CStartedTestCase* testCase = NULL;
if( FindByContainer( aContainer, testCase ) != KErrNone )
{
__TRACE( KError, ( CStifLogger::EError, _L("CUIStore::TestExecuted: Not found")));
return;
}
CStartedTestSet* set = NULL;
TInt setStatus = 0;
if( FindStartedSetByCase( testCase, set ) == KErrNone )
{
setStatus = set->Status();
set->TestCompleted( testCase, aFullTestResult );
setStatus |= set->Status();
}
// Check and delete all pending popup windows for test case
TInt count = iPopups.Count();
for( TInt i = 0; i<count; i++ )
{
if( iPopups[i]->Container() == aContainer )
{
delete iPopups[i];
iPopups.Remove( i );
}
}
// Get old status
TInt status = testCase->Status();
// Set result
testCase->SetResult( aFullTestResult );
// Get new status
status |= testCase->Status();
// Add set status flags
status |= setStatus;
iUIStoreIf->Update( testCase, status );
return;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: PrintProg
Description: Progress information from test case execution,
callback from UI engine.
Parameters: CUIEngineContainer* const aContainer: in: Execution container
TTestProgress& aProgress: in: print info
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::PrintProg ( CUIEngineContainer* aContainer,
TTestProgress& aProgress )
{
if( aContainer == NULL )
{
return KErrArgument;
}
if( ( aProgress.iDescription.Length() == 0 ) &&
( aProgress.iText.Length() == 0 ) )
{
return KErrArgument;
}
CStartedTestCase* testCase = NULL;
if( FindByContainer( aContainer, testCase ) != KErrNone )
{
__TRACE( KError, ( CStifLogger::EError, _L("CUIStore::TestExecuted: Not found")));
return KErrNotFound;
}
TInt position = KErrNotFound;
TInt smallPos = KErrNotFound;
// Search the array to find the position
const TInt count = testCase->PrintArray().Count();
for (TInt i = 0; i < count; i++)
{
// Check if that item is already on list
if ( testCase->PrintArray()[i]->iDescription == aProgress.iDescription &&
testCase->PrintArray()[i]->iPosition == aProgress.iPosition )
{
// Set it to be updated
position = i;
break;
}
// Found a smaller priority item from list
if ( aProgress.iPosition < testCase->PrintArray()[i]->iPosition )
{
smallPos = i;
break;
}
}
// Either update item in array or add new item to array
if ( position != KErrNotFound )
{
// Replace existing text
testCase->PrintArray()[position]->ReplaceTextL( aProgress );
}
else
{
CTestProgress* prog = NULL;
TRAPD( err,
// Allocate new
prog = CTestProgress::NewL( aProgress );
);
if( err != KErrNone )
{
return err;
}
if ( smallPos != KErrNotFound )
{
if( testCase->PrintArray().Insert( prog, smallPos ) != KErrNone )
{
delete prog;
return KErrNoMemory;
}
}
else
{
if( testCase->PrintArray().Append( prog ) != KErrNone )
{
delete prog;
return KErrNoMemory;
}
}
}
iUIStoreIf->Update( testCase, CUIStoreIf::EPrintUpdate );
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: PrintProg
Description: Error information from Test framework,
callback from UI engine.
Parameters: CUIEngineContainer* const aContainer: in: Execution container
TErrorNotification& aError: in: error info
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::ErrorPrint( TErrorNotification& aError )
{
if( aError.iText.Length() == 0 )
{
return KErrArgument;
}
iUIStoreIf->Error( aError );
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: RemoteMsg
Description: Remote protocol control messages handling.
Parameters: const TDesC& aMessage: in: Remote message
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::RemoteMsg( CUIEngineContainer* aContainer,
const TDesC& aMessage)
{
if( ( aMessage.Length() == 0 ) ||
( aContainer == NULL ) )
{
return KErrArgument;
}
TInt ret = KErrNone;
TInt error = KErrNone;
CStifTFwIfProt* msg = NULL;
CStifTFwIfProt* resp = NULL;
TRAPD( err, msg = CStifTFwIfProt::NewL(); );
if( err != KErrNone )
{
return err;
}
TRAP( err, resp = CStifTFwIfProt::NewL(); );
if( err != KErrNone )
{
delete msg;
return err;
}
// Parse received message
TRAP( err,
error = msg->SetL( aMessage )
);
if( err != KErrNone )
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: message header parsing failed [%d]"), err ) );
delete msg;
delete resp;
return err;
}
// Create response
TRAP( err, resp->CreateL(); );
if( err != KErrNone )
{
delete msg;
delete resp;
return err;
}
resp->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgResponse );
if( error != KErrNone )
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: message parsing failed [%d]"), error ) );
resp->AppendId( SETID( (TInt32)DevId(), 0 ) );
resp->AppendId( msg->SrcId() );
resp->Append( CStifTFwIfProt::MsgType, msg->iMsgType );
resp->Append( CStifTFwIfProt::RespParam, CStifTFwIfProt::ERespResult, error );
aContainer->RemoteReceive( resp->Message() );
// Error reported with protocol message, return success
delete msg;
delete resp;
return KErrNone;
}
TBool sendResp = ETrue;
switch( msg->iMsgType )
{
case CStifTFwIfProt::EMsgReserve:
{
// Check IDs
if( ( msg->SrcDevId() == 0 ) ||
( msg->SrcTestId() == 0 ) )
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: reserve for illegal srcid received") ) );
error = KErrGeneral;
}
if( msg->DstId() != 0 )
{
// Not a broadcast
if( ( msg->DstDevId() != DevId() ) ||
( msg->DstTestId() != 0 ) )
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: reserve for illegal dstid received") ) );
error = KErrGeneral;
}
}
resp->AppendId( SETID( (TInt32)DevId(), 0 ) );
resp->AppendId( msg->SrcId() );
resp->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgReserve );
if( error != KErrNone )
{
resp->Append( CStifTFwIfProt::RespParam, CStifTFwIfProt::ERespResult, error );
}
}
break;
case CStifTFwIfProt::EMsgRelease:
{
// Check protocol ids
if( ( msg->SrcDevId() == 0 ) ||
( msg->SrcTestId() == 0 ) ||
( msg->DstTestId() != 0 ) )
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: release for illegal srcid or dstid received") ) );
error = KErrGeneral;
}
else if( msg->DstDevId() != DevId() )
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: release for illegal dstid received") ) );
error = KErrNotFound;
}
resp->AppendId( msg->DstId() );
resp->AppendId( msg->SrcId() );
resp->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRelease );
if( error != KErrNone )
{
resp->Append( CStifTFwIfProt::RespParam, CStifTFwIfProt::ERespResult, error );
}
}
break;
case CStifTFwIfProt::EMsgRemote:
{
// Check protocol ids
if( ( msg->SrcDevId() == 0 ) ||
( msg->SrcTestId() == 0 ) ||
( msg->DstDevId() == 0 ) )
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: remote for illegal srcid or dstid received") ) );
error = KErrGeneral;
}
else
{
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: received remote call") ) );
error = MsgRemote( aContainer, *msg, *resp );
}
if( error != KErrNone )
{
resp->AppendId( msg->DstId() );
resp->AppendId( msg->SrcId() );
resp->Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote );
resp->Append( msg->iCmdDes );
resp->Append( CStifTFwIfProt::RespParam,
CStifTFwIfProt::ERespResult,
error );
}
else
{
sendResp = EFalse;
}
}
break;
case CStifTFwIfProt::EMsgResponse:
default:
__TRACE( KError, ( _L( "CUIStore::RemoteMsg: invalid message")) );
ret = KErrNotSupported;
}
if( ( ret == KErrNone ) && sendResp )
{
aContainer->RemoteReceive( resp->Message() );
}
delete msg;
delete resp;
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: MsgRemote
Description: Remote command
Parameters: const TDesC& aMessage: in:
Return Values: KErrNotSupported
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::MsgRemote( CUIEngineContainer* aContainer,
CStifTFwIfProt& aReq,
CStifTFwIfProt& aResp )
{
TInt ret = KErrNone;
switch( aReq.iCmdType )
{
case CStifTFwIfProt::ECmdRun:
ret = MsgRemoteRun( aContainer, aReq, aResp );
break;
case CStifTFwIfProt::ECmdPause:
case CStifTFwIfProt::ECmdResume:
case CStifTFwIfProt::ECmdCancel:
ret = MsgRemoteTestCtl( aContainer, aReq, aResp );
break;
case CStifTFwIfProt::ECmdRequest:
case CStifTFwIfProt::ECmdRelease:
ret = MsgRemoteEventCtl( aContainer, aReq, aResp );
break;
case CStifTFwIfProt::ECmdSendReceive:
{
ret = MsgRemoteSendReceive( aContainer, aReq, aResp );
break;
}
default:
{
CStifTFwIfProt* resp = NULL;
TRAPD( err,
resp = CStifTFwIfProt::NewL();
resp->CreateL();
);
if( err != KErrNone )
{
delete resp;
return err;
}
resp->SetMsgType( CStifTFwIfProt::EMsgResponse );
resp->SetSrcId( aReq.DstId() );
resp->SetDstId( aReq.SrcId() );
resp->SetRespType( CStifTFwIfProt::EMsgRemote );
// Command type must be set separately,
// because it is unspecified in this case
resp->iCmdType = aReq.iCmdType;
resp->Append( aReq.iCmdDes );
ret = RemotePopup( aContainer, aReq.Message(), resp );
if( ret != KErrNone )
{
delete resp;
}
}
break;
}
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: AtsRemoteRun
Description: Remote run message
Parameters: const TDesC& aMessage: in:
Return Values: KErrNotSupported
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::MsgRemoteRun( CUIEngineContainer* aContainer,
CStifTFwIfProt& aReq,
CStifTFwIfProt& /* aResp */)
{
TInt ret = KErrNone;
TUint16 testid = 0;
if( ( aReq.DstDevId() == 0 ) ||
( aReq.DstTestId() != 0 ) )
{
// Protocol violation
__TRACE( KError, ( _L( "AtsReceive: remote run for illegal dstid received") ) );
return KErrGeneral;
}
if ( aReq.DstDevId() != DevId() )
{
// Not our protocol message
__TRACE( KError, ( _L( "AtsReceive: remote run for illegal dstdevid received") ) );
return KErrNotFound;
}
if( aReq.iModule.Length() == 0 )
{
__TRACE( KError, ( _L("No mandatory test module name given as run parameter") ) );
ret = KErrNotFound;
}
else if( aReq.iTestCaseNumber < 0 )
{
__TRACE( KError, ( _L("No mandatory test case number given as run parameter") ) );
ret = KErrNotFound;
}
testid = 1;
CStifTFwIfProt* resp = NULL;
TRAPD( err,
resp = CStifTFwIfProt::NewL();
resp->CreateL();
);
if( err != KErrNone )
{
delete resp;
return err;
}
CStifTFwIfProt* resp2 = NULL;
TRAP( err,
resp2 = CStifTFwIfProt::NewL();
resp2->CreateL();
);
if( err != KErrNone )
{
delete resp2;
return err;
}
resp->SetMsgType( CStifTFwIfProt::EMsgResponse );
resp->SetSrcId( SETID( (TInt32)DevId(), testid ) );
resp->SetDstId( aReq.SrcId() );
resp->SetRespType( CStifTFwIfProt::EMsgRemote );
resp->SetCmdType( CStifTFwIfProt::ECmdRun );
resp2->SetMsgType( CStifTFwIfProt::EMsgResponse );
resp2->SetSrcId( SETID( (TInt32)DevId(), testid ) );
resp2->SetDstId( aReq.SrcId() );
resp2->SetRespType( CStifTFwIfProt::EMsgRemote );
resp2->SetCmdType( CStifTFwIfProt::ECmdRun );
// Remote run started popup call
ret = RemotePopup( aContainer, aReq.Message(), resp, EPopupPriorityHighest );
if( ret != KErrNone )
{
delete resp;
}
// Remote run result popup call
ret = RemotePopup( aContainer, aReq.Message(), resp2 );
if( ret != KErrNone )
{
delete resp2;
}
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: MsgRemoteTestCtl
Description: Remote test control message
Parameters: const TDesC& aMessage: in:
Return Values: KErrNotSupported
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::MsgRemoteTestCtl( CUIEngineContainer* aContainer,
CStifTFwIfProt& aReq,
CStifTFwIfProt& /*aResp*/ )
{
TInt ret = KErrNone;
if( ( aReq.DstDevId() == 0 ) ||
( aReq.DstTestId() == 0 ) )
{
// Protocol violation
__TRACE( KError, ( _L( "AtsReceive: remote test control for illegal dstid received") ) );
return KErrGeneral;
}
if ( aReq.DstDevId() != DevId() )
{
// Not our protocol message
__TRACE( KError, ( _L( "AtsReceive: remote test control for illegal dstdevid received") ) );
return KErrNotFound;
}
CStifTFwIfProt* resp = NULL;
TRAPD( err,
resp = CStifTFwIfProt::NewL();
resp->CreateL();
);
if( err != KErrNone )
{
delete resp;
return err;
}
resp->SetMsgType( CStifTFwIfProt::EMsgResponse );
resp->SetSrcId( aReq.DstId() );
resp->SetDstId( aReq.SrcId() );
resp->SetRespType( CStifTFwIfProt::EMsgRemote );
resp->SetCmdType( aReq.iCmdType );
ret = RemotePopup( aContainer, aReq.Message(), resp );
if( ret != KErrNone )
{
delete resp;
}
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: MsgRemoteEventCtl
Description: Remote run message
Parameters: const TDesC& aMessage: in:
Return Values: KErrNotSupported
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::MsgRemoteEventCtl( CUIEngineContainer* aContainer,
CStifTFwIfProt& aReq,
CStifTFwIfProt& aResp )
{
if( ( aReq.DstDevId() == 0 ) ||
( aReq.DstTestId() != 0 ) )
{
// Protocol violation
__TRACE( KError, ( _L( "AtsReceive: remote event control for illegal dstid received") ) );
return KErrGeneral;
}
if ( aReq.DstDevId() != DevId() )
{
// Not our protocol message
__TRACE( KError, ( _L( "AtsReceive: remote event control for illegal dstdevid received") ) );
return KErrNotFound;
}
if( aReq.iEventName.Length() == 0 )
{
__TRACE( KError, ( _L("No event name given") ) );
return KErrNotFound;
}
TInt ret = KErrNone;
switch( aReq.iCmdType )
{
case CStifTFwIfProt::ECmdRequest:
{
// Send event active information
CStifTFwIfProt* resp = NULL;
TRAP( ret,
resp = CStifTFwIfProt::NewL();
resp->CreateL(); );
if( ret != KErrNone )
{
delete resp;
return ret;
}
resp->SetMsgType( CStifTFwIfProt::EMsgResponse );
resp->SetSrcId( aReq.DstId() );
resp->SetDstId( aReq.SrcId() );
resp->SetRespType( CStifTFwIfProt::EMsgRemote );
resp->SetCmdType( CStifTFwIfProt::ECmdRequest );
resp->Append( CStifTFwIfProt::EventStatus,
CStifTFwIfProt::EEventSet );
resp->Append( aReq.iEventName );
ret = RemotePopup( aContainer, aReq.Message(), resp, EPopupPriorityNormal );
if( ret != KErrNone )
{
delete resp;
}
aResp.AppendId( aReq.DstId() );
aResp.AppendId( aReq.SrcId() );
aResp.Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote );
aResp.Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdRequest );
if( ret == KErrNone )
{
aResp.Append( CStifTFwIfProt::EventStatus,
CStifTFwIfProt::EEventActive );
aResp.Append( aReq.iEventName );
}
else
{
aResp.Append( CStifTFwIfProt::EventStatus,
CStifTFwIfProt::EEventError );
aResp.Append( aReq.iEventName );
aResp.Append( CStifTFwIfProt::EventStatusParams,
CStifTFwIfProt::EEventResult,
ret );
}
ret = aContainer->RemoteReceive( aResp.Message() );
ret = KErrNone;
}
break;
case CStifTFwIfProt::ECmdRelease:
{
// Check and delete all pending event popup windows for test case
TInt count = iPopups.Count();
for( TInt i = 0; i<count; i++ )
{
if( ( iPopups[i]->Container() == aContainer ) &&
iPopups[i]->IsEventPopup() )
{
delete iPopups[i];
iPopups.Remove( i );
}
}
aResp.AppendId( aReq.DstId() );
aResp.AppendId( aReq.SrcId() );
aResp.Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote );
aResp.Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdRelease );
aResp.Append( aReq.iEventName );
ret = aContainer->RemoteReceive( aResp.Message() );
ret = KErrNone;
}
break;
default:
return KErrNotSupported;
}
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: MsgRemoteSendReceive
Description: Asynchronous remote sendreceive message
Parameters: CUIEngineContainer* aContainer: in:
CStifTFwIfProt& aReq: in
CStifTFwIfProt& aResp: in
Return Values: KErrNotSupported
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::MsgRemoteSendReceive( CUIEngineContainer* aContainer,
CStifTFwIfProt& aReq,
CStifTFwIfProt& aResp )
{
TInt ret = KErrNone;
// TUint16 testid = 0;
if( ( aReq.DstDevId() == 0 ) ||
( aReq.DstTestId() != 0 ) )
{
// Protocol violation
__TRACE( KError, ( _L( "AtsReceive: remote run for illegal dstid received") ) );
return KErrGeneral;
}
if ( aReq.DstDevId() != DevId() )
{
// Not our protocol message
__TRACE( KError, ( _L( "AtsReceive: remote run for illegal dstdevid received") ) );
return KErrNotFound;
}
// testid = 1;
CStifTFwIfProt* resp = NULL;
TRAPD( err,
resp = CStifTFwIfProt::NewL();
resp->CreateL();
);
if( err != KErrNone )
{
delete resp;
return err;
}
resp->SetMsgType( CStifTFwIfProt::EMsgResponse );
//resp->SetSrcId( SETID( DevId(), testid ) );
resp->SetSrcId( aReq.DstId() );
resp->SetDstId( aReq.SrcId() );
resp->SetRespType( CStifTFwIfProt::EMsgRemote );
resp->SetCmdType( CStifTFwIfProt::ECmdSendReceive );
ret = RemotePopup( aContainer, aReq.Message(), resp );
if( ret != KErrNone )
{
delete resp;
}
aResp.AppendId( aReq.DstId() );
aResp.AppendId( aReq.SrcId() );
aResp.Append( CStifTFwIfProt::MsgType, CStifTFwIfProt::EMsgRemote );
aResp.Append( CStifTFwIfProt::CmdType, CStifTFwIfProt::ECmdSendReceive );
if( ret != KErrNone )
{
aResp.Append( CStifTFwIfProt::RunStatus,
CStifTFwIfProt::ERunError );
aResp.Append( CStifTFwIfProt::RunStatusParams,
CStifTFwIfProt::ERunResult, ret );
}
else
{
aResp.Append( CStifTFwIfProt::RunStatus,
CStifTFwIfProt::ERunStarted );
}
// Send response
aContainer->RemoteReceive( aResp.Message() );
// Response is created, return success
ret = KErrNone;
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: GoingToReboot
Description: Reboot indication handling.
Parameters: CUIEngineContainer* aContainer: in: Container
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::GoingToReboot( CUIEngineContainer* /* aContainer */,
TRequestStatus& aStatus )
{
_LIT( KDateString,"%H%T%S.%C" );
const TInt KTimeFieldLength = 30;
TBuf<KTimeFieldLength> time;
// Store info
CStifLogger* logger = CStifLogger::NewL( KUIStoreDefaultDir,
KUIStoreDefaultRebootFile,
CStifLogger::EData,
CStifLogger::EFile,
ETrue,
EFalse,
EFalse,
EFalse,
EFalse,
ETrue );
CleanupStack::PushL( logger );
TInt count = iStartedTestCases.Count();
for( TInt index=0; index<count; index++ )
{
logger->Log( _L("%S\r\n"), &KUIStoreStartTest );
// First test case info
logger->Log( _L("%S %S\r\n"), &KUIStoreCaseModuleName,
&iStartedTestCases[index]->TestInfo().ModuleName() );
logger->Log( _L("%S %S\r\n"), &KUIStoreTestCaseTitle,
&iStartedTestCases[index]->TestInfo().TestCaseTitle() );
if( iStartedTestCases[index]->TestInfo().TestCaseFile().Length() > 0 )
{
logger->Log( _L("%S %S\r\n"), &KUIStoreTestCaseFile,
&iStartedTestCases[index]->TestInfo().TestCaseFile() );
}
logger->Log( _L("%S %d\r\n"), &KUIStoreTestCaseNum,
iStartedTestCases[index]->TestInfo().TestCaseNum() );
logger->Log( _L("%S %d\r\n"), &KUIStoreCasePriority,
iStartedTestCases[index]->TestInfo().Priority() );
//@js<--remove--> logger->Log( _L("%S %d %d\r\n"), &KUIStoreCaseTimeout,
//@js<--remove--> iStartedTestCases[index]->TestInfo().Timeout().Int64().Low(),
//@js<--remove--> iStartedTestCases[index]->TestInfo().Timeout().Int64().High() );
logger->Log( _L("%S %d %d\r\n"), &KUIStoreCaseTimeout,
I64LOW(iStartedTestCases[index]->TestInfo().Timeout().Int64()),
I64HIGH(iStartedTestCases[index]->TestInfo().Timeout().Int64()));
logger->Log( _L("%S %d\r\n"), &KUIStoreCaseExpectedResult,
iStartedTestCases[index]->TestInfo().ExpectedResult() );
logger->Log( _L("%S %d\r\n"), &KUIStoreCaseStatus,
iStartedTestCases[index]->Status() );
logger->Log( _L("%S %d %d\r\n"), &KUIStoreCaseExecutionResult,
iStartedTestCases[index]->Result().iCaseExecutionResultType,
iStartedTestCases[index]->Result().iCaseExecutionResultCode );
logger->Log( _L("%S %d %S\r\n"), &KUIStoreCaseResult,
iStartedTestCases[index]->Result().iTestResult.iResult,
&iStartedTestCases[index]->Result().iTestResult.iResultDes );
// Start time
iStartedTestCases[index]->Result().iStartTime.FormatL(
time, KDateString );
logger->Log( _L("%S %S\r\n"), &KUIStoreCaseStartTime, &time );
// Start time
iStartedTestCases[index]->Result().iEndTime.FormatL(
time, KDateString );
logger->Log( _L("%S %S\r\n"), &KUIStoreCaseEndTime, &time );
logger->Log( _L("%S\r\n\r\n"), &KUIStoreStartTestEnd );
}
CleanupStack::PopAndDestroy( logger );
// Show popup
TKeyCode key;
iUIStoreIf->PopupMsg( _L("GoingToReboot"),
_L("Press any key to continue"),
KRebootPopupTimeout, key, aStatus );
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: LoadExecutedTestCasesL
Description: Load all executed testcases saved before reboot.
Parameters: None
Return Values: None
Errors/Exceptions: Leaves on error
Status: Draft
-------------------------------------------------------------------------------
*/
void CUIStore::LoadExecutedTestCasesL()
{
TPtrC tmp;
TInt num = 0;
TInt high = 0;
TInt64 interval;
TFullTestResult result;
TInt status = 0;
CStifItemParser* item = NULL;
TInt ret = KErrNone;
CStifParser* parser = NULL;
TRAP( ret,
parser = CStifParser::NewL( KUIStoreDefaultDir,
KUIStoreDefaultRebootFile );
);
if( ret != KErrNone )
{
// reboot file not found
return;
}
CleanupStack::PushL( parser );
__TRACE( KInit, ( _L( "Reboot file is found(%S%S). Reboot testing ongoing..." ), &KUIStoreDefaultDir, &KUIStoreDefaultRebootFile ) );
CTestInfo* testInfo = NULL;
CStifSectionParser* section =
parser->SectionL( KUIStoreStartTest, KUIStoreStartTestEnd );
while( section )
{
CleanupStack::PushL( section );
testInfo = CTestInfo::NewL();
CleanupStack::PushL( testInfo );
// Get module name
// Mandatory, leave if not found
User::LeaveIfError(
section->GetLine( KUIStoreCaseModuleName, tmp, ENoTag ) );
testInfo->SetModuleName( tmp );
// Get test case title
// Mandatory, leave if not found
User::LeaveIfError(
section->GetLine( KUIStoreTestCaseTitle, tmp, ENoTag ) );
testInfo->SetTestCaseTitle( tmp );
// Get test case file
num = section->GetLine( KUIStoreTestCaseFile, tmp, ENoTag );
if( ( num == KErrNone ) &&
( tmp.Length() > 0 ) )
{
// Optional
testInfo->SetTestCaseFile( tmp );
}
else
{
testInfo->SetTestCaseFile( KNullDesC );
}
// Get test case number
item = section->GetItemLineL( KUIStoreTestCaseNum );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreTestCaseNum, num ));
testInfo->SetTestCaseNumber( num );
CleanupStack::PopAndDestroy( item );
// Get test case priority
item = section->GetItemLineL( KUIStoreCasePriority );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreCasePriority, num ));
testInfo->SetPriority( num );
CleanupStack::PopAndDestroy( item );
// Get test case timeout
item = section->GetItemLineL( KUIStoreCaseTimeout );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreCaseTimeout, num ));
User::LeaveIfError( item->GetNextInt( high ));
//interval.Set( high, num );
interval = MAKE_TINT64( high, num );
TTimeIntervalMicroSeconds timeout( interval );
testInfo->SetTimeout( timeout );
CleanupStack::PopAndDestroy( item );
// Get test case status
item = section->GetItemLineL( KUIStoreCaseStatus );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreCaseStatus, status ));
CleanupStack::PopAndDestroy( item );
// Get test case execution result
item = section->GetItemLineL( KUIStoreCaseExecutionResult );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreCaseExecutionResult, num ));
result.iCaseExecutionResultType = ( TFullTestResult::TCaseExecutionResult) num;
// Mandatory, leave if not found
User::LeaveIfError( item->GetNextInt( result.iCaseExecutionResultCode ));
CleanupStack::PopAndDestroy( item );
// Get test case result
item = section->GetItemLineL( KUIStoreCaseResult );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetInt( KUIStoreCaseResult,
result.iTestResult.iResult ));
// Not mandatory
TBool first = ETrue;
result.iTestResult.iResultDes.Zero();
ret = item->GetNextString( tmp );
while( ret == KErrNone )
{
if( result.iTestResult.iResultDes.Length() + tmp.Length() + 1 > result.iTestResult.iResultDes.MaxLength() )
{
User::Leave( KErrGeneral );
}
if(!first)
result.iTestResult.iResultDes.Append(_L(" "));
result.iTestResult.iResultDes.Append( tmp );
first = EFalse;
ret = item->GetNextString( tmp );
}
/*
ret = item->GetNextString( tmp );
if( ret == KErrNone )
{
if( tmp.Length() > result.iTestResult.iResultDes.MaxLength() )
{
User::Leave( KErrGeneral );
}
result.iTestResult.iResultDes.Copy( tmp );
}
*/
CleanupStack::PopAndDestroy( item );
// Get test start time
item = section->GetItemLineL( KUIStoreCaseStartTime );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetString( KUIStoreCaseStartTime, tmp ));
result.iStartTime.Set( tmp );
CleanupStack::PopAndDestroy( item );
// Get test end time
item = section->GetItemLineL( KUIStoreCaseEndTime );
CleanupStack::PushL( item );
// Mandatory, leave if not found
User::LeaveIfError( item->GetString( KUIStoreCaseEndTime, tmp ));
result.iEndTime.Set( tmp );
CleanupStack::PopAndDestroy( item );
if( status != CUIStoreIf::EStatusRunning )
{
// Add executed test cases to list
CStartedTestCase* startedCase =
new( ELeave )CStartedTestCase( testInfo, result, status );
User::LeaveIfError( iStartedTestCases.Append( startedCase ) );
CleanupStack::Pop( testInfo );
// Fill data with test case info and send to test engine
TTestInfo *info = new (ELeave) TTestInfo;
CleanupStack::PushL(info);
info->iModuleName.Copy(testInfo->ModuleName());
info->iConfig.Copy(testInfo->TestCaseFile());
info->iTestCaseInfo.iCaseNumber = testInfo->TestCaseNum();
info->iTestCaseInfo.iTitle.Copy(testInfo->TestCaseTitle());
info->iTestCaseInfo.iTimeout = testInfo->Timeout();
info->iTestCaseInfo.iPriority = testInfo->Priority();
iUIEngine->TestEngine().AddTestCaseResultToTestReport(*info, result, KErrNone);
CleanupStack::PopAndDestroy(info);
}
else
{
// Restart testcase that was running when reset was done
CUIEngineContainer* container = NULL;
User::LeaveIfError(
iUIEngine->StartTestCase( container, *testInfo ) );
CStartedTestCase* testCase = NULL;
TRAPD( retVal,
testCase = CStartedTestCase::NewL( *testInfo, *container );
);
if( retVal != KErrNone )
{
iUIEngine->AbortStartedTestCase( container );
User::Leave( retVal );
}
retVal = iStartedTestCases.Append( testCase );
if( retVal != KErrNone )
{
iUIEngine->AbortStartedTestCase( container );
delete testCase;
User::Leave( retVal );
}
CleanupStack::PopAndDestroy( testInfo );
}
CleanupStack::PopAndDestroy( section );
section =
parser->NextSectionL( KUIStoreStartTest, KUIStoreStartTestEnd );
}
CleanupStack::PopAndDestroy( parser );
// Delete file
RFs rf;
TInt retVal = rf.Connect();
if( retVal != KErrNone )
{
User::Leave( retVal );
}
TFileName file( KUIStoreDefaultDir );
file.Append( KUIStoreDefaultRebootFile );
rf.Delete( file );
rf.Close();
return;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: FindByContainer
Description: Find test case with UIEngine Container pointer.
Parameters: CUIEngineContainer* const aContainer: in: Execution container
CStartedTestCase*& aTestCase: out: Testcase info
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::FindByContainer( CUIEngineContainer* const aContainer,
CStartedTestCase*& aTestCase )
{
TInt count = iStartedTestCases.Count();
TInt index = 0;
for( ; index < count; index++ )
{
if( ( iStartedTestCases[index]->Status() &
CUIStoreIf::EStatusRunning ) &&
( &iStartedTestCases[index]->UIEngineContainer() ==
aContainer ) )
{
aTestCase = iStartedTestCases[index];
return KErrNone;
}
}
return KErrNotFound;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: UpdateCases
Description: Refreshs iTestCases array ie. fetches test cases from
test framework
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::UpdateCases()
{
if( iUpdateNeeded )
{
TInt handle = iUIStoreIf->PopupMsg(
_L("Updating"), _L("Test cases"), 60 );
iTestCases.ResetAndDestroy();
TRAPD( ret,
ret = iUIEngine->GetTestCasesL( iTestCases );
);
iUpdateNeeded = EFalse;
// Close popup
iUIStoreIf->Close( handle );
if( iTestCases.Count() == 0 )
{
iUIStoreIf->PopupMsg( _L("No test cases found"),
_L("e.g. check TestEngine log"),
3 );
}
return ret;
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: CheckIniL
Description: Check ini file
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
void CUIStore::CheckIniL( TFileName& aIni )
{
RFs fs;
User::LeaveIfError( fs.Connect() );
RFile file;
TInt err = KErrNone;
TErrorNotification error;
error.iModule.Copy( KUIStore );
TStifUtil::CorrectFilePathL( aIni );
if ( aIni.Length() != 0 )
{
err = file.Open ( fs, aIni, EFileRead );
if ( err == KErrNone )
{
// Use the file given as command line parameter
iUIStoreIf->PopupMsg( _L("Using given ini-file"),
KNullDesC, 0 );
file.Close();
fs.Close();
return;
}
else
{
error.iText.Copy( _L("Can't open given ini-file") );
iUIStoreIf->Error( error );
aIni.Zero();
}
}
// Try to locate default ini file from every drive
TDriveList drivelist;
User::LeaveIfError( fs.DriveList(drivelist) );
// A TDriveList (the list of available drives), is an array of
// 26 bytes. Each byte with a non zero value signifies that the
// corresponding drive is available.
TInt driveNumber;
TChar driveLetter;
for( driveNumber=EDriveA; driveNumber<=EDriveZ; driveNumber++ )
{
if( !drivelist[driveNumber] )
{
// If drive-list entry is zero, drive is not available
continue;
}
User::LeaveIfError(
fs.DriveToChar( driveNumber, driveLetter ));
aIni.Zero();
aIni.Append( driveLetter );
aIni.Append( _L(":") );
aIni.Append( KDefaultIni );
// Try to open
err = file.Open ( fs, aIni, EFileRead );
if ( err == KErrNone )
{
// Use default file
file.Close();
TFileName info( _L("Using default ini-file ") );
if( info.MaxLength()-info.Length() > aIni.Length() )
{
// Show also filename if fits to descriptor
info.Append( aIni );
}
iUIStoreIf->PopupMsg( info, KNullDesC, 0 );
break;
}
}
if( err != KErrNone )
{
iUIStoreIf->PopupMsg( _L("Starting without ini-file"),
KNullDesC, 0);
aIni.Zero();
}
fs.Close();
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ParseTestSetName
Description: Parses test set name from test set filename.
Parameters: const TDesC& aSetFileName: in: Test set filename
TPtrC& aSetName: out: testset name
TFileName& aFileName: in: filenamebuffer
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::ParseTestSetName( const TDesC& aSetFileName,
TPtrC& aSetName,
TFileName& aFileName )
{
if( aSetFileName.Length() > KMaxFileName )
{
return KErrArgument;
}
aFileName.Copy( aSetFileName );
TParsePtr p( aFileName );
aSetName.Set( p.NameAndExt() ); // gives test set name without path
if( aSetName.Length() > KMaxName )
{
return KErrArgument;
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: RemotePopup
Description: Do remote message popup
Parameters: const TDesC& aReq: in: request
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::RemotePopup( CUIEngineContainer* aContainer,
const TDesC& aMsg,
CStifTFwIfProt* aResp,
TPopupPriority aPopupPriority )
{
TInt ret = KErrNone;
CUIStorePopup* popup = NULL;
TRAP( ret, popup = CUIStorePopup::NewL( this, aContainer, aResp, aPopupPriority, aMsg ); );
if( ret != KErrNone )
{
return ret;
}
ret = iPopups.Append( popup );
if( ret != KErrNone )
{
delete popup;
return ret;
}
// We'll put new popup to the top if there are no popups active or if
// currently active popup has lower priority than the new one
if( !iPopupActive || iActivePopupPriority > popup->GetPriority() )
{
SetRemotePopupFromQueue();
}
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: SetRemotePopupFromQueue
Description: Prints the highest priority popup to the UI from the popup
queue
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft @js
-------------------------------------------------------------------------------
*/
void CUIStore::SetRemotePopupFromQueue()
{
CUIStorePopup* popup = NULL;
if(iPopups.Count() > 0 )
{
TInt highest = 0;
// Let's get the highest priority popup and print it to the UI
for( TInt x=0; x<iPopups.Count(); x++)
{
if( iPopups[x]->GetPriority() < iPopups[highest]->GetPriority() )
{
highest = x;
}
}
popup = iPopups[highest];
if( popup == NULL )
{
// Some weird error
iPopupActive = EFalse;
return;
}
// Change the active popup priority
iActivePopupPriority = popup->GetPriority();
// Create proper popup
if( popup->GetPriority() == EPopupPriorityHighest )
{
popup->Start( popup->GetMessage().Right( popup->GetMessage().Length() - KRcpHeaderLen ),
_L("Press any key to send 'remote run started' message"));
}
else if( popup->GetPriority() == EPopupPriorityNormal )
{
popup->Start( popup->GetMessage().Right( popup->GetMessage().Length() - KRcpHeaderLen ),
_L("Press any key to set event") );
}
else if( popup->GetPriority() == EPopupPriorityLow )
{
popup->Start( popup->GetMessage().Right( popup->GetMessage().Length() - KRcpHeaderLen ),
_L("Press 1-9 to return negative error value, a to switch to another remote run result popup, or any other key to return 0") );
}
iPopupActive = ETrue;
}
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ShuffleRemoteRunResultPopups
Description: Shuffle remote run result popups
Parameters: CUIStorePopup* aPopup (currently active popup)
Return Values: None
Errors/Exceptions: None
Status: Draft @js
-------------------------------------------------------------------------------
*/
void CUIStore::ShuffleRemoteRunResultPopups( CUIStorePopup* aPopup )
{
TInt nextPopupId = -1;
for( TInt x=0; x<iPopups.Count(); x++)
{
// Lets find the next remote run result priority popup
if( iPopups[x]->GetPriority() == EPopupPriorityLow && iPopups[x] != aPopup )
{
nextPopupId = x;
break;
}
}
if( nextPopupId == -1 )
{
// We'll print error message popup, because there weren't any other remote run
// result popups active
iUIStoreIf->PopupMsg(
_L("Error! There weren't any other remote run result popups active."),
_L(""),
5 );
User::After( 5000000 );
iPopups.Append( aPopup );
SetRemotePopupFromQueue();
return;
}
// We'll add the popup to the end of the array
TInt ret = iPopups.Append( aPopup );
if( ret != KErrNone )
{
delete aPopup;
return;
}
// Print the next popup from queue
SetRemotePopupFromQueue();
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: RemotePopup
Description: Do remote message popup
Parameters: const TDesC& aReq: in: request
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CUIStore::RemotePopupComplete( CUIStorePopup* aPopup,
TInt aError,
CUIEngineContainer* aContainer,
CStifTFwIfProt* aResp,
TKeyCode aKeyCode )
{
TInt ret = KErrNone;
TInt index = iPopups.Find( aPopup );
if( index < 0 )
{
User::Panic( KUIStore, KErrGeneral );
}
iPopups.Remove( index );
iPopupActive = EFalse;
iActivePopupPriority = EPopupPriorityLow;
if( aError != KErrNone )
{
ret = aError;
}
else
{
TChar c( aKeyCode );
if( c.IsDigit() )
{
// Solve return value
ret = -( aKeyCode - '0' );
}
else
{
ret = KErrNone;
}
}
// If aResp is given, send it
if( aResp )
{
switch( aResp->iCmdType )
{
case CStifTFwIfProt::ECmdRun:
{
TChar response( aKeyCode );
RDebug::Print(_L("CUIStore::RemotePopupComplete: user pressed key %c"), (char)response);
if( aPopup->GetPriority() == EPopupPriorityHighest )
{
// User has given response to remote run started- popup
aResp->Append( CStifTFwIfProt::RunStatus,
CStifTFwIfProt::ERunStarted );
}
else if( aPopup->GetPriority() == EPopupPriorityLow && response=='a' )
{
// User wants to change current remote run result popup to other
// remote run result popup.
ShuffleRemoteRunResultPopups( aPopup );
return KErrNone;
}
else
{
// The test case result was given
aResp->Append( CStifTFwIfProt::RunStatus,
CStifTFwIfProt::ERunReady );
if( ret != KErrNone )
{
aResp->Append( CStifTFwIfProt::RunStatusParams,
CStifTFwIfProt::ERunResult, ret );
}
}
break;
}
case CStifTFwIfProt::ECmdSendReceive:
{
aResp->Append( CStifTFwIfProt::RunStatus,
CStifTFwIfProt::ERunReady );
if( ret != KErrNone )
{
aResp->Append( CStifTFwIfProt::RunStatusParams,
CStifTFwIfProt::ERunResult, ret );
}
break;
}
case CStifTFwIfProt::ECmdPause:
case CStifTFwIfProt::ECmdResume:
case CStifTFwIfProt::ECmdCancel:
case CStifTFwIfProt::ECmdRequest:
case CStifTFwIfProt::ECmdRelease:
default:
if( ret != KErrNone )
{
aResp->Append( CStifTFwIfProt::RespParam,
CStifTFwIfProt::ERespResult,
ret );
}
break;
}
ret = aContainer->RemoteReceive( aResp->Message() );
}
delete aPopup;
SetRemotePopupFromQueue();
return ret;
}
/*
-------------------------------------------------------------------------------
Class: CUIStore
Method: ReadFiltersL
Description: Reads filters from test framework initialization file.
Parameters: RPointerArray<TDesC>& aFilters: array to be filled
Return Values: None
Errors/Exceptions:
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C void CUIStore::ReadFiltersL(RPointerArray<TDesC>& aFilters)
{
// Clean array
aFilters.ResetAndDestroy();
// Locate file
_LIT(KFilterSectionStart, "[Filters]");
_LIT(KFilterSectionEnd, "[End_Filters]");
_LIT(KFilterDefinition, "filter=");
// Parse initialization file
TInt err = KErrNone;
CStifParser* parser;
RDebug::Print(_L("STIF: Try to read filters from [%S]"), &iTestFrameworkIni);
parser = CStifParser::NewL(KNullDesC, iTestFrameworkIni);
CleanupStack::PushL(parser);
// Parser created (file exists), create section parser
CStifSectionParser* section;
section = parser->SectionL(KFilterSectionStart, KFilterSectionEnd);
if(section)
{
CleanupStack::PushL(section);
// Get item lines
CStifItemParser* item = section->GetItemLineL(KFilterDefinition, ENoTag);
TPtrC ptr;
while(item)
{
CleanupStack::PushL(item);
// Read filter value
err = item->GetString(KNullDesC, ptr);
if(err == KErrNone)
{
HBufC* filter = ptr.AllocLC();
User::LeaveIfError(aFilters.Append(filter));
CleanupStack::Pop();
}
CleanupStack::PopAndDestroy(item);
item = NULL;
item = section->GetNextItemLineL(KFilterDefinition, ENoTag);
}
CleanupStack::PopAndDestroy(section);
}
// Clean
CleanupStack::PopAndDestroy(parser);
// If there are some filters added, first filter has to be "No filter"
if(aFilters.Count() > 0)
{
RDebug::Print(_L("STIF: Filters loaded"));
_LIT(KNoFilter, "No filter");
HBufC* name = KNoFilter().AllocLC();
User::LeaveIfError(aFilters.Insert(name, 0));
CleanupStack::Pop(name);
}
}
/*
-------------------------------------------------------------------------------
DESCRIPTION
This module contains implementation of CUIStoreIf class member functions.
-------------------------------------------------------------------------------
*/
// ================= MEMBER FUNCTIONS =========================================
/*
-------------------------------------------------------------------------------
Class: CUIStoreIf
Method: ConstructL
Description: Second phase constructor.
Parameters: None
Return Values: None
Errors/Exceptions: Leaves if..
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C void CUIStoreIf::ConstructL( )
{
iUIStore = CUIStore::NewL( this );
}
/*
-------------------------------------------------------------------------------
Class: CUIStoreIf
Method: CUIStoreIf
Description: Constructor.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C CUIStoreIf::CUIStoreIf( )
{
}
/*
-------------------------------------------------------------------------------
Class: CUIStoreIf
Method: ~CUIStoreIf
Description: Destructor
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C CUIStoreIf::~CUIStoreIf()
{
delete iUIStore;
iUIStore = NULL;
}
/*
-------------------------------------------------------------------------------
Class: CUIStoreIf
Method: UIStore
Description: Returns reference to CUIStore object, which handles test
cases and test modules.
Parameters: None
Return Values: CUIStore reference
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
EXPORT_C CUIStore& CUIStoreIf::UIStore()
{
__ASSERT_ALWAYS( iUIStore, User::Panic( KUIStoreIf, KErrNotFound ) );
return *iUIStore;
}
/*
-------------------------------------------------------------------------------
DESCRIPTION
This module contains implementation of CTestSetInfo class member functions.
-------------------------------------------------------------------------------
*/
// ================= MEMBER FUNCTIONS =========================================
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: NewL
Description: Construct the CTestSetInfo class
Parameters: None
Return Values: CTestSetInfo* New object
Errors/Exceptions: Leaves if memory allocation fails or
ConstructL leaves.
Status: Draft
-------------------------------------------------------------------------------
*/
CTestSetInfo* CTestSetInfo::NewL( const TDesC& aName )
{
CTestSetInfo* self = new ( ELeave ) CTestSetInfo();
CleanupStack::PushL( self );
self->ConstructL( aName );
CleanupStack::Pop( self );
return self;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: ConstructL
Description: Second phase constructor.
Parameters: None
Return Values: None
Errors/Exceptions: Leaves if..
Status: Draft
-------------------------------------------------------------------------------
*/
void CTestSetInfo::ConstructL( const TDesC& aName )
{
iName = aName.AllocL();
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: CTestSetInfo
Description: Constructor.
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
CTestSetInfo::CTestSetInfo()
{
iLastStartedCaseIndex = 0;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: ~CTestSetInfo
Description: Destructor
Parameters: None
Return Values: None
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
CTestSetInfo::~CTestSetInfo()
{
iTestCases.ResetAndDestroy();
iTestCaseRefs.Reset();
iTestCases.Close();
iTestCaseRefs.Close();
delete iName;
iName = NULL;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: AddTestCase
Description: Add test case to test set.
Parameters: const CTestInfo& aTestInfo: in: test info
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CTestSetInfo::AddTestCase( const CTestInfo& aTestInfo )
{
CTestInfo* testInfo = NULL;
TRAPD( err,
testInfo = CTestInfo::NewL();
testInfo->CopyL( aTestInfo );
);
if( err != KErrNone )
{
return err;
}
if( iTestCaseRefs.Append( *testInfo ) != KErrNone )
{
delete testInfo;
return KErrNoMemory;
}
if( iTestCases.Append( testInfo ) != KErrNone )
{
iTestCaseRefs.Remove( iTestCaseRefs.Count()-1 );
delete testInfo;
return KErrNoMemory;
}
return KErrNone;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: InsertTestCase
Description: Insert test case to test set.
Parameters: const CTestInfo& aTestInfo: in: test info
TInt aPos: in: position to add
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CTestSetInfo::InsertTestCase( const CTestInfo& aTestInfo, TInt aPos )
{
if( ( aPos < 0 ) ||
( aPos >= iTestCases.Count() ) )
{
return KErrArgument;
}
CTestInfo* testInfo = NULL;
TRAPD( err,
testInfo = CTestInfo::NewL();
testInfo->CopyL( aTestInfo );
);
if( err != KErrNone )
{
return err;
}
if( iTestCaseRefs.Insert( *testInfo, aPos ) != KErrNone )
{
delete testInfo;
return KErrNoMemory;
}
if( iTestCases.Insert( testInfo, aPos ) != KErrNone )
{
iTestCaseRefs.Remove( aPos );
delete testInfo;
return KErrNoMemory;
}
return err;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: RemoveTestCase
Description: Remove test case from test set.
Parameters: const CTestInfo& aTestInfo: in: test info
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
TInt CTestSetInfo::RemoveTestCase( const CTestInfo& aTestInfo )
{
TInt count = iTestCases.Count();
for( TInt i=0; i<count; i++ )
{
if( aTestInfo == *iTestCases[i] )
{
CTestInfo* testInfo = iTestCases[i];
iTestCases.Remove( i );
iTestCaseRefs.Remove( i );
delete testInfo;
return KErrNone;
}
}
return KErrNotFound;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: CopyL
Description: Remove test case from test set.
Parameters: const CTestInfo& aTestInfo: in: test info
Return Values: Symbian OS error code
Errors/Exceptions: None
Status: Draft
-------------------------------------------------------------------------------
*/
void CTestSetInfo::CopyL( const CTestSetInfo& aTestSetInfo )
{
iTestCaseRefs.Reset();
iTestCases.ResetAndDestroy();
TInt count = aTestSetInfo.TestCases().Count();
for( TInt i=0; i<count; i++ )
{
User::LeaveIfError( AddTestCase( aTestSetInfo.TestCases()[i] ) );
}
delete iName;
iName = 0;
iName = aTestSetInfo.Name().AllocL();
iLastStartedCaseIndex = aTestSetInfo.iLastStartedCaseIndex;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: SetLastStartedCaseIndex
Description: Sets the info which test case has been started lately.
Parameters: TInt aCaseStarted: index of started test case
Return Values: None
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
void CTestSetInfo::SetLastStartedCaseIndex(TUint aLastStartedCaseIndex)
{
iLastStartedCaseIndex = aLastStartedCaseIndex;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: GetLastStartedCaseIndex
Description: Gets the info which test case has been started lately.
Parameters: None
Return Values: TInt: index of lately started test case
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
TUint CTestSetInfo::GetLastStartedCaseIndex(void)
{
return iLastStartedCaseIndex;
}
/*
-------------------------------------------------------------------------------
Class: CTestSetInfo
Method: RenameTestSet
Description: rename test set
Parameters: aTestSetName : new TestSetName
Return Values: TInt: KErrNone if success.
Errors/Exceptions: None
Status: Approved
-------------------------------------------------------------------------------
*/
void CTestSetInfo::RenameTestSet(const TDesC& aTestSetName)
{
delete iName;
iName=NULL;
iName=aTestSetName.AllocL();
}
// ================= OTHER EXPORTED FUNCTIONS =================================
// End of File