--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/ATSInterface/src/ATSInterface.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,1111 @@
+/*
+* 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: CATSInterface: This object executes test cases from
+* STIF Test Framework.
+*
+*/
+
+// INCLUDE FILES
+#include <e32base.h>
+#include <e32cons.h>
+#include <e32svr.h>
+#include "ATSInterface.h"
+#include "ATSInterfaceRunner.h"
+
+#include "StifTestInterface.h"
+
+
+// EXTERNAL DATA STRUCTURES
+// None
+
+// EXTERNAL FUNCTION PROTOTYPES
+// None
+
+// CONSTANTS
+// None
+
+// MACROS
+// None
+
+// LOCAL CONSTANTS AND MACROS
+// None
+
+// MODULE DATA STRUCTURES
+// None
+
+// LOCAL FUNCTION PROTOTYPES
+// None
+
+// FORWARD DECLARATIONS
+// None
+
+// ==================== LOCAL FUNCTIONS =======================================
+// None
+
+// ================= MEMBER FUNCTIONS =========================================
+
+
+// ================= MEMBER FUNCTIONS =========================================
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: CATSInterface
+
+ Description: Default constructor
+
+ C++ default constructor can NOT contain any code, that
+ might leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CATSInterface::CATSInterface()
+ {
+ // Initialize buffers to zero
+ iEngineIniFile.Zero();
+ iModuleIniFile.Zero();
+ iConfigFile.Zero();
+ iTestModule.Zero();
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: ConstructL
+
+ Description: Symbian OS second phase constructor
+
+ Symbian OS default constructor can leave.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving functions leaves
+ Leaves each time the LogErrorAndLeaveL is called
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::ConstructL()
+ {
+ RDebug::Print(_L("Creating module list object"));
+ TRAPD(err, iModuleList = CTestModuleList::NewL(NULL));
+ if(err != KErrNone)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ConstructL"), _L("CTestModuleList::NewL"), err);
+ return;
+ }
+ if(!iModuleList)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ConstructL"), _L("CTestModuleList::NewL - iModuleList is NULL"), KErrGeneral);
+ return;
+ }
+
+ // Read command line
+ ParseCommandLineL();
+
+ // Add to module list info about module taken from command line
+ RDebug::Print(_L("Adding command line module to list"));
+ TName moduleName;
+ moduleName.Copy(iTestModule);
+ moduleName.LowerCase();
+ err = iModuleList->AddTestModule(moduleName);
+ if(err != KErrNone && err != KErrAlreadyExists)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ConstructL"), _L("CTestModuleList::AddTestModule - Could not add module to list of modules"), err);
+ return;
+ }
+
+ //Get added module
+ CTestModuleInfo* moduleInfo = iModuleList->GetModule(moduleName);
+ if(!moduleInfo)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ConstructL"), _L("CTestModuleList::GetModule - Could not add get module info from list"), KErrGeneral);
+ return;
+ }
+
+ //Add ini file if given
+ if(iModuleIniFile.Length() > 0)
+ {
+ TFileName filename;
+ filename.Copy(iModuleIniFile);
+ filename.LowerCase();
+ moduleInfo->SetIniFile(filename);
+ }
+
+ //Add config file if given
+ if(iConfigFile.Length() > 0)
+ {
+ TFileName filename;
+ filename.Copy(iConfigFile);
+ filename.LowerCase();
+ moduleInfo->AddCfgFile(filename);
+ }
+
+ //Now check all config files if there are included modules
+ _LIT(KIncludeModuleStart, "[New_Include_Module]");
+ _LIT(KIncludeModuleEnd, "[End_Include_Module]");
+
+ RDebug::Print(_L("Start parsing included modules"));
+ CTestCaseFileInfo* finfo = iModuleList->GetUncheckedCfgFile();
+ while(finfo)
+ {
+ TFileName fname;
+ finfo->GetCfgFileName(fname);
+
+ RDebug::Print(_L("Checking file: '%S'"), &fname);
+ finfo->SetChecked();
+
+ CStifParser* parser = NULL;
+
+ TRAP(err, parser = CStifParser::NewL(_L(""), fname));
+ if(err != KErrNone)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ConstructL"), _L("CStifParser::NewL - Could not create parser"), err);
+ return;
+ }
+ CleanupStack::PushL(parser);
+
+ ParseTestModulesL(parser, iModuleList, KIncludeModuleStart, KIncludeModuleEnd);
+
+ CleanupStack::PopAndDestroy(parser);
+ finfo = iModuleList->GetUncheckedCfgFile();
+ }
+ RDebug::Print(_L("End parsing included modules"));
+
+ // Create Test Engine
+ RDebug::Print(_L("Creating test engine"));
+ TInt ret = iTestEngineServ.Connect();
+ if ( ret != KErrNone )
+ {
+ // Log error
+ LogErrorAndLeaveL( _L("CATSInterface::ConstructL"), _L("iTestEngineServ.Connect"), ret );
+ return;
+ }
+
+ ret = iTestEngine.Open( iTestEngineServ, iEngineIniFile );
+ if ( ret != KErrNone )
+ {
+ // Log error
+ LogErrorAndLeaveL( _L("CATSInterface::ConstructL"), _L("iTestEngine.Open"), ret );
+ return;
+ }
+
+/*
+ // Add test module
+ ret = iTestEngine.AddTestModule( iTestModule, iModuleIniFile );
+ if ( ret != KErrNone && ret != KErrAlreadyExists )
+ {
+ // Log error
+ LogErrorAndLeaveL( _L("CATSInterface::ConstructL"), _L("iTestEngine.AddTestModule"), ret );
+ return;
+ }
+*/
+ // Add all test modules and config files
+ RDebug::Print(_L("Start creating test modules"));
+ moduleInfo = NULL;
+ TInt i;
+ TInt modCnt = iModuleList->Count();
+
+ for(i = 0; i < modCnt; i++)
+ {
+ RDebug::Print(_L("Processing module"));
+ // Get module
+ moduleInfo = iModuleList->GetModule(i);
+ if(!moduleInfo)
+ {
+ RDebug::Print(_L("Could not get module info at index %d"), i);
+ continue;
+ }
+
+ // Get module name
+ TName moduleName;
+ moduleInfo->GetModuleName(moduleName);
+ RDebug::Print(_L("module name: '%S'"), &moduleName);
+
+ // Get ini file, if exists
+ TFileName ini;
+ moduleInfo->GetIniFileName(ini);
+ if(ini.Length() == 0)
+ {
+ RDebug::Print(_L("ini file not found"));
+ }
+ else
+ {
+ RDebug::Print(_L("ini file: '%S'"), &ini);
+ }
+
+ // Create test module
+ RDebug::Print(_L("Adding module to test engine"));
+ ret = iTestEngine.AddTestModule(moduleName, ini);
+ if(ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ConstructL"), _L("iTestEngine.AddTestModule"), ret);
+ return;
+ }
+
+ //Add test case files
+ TInt cfgCnt = moduleInfo->CountCfgFiles();
+ TInt j;
+ TFileName cfgFile;
+ for(j = 0; j < cfgCnt; j++)
+ {
+ moduleInfo->GetCfgFileName(j, cfgFile);
+ if(cfgFile.Length() > 0)
+ {
+ RDebug::Print(_L("config file: '%S'"), &cfgFile);
+
+ ret = iTestEngine.AddConfigFile(moduleName, cfgFile);
+ if(ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ // Log error
+ LogErrorAndLeaveL(_L("CATSInterface::ConstructL"), _L("RTestEngine::AddConfigFile"), ret);
+ return;
+ }
+ }
+ else
+ {
+ RDebug::Print(_L("Got empty cfg file"));
+ }
+ }
+ if(cfgCnt == 0)
+ {
+ RDebug::Print(_L("cfg file not found"));
+ }
+
+ RDebug::Print(_L("Module '%S' processed correctly"), &moduleName);
+ }
+
+ RDebug::Print(_L("End creating test modules"));
+
+ // Create console screen
+ iConsole = Console::NewL(
+ iTestModule, TSize( KConsFullScreen, KConsFullScreen ) );
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: NewL
+
+ Description: Two-phased constructor.
+
+ Parameters: None
+
+ Return Values: CATSInterface* : pointer to created CATSInterface object
+
+ Errors/Exceptions: Leaves if memory allocation for CATSInterface fails
+ Leaves if ConstructL leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CATSInterface* CATSInterface::NewL()
+ {
+ // Create CATSInterface and return it
+ CATSInterface* self = new ( ELeave ) CATSInterface();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: ~CATSInterface
+
+ Description: Destructor
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+CATSInterface::~CATSInterface()
+ {
+ // Close Test Engine
+ iTestEngine.Close();
+ iTestEngineServ.Close();
+
+ delete iModuleList;
+ delete iConsole;
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: ParseTestModulesL
+
+ Description: Parse and search for module info and fill list of modules.
+
+ Parameters: CStifParser* aParser: in: CStifParser object
+ CTestModuleList* aModuleList: in: list of modules
+ TPtrC& aSectionStart: in: descriptor with start of section string
+ TPTrC& aSectionEnd: in: descriptor with end of section string
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::ParseTestModulesL(CStifParser* aParser, CTestModuleList* aModuleList, const TDesC& aSectionStart, const TDesC& aSectionEnd)
+ {
+ //First let's find all modules given in Stif's ini file and store that info in CTestModuleList object
+ CStifSectionParser* sectionParser = NULL;
+ CStifItemParser* item = NULL;
+
+ sectionParser = aParser->SectionL(aSectionStart, aSectionEnd);
+
+ while(sectionParser)
+ {
+ RDebug::Print(_L("Found '%S' and '%S' sections"), &aSectionStart, &aSectionEnd);
+ CleanupStack::PushL(sectionParser);
+ RDebug::Print(_L("Starting to read module information"));
+
+ // Get name of module
+ _LIT(KModuleName, "ModuleName=");
+ item = sectionParser->GetItemLineL(KModuleName);
+ CleanupStack::PushL(item);
+ if(!item)
+ {
+ CleanupStack::PopAndDestroy(item);
+ LogErrorAndLeaveL(_L("CATSInterface::ParseTestModulesL"), _L("CStifItemParser::GetItemLineL - line not found from module section"), KErrNotFound);
+ return;
+ }
+ else
+ {
+ RDebug::Print(_L("'%S' found"), &KModuleName);
+ }
+
+ TPtrC name;
+ TName moduleName;
+ TInt ret(KErrNone);
+ ret = item->GetString(KModuleName, name);
+ if(ret != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(item);
+ LogErrorAndLeaveL(_L("CATSInterface::ParseTestModulesL"), _L("CStifItemParser::GetString - Module name parsing left with error"), ret);
+ return;
+ }
+ else
+ {
+ RDebug::Print(_L("Module '%S' found from ini-file"), &name);
+ moduleName.Copy(name);
+ moduleName.LowerCase();
+ ret = aModuleList->AddTestModule(moduleName);
+ if(ret != KErrNone && ret != KErrAlreadyExists)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ParseTestModulesL"), _L("CTestModuleList::AddTestModule - Could not add module to list of modules"), ret);
+ return;
+ }
+ }
+ CleanupStack::PopAndDestroy(item);
+
+ //Get pointer to added module
+ CTestModuleInfo* moduleInfo = aModuleList->GetModule(moduleName);
+ if(!moduleInfo)
+ {
+ LogErrorAndLeaveL(_L("CATSInterface::ParseTestModulesL"), _L("CTestModuleList::GetModule - Could not add get module info from list"), KErrNotFound);
+ return;
+ }
+
+ // Get ini file, if it exists
+ RDebug::Print(_L("Start parsing ini file"));
+ _LIT(KIniFile, "IniFile=");
+ item = sectionParser->GetItemLineL(KIniFile);
+ if(item)
+ {
+ RDebug::Print(_L("'%S' found"), &KIniFile);
+ CleanupStack::PushL(item);
+ TPtrC iniFile;
+ ret = item->GetString(KIniFile, iniFile);
+ if(ret == KErrNone)
+ {
+ RDebug::Print(_L("Initialization file '%S' found, file can be empty"), &iniFile);
+ TFileName filename;
+ filename.Copy(iniFile);
+ filename.LowerCase();
+ TStifUtil::CorrectFilePathL( filename );
+ moduleInfo->SetIniFile(filename);
+ }
+ else
+ {
+ RDebug::Print(_L("Initialization file not found"));
+ }
+ CleanupStack::PopAndDestroy(item);
+ }
+ else
+ {
+ RDebug::Print(_L("'%S' not found"), &KIniFile);
+ }
+
+ // Get config (testcase) file
+ RDebug::Print(_L("Start parsing cfg files"));
+ TPtrC cfgTag;
+ for(TInt i = 0; i < 2; i++)
+ {
+ //Set tag for config files
+ if(i == 0)
+ {
+ cfgTag.Set(_L("ConfigFile="));
+ }
+ else
+ {
+ cfgTag.Set(_L("TestCaseFile="));
+ }
+ //Read data
+ item = sectionParser->GetItemLineL(cfgTag);
+ while(item)
+ {
+ CleanupStack::PushL(item);
+ RDebug::Print(_L("Item '%S' found"), &cfgTag);
+ TPtrC cfgFile;
+ ret = item->GetString(cfgTag, cfgFile);
+ if(ret == KErrNone)
+ {
+ TFileName ifile;
+ ifile.Copy(cfgFile);
+ ifile.LowerCase();
+ TStifUtil::CorrectFilePathL( ifile );
+ RDebug::Print(_L("Configuration file '%S' found"), &ifile);
+ moduleInfo->AddCfgFile(ifile);
+ }
+ else
+ {
+ RDebug::Print(_L("Configuration file not found"));
+ }
+ CleanupStack::PopAndDestroy(item);
+ item = sectionParser->GetNextItemLineL(cfgTag);
+ }
+ }
+
+ RDebug::Print(_L("Module '%S' information read correctly"), &moduleName);
+
+ // Get next section
+ CleanupStack::PopAndDestroy(sectionParser);
+ sectionParser = aParser->NextSectionL(aSectionStart, aSectionEnd);
+ }
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: ParseCommandLineL
+
+ Description: Parse command line parameters
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if module name not found from command line
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::ParseCommandLineL()
+ {
+ // Command line params
+ _LIT( KTestModule, "-testmodule" );
+ _LIT( KConfigFile, "-config" );
+ _LIT( KEngineIniFile, "-engineini" );
+ _LIT( KModuleIniFile, "-moduleini" );
+
+ const TInt length = User().CommandLineLength();
+
+ HBufC* cmdLine = HBufC::NewLC( length );
+ TPtr ptr = cmdLine->Des();
+
+ User().CommandLine( ptr );
+
+ TBool moduleFound( EFalse );
+ TLex lex( ptr );
+ // Parse the command line
+ while ( !lex.Eos() )
+ {
+ TPtrC tmpPtr = lex.NextToken();
+ // Check the test module name
+ if ( tmpPtr == KTestModule )
+ {
+ TPtrC module = lex.NextToken();
+ if ( module.Ptr() )
+ {
+ iTestModule.Copy( module );
+ moduleFound = ETrue;
+ }
+ }
+ // Check the module's config file
+ else if ( tmpPtr == KConfigFile )
+ {
+ TPtrC config = lex.NextToken();
+ if ( config.Ptr() )
+ {
+ iConfigFile.Copy( config );
+ TStifUtil::CorrectFilePathL( iConfigFile );
+ }
+ }
+ // Check the engine's ini file
+ else if ( tmpPtr == KEngineIniFile )
+ {
+ TPtrC iniFile = lex.NextToken();
+ if ( iniFile.Ptr() )
+ {
+ iEngineIniFile.Copy( iniFile );
+ TStifUtil::CorrectFilePathL( iEngineIniFile );
+ }
+ }
+ // Check the module's ini file
+ else if ( tmpPtr == KModuleIniFile )
+ {
+ TPtrC iniFile = lex.NextToken();
+ if ( iniFile.Ptr() )
+ {
+ iModuleIniFile.Copy( iniFile );
+ TStifUtil::CorrectFilePathL( iModuleIniFile );
+ }
+ }
+ else
+ {
+ // Skip unknown commands
+ }
+ } // while
+
+ // Destroy command line buffer
+ CleanupStack::PopAndDestroy( cmdLine );
+
+ // Module name has to exists
+ if ( !moduleFound )
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: RunTestsL
+
+ Description: Starts testing
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if RunAllTestCasesL leaves
+ Leaves if RemoveTestModule returns error
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::RunTestsL()
+ {
+ // Run all test cases
+ RunAllTestCasesL();
+
+ /*
+ // Remove test module
+ User::LeaveIfError( iTestEngine.RemoveTestModule( iTestModule ) );
+ */
+ RDebug::Print(_L("Start removing test modules"));
+ CTestModuleInfo* moduleInfo = NULL;
+ TInt i;
+ TInt modCnt = iModuleList->Count();
+
+ for(i = 0; i < modCnt; i++)
+ {
+ RDebug::Print(_L("Processing module"));
+ // Get module
+ moduleInfo = iModuleList->GetModule(i);
+ if(!moduleInfo)
+ {
+ RDebug::Print(_L("Could not get module info at index %d"), i);
+ continue;
+ }
+
+ // Get module name
+ TName moduleName;
+ moduleInfo->GetModuleName(moduleName);
+ RDebug::Print(_L("module name: '%S'"), &moduleName);
+
+ // Remove test module
+ User::LeaveIfError(iTestEngine.RemoveTestModule(moduleName));
+ RDebug::Print(_L("Module '%S' removed"), &moduleName);
+ }
+
+ RDebug::Print(_L("End removing test modules"));
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: RunAllTestCasesL
+
+ Description: Run all test cases from test module.
+
+ Parameters: None
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::RunAllTestCasesL()
+ {
+ TInt ret( KErrNone );
+
+ /*
+ // Add given config file to test module
+ if ( iConfigFile.Length() > 0 )
+ {
+ ret = iTestEngine.AddConfigFile( iTestModule, iConfigFile );
+ if ( ret != KErrNone && ret != KErrAlreadyExists )
+ {
+ // Log error
+ LogErrorAndLeaveL( _L("CATSInterface::RunAllTestCasesL"), _L("iTestEngine.AddConfigFile"), ret );
+ return;
+ }
+ }
+ */
+
+ // Enumerate test cases
+ TCaseCount caseCount;
+ TRequestStatus status;
+ iTestEngine.EnumerateTestCases( caseCount, status );
+ User::WaitForRequest( status );
+
+ // Check that enumerate succeeded
+ if ( status != KErrNone )
+ {
+ // Log error
+ LogErrorAndLeaveL( _L("CATSInterface::RunAllTestCasesL"), _L("iTestEngine.EnumerateTestCases"), status.Int() );
+ return;
+ }
+
+ // Get test cases to buffer
+ CFixedFlatArray<TTestInfo>* testCases =
+ CFixedFlatArray<TTestInfo>::NewL( caseCount() );
+ CleanupStack::PushL( testCases );
+
+ ret = iTestEngine.GetTestCases( *testCases );
+ if ( ret != KErrNone )
+ {
+ // Log error
+ LogErrorAndLeaveL( _L("CATSInterface::RunAllTestCasesL"), _L("iTestEngine.GetTestCases"), status.Int() );
+ return;
+ }
+
+ //variables used to get version of STIF
+ TInt majorV;
+ TInt minorV;
+ TInt buildV;
+ TBuf<30> relDate;
+ TStifUtil::STIFVersion(majorV, minorV, buildV, relDate);
+
+ TBuf<50> version;
+ version.Format(_L("STIF v%d.%d.%d - "), majorV, minorV, buildV);
+ version.Append(relDate);
+ version.Append(_L("\n"));
+
+ iConsole->Printf(version); //printing STIF version information (version and release date)
+ iConsole->Printf( _L("Test case count: [%d]\n\n"), testCases->Count() );
+
+ // Loop through all test cases in buffer and run them
+ const TInt count = testCases->Count();
+ for ( TInt i = 0; i < count; i++ )
+ {
+#ifdef _DEBUG
+ RDebug::Print( ( *testCases)[i].iTestCaseInfo.iTitle );
+#endif
+ iConsole->Printf( _L("Now running test case: [%d] [%S] "), i+1,
+ &( *testCases )[i].iTestCaseInfo.iTitle );
+
+ // Run test case
+ RunTestCaseL( ( *testCases )[i] );
+ }
+
+ // End test set
+ CleanupStack::PopAndDestroy( testCases );
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: RunTestCaseL
+
+ Description: Run test case
+
+ Parameters: TTestInfo& aTestInfo: in: TTestInfo: Test info
+
+ Return Values: None
+
+ Errors/Exceptions: Leaves if some of called leaving methods leaves
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::RunTestCaseL( TTestInfo& aTestInfo )
+ {
+ TInt testResult( KErrNone );
+ CATSInterfaceRunner* runner;
+
+ // Trap to catch errors from test case executing
+ TRAPD( trapError,
+ runner = CATSInterfaceRunner::NewL( this, aTestInfo );
+ CleanupStack::PushL( runner );
+
+ testResult = RunATestCaseL( runner );
+
+ CleanupStack::PopAndDestroy( runner );
+ );
+
+ if ( trapError != KErrNone )
+ {
+ testResult = trapError;
+ }
+
+ if ( testResult != KErrNone ) // Test case is FAILED
+ {
+ // Test case failed, print out the error
+ iConsole->Printf( _L("\nTest case FAILED! err=[%d]\n"), testResult );
+ }
+
+ else // Test case is PASSED
+ {
+ iConsole->Printf( _L("\nTest case PASSED!\n") );
+ testResult = KErrNone;
+ }
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: RunATestCaseL
+
+ Description: Run a test case
+
+ Parameters: CATSInterfaceRunner* aTestCase: in: Pointer to test case runner
+
+ Return Values: TInt KErrNone: Test case passed
+ other error code: Test case failed or cannot be executed
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+TInt CATSInterface::RunATestCaseL( CATSInterfaceRunner* aTestCase )
+ {
+ iTestCompletedError = KErrNone;
+
+ // Create timer
+ CActiveTimer* timer = CActiveTimer::NewL( iConsole );
+ CleanupStack::PushL( timer );
+
+ // Start test case and timer
+ aTestCase->StartTestL();
+ timer->StartL();
+
+ // Wait for test case completed
+ CActiveScheduler::Start();
+
+ timer->Cancel();
+ CleanupStack::PopAndDestroy( timer );
+
+ // test completion error is set in TestCompleted method
+ return iTestCompletedError;
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: TestEngineServer
+
+ Description: Return handle to Test Engine Server.
+
+ Parameters: None
+
+ Return Values: RTestEngineServer&: Reference to RTestEngineServer handle
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+RTestEngineServer& CATSInterface::TestEngineServer()
+ {
+ return iTestEngineServ;
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: TestEngine
+
+ Description: Return handle to Test Engine.
+
+ Parameters: None
+
+ Return Values: RTestEngine&: reference to RTestEngine handle
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+RTestEngine& CATSInterface::TestEngine()
+ {
+ return iTestEngine;
+
+ }
+
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: TestCompleted
+
+ Description: Test case completed
+
+ This method is called when test case is completed or error occurred
+ during the test.
+
+ Parameters: TInt aError: in: Symbian OS error: Test result
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::TestCompleted( TInt aError )
+ {
+ // Store completion error
+ iTestCompletedError = aError;
+
+ // Stop the scheduler
+ CActiveScheduler::Stop();
+
+ }
+
+/*
+-------------------------------------------------------------------------------
+
+ Class: CATSInterface
+
+ Method: LogErrorAndLeaveL
+
+ Description: Write error Logger and leave.
+
+ This function is called if some function returns error and the error cannot
+ be logged another way Logger, e.g. RTestEngineServer and
+ RTestEngine methods.
+
+ Parameters: const TDesC& aFunction: in: any string: Function where the error
+ occurred
+ const TDesC& aDescription: in: any string: Description for error
+ const TInt aError: in: Symbian OS error: Test result
+
+ Return Values: None
+
+ Errors/Exceptions: None
+
+ Status: Proposal
+
+-------------------------------------------------------------------------------
+*/
+void CATSInterface::LogErrorAndLeaveL( const TDesC& aFunction,
+ const TDesC& aDescription,
+ const TInt aError )
+ {
+
+ RDebug::Print( _L("%S: %S [%d]"), &aFunction, &aDescription, aError );
+ User::Leave( aError );
+
+ }
+
+// ================= OTHER EXPORTED FUNCTIONS =================================
+
+/*
+-------------------------------------------------------------------------------
+
+ Function: E32Main
+
+ Description: Main function called by E32.
+
+ Parameters: None
+
+ Return Values: TInt: KErrNone :No errors occurred
+ TInt: Other Symbian OS Error :Error catch by TRAP
+
+ Errors/Exceptions: TRAP is used to catch errors from leaving methods.
+
+ Status: Approved
+
+-------------------------------------------------------------------------------
+*/
+GLDEF_C TInt E32Main()
+ {
+
+ TInt processHandleCountBefore;
+ TInt threadHandleCountBefore;
+ RThread().HandleCount( processHandleCountBefore, threadHandleCountBefore );
+ TInt reqsBefore = RThread().RequestCount();
+
+ TInt processHandleCountAfter;
+ TInt threadHandleCountAfter;
+ TInt reqsAfter;
+
+ __UHEAP_MARK;
+
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ if ( cleanup == NULL )
+ {
+ __UHEAP_MARKEND;
+ return KErrNoMemory;
+ }
+
+ CActiveScheduler* activeScheduler = new CActiveScheduler;
+ if ( activeScheduler == NULL )
+ {
+ delete cleanup;
+ __UHEAP_MARKEND;
+ return KErrNoMemory;
+ }
+ CActiveScheduler::Install( activeScheduler );
+
+ // Construct the test client
+ CATSInterface* test = NULL;
+ TRAPD( err, test = CATSInterface::NewL() );
+ if ( err != KErrNone )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("ATSInterface construction failed %d: "), err );
+#endif
+ delete cleanup;
+ delete activeScheduler;
+ __UHEAP_MARKEND;
+ return err;
+ }
+
+ // Run tests
+ TRAP( err, test->RunTestsL() );
+ if ( err != KErrNone )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("RunTestsL left with %d: "), err );
+#endif
+ }
+
+
+ // Deallocate resources
+ delete test;
+ delete activeScheduler;
+ delete cleanup;
+
+ reqsAfter = RThread().RequestCount();
+ RThread().HandleCount( processHandleCountAfter, threadHandleCountAfter );
+
+ if ( reqsAfter != reqsBefore )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("Request count not matching! %d vs. %d: "),
+ reqsBefore, reqsAfter );
+#endif
+ }
+ if ( threadHandleCountAfter != threadHandleCountBefore )
+ {
+#ifdef _DEBUG
+ RDebug::Print(_L("Handle count not matching! %d vs. %d: "),
+ threadHandleCountBefore, threadHandleCountAfter );
+#endif
+ }
+
+ __UHEAP_MARKEND;
+
+ return err;
+ }
+
+// End of File
+
+// End of File