testexecfw/tef/scriptengine/src/testexecute.cpp
changeset 0 3e07fef1e154
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecfw/tef/scriptengine/src/testexecute.cpp	Mon Mar 08 15:03:44 2010 +0800
@@ -0,0 +1,767 @@
+/*
+* Copyright (c) 2005-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:  
+* Script Engine executable entry point.
+* Log initialisation.
+* Command line read.
+* Trigger entry into the top level state machine.
+*
+*/
+
+
+
+/**
+ @file testexecute.cpp
+*/
+
+#include <testexecuteclient.h>
+#include "ScriptEngine.h"
+#include <testexecutelogger.h>
+#include "TestWatcher.h"
+#include "Version.h"
+#include "tefutils.h"
+
+#include <f32file.h>
+#include <wrapperutilsplugin.h>
+
+
+const TInt KBuffSize= 500;
+GLDEF_D TInt CScriptControl::commentedCommandsCount;
+GLDEF_D TInt CScriptControl::iRunScriptFailCount;
+
+/**
+ * Code for reading commandline set when testexecute is invoked
+ * @param aCommandLine - Function fills descriptor with space separated command line args
+ */
+LOCAL_C void ReadCommandLineL(TDes& aCommandLine)
+	{
+	// Far simpler for EKA2
+	if(User::CommandLineLength() > aCommandLine.MaxLength())
+		User::Leave(KErrTooBig);
+	User::CommandLine(aCommandLine);
+	}
+
+/**
+ * Function to parse command line and set optional flags with ON/OFF status acordingly
+ * @param aCommandLine - Command line descriptor with ' ' separated arguments/tokens
+ * @param aSeparateLogFiles - Function sets to ETrue if -slf is detected in command line
+ * @param aJustInTime - Function sets to ETrue if -d is detected in command line
+ * @param aGraphicalWindowServer - Function sets to ETrue if -gws is detected in command line
+ * @param HelpRequest - Function sets to ETrue if -help is detected in command line
+ * @param aVersionRequest - Function sets to ETrue if -v is detected in command line
+ * @param aParseTestExecuteIni - Object of the parser class for checking options set through testexecute.ini
+ * @param aParserState - TInt value representing whether the parser object instance is active or not
+ */
+LOCAL_C void ParseCommandLine(const TDesC& aCommandLine,TBool& aSeparateLogFiles,TBool& aJustInTime,
+TBool& aGraphicalWindowServer,TBool& aIncludeSelectiveCases,TBool& aExcludeSelectiveCases, TBool& aPipe, TBool& aHelpRequest, TBool& aVersionRequest, 
+CTestExecuteIniData& aParseTestExecuteIni, TInt& aParserState)
+	{
+	// Set up a lex for looping through the command line arguments
+	TLex flagLex(aCommandLine);
+	// Initialise all flags to false
+	aJustInTime = EFalse;
+	aSeparateLogFiles = EFalse;
+	aGraphicalWindowServer = EFalse;
+	aHelpRequest = EFalse;
+	aVersionRequest = EFalse;
+
+	_LIT(KTestExecuteCommandLineHelp, "-help");
+	_LIT(KTestExecuteCommandLineVersion, "-v");
+
+	while(!flagLex.Eos())
+		{
+		TPtrC token(flagLex.NextToken());
+		TInt result = 0;
+		// Get the value for JustInTimeDebug from the TestExecute.ini parser 
+		if (aParserState == KErrNone)
+			{
+			// Get the value from testexecute.ini for optional flag 'JustInTimeDebug'
+			aParseTestExecuteIni.GetKeyValueFromIni(KTEFJustInTimeDebug, result);
+			}
+		const TInt KOne = 1;
+		if(token == KTestExecuteCommandLineFlagDebugMode || result == KOne)
+			{
+			// if the command line contains the token '-d' or the testexecute.ini flag options for JustinTime is set to 'ON'
+			aJustInTime = ETrue;
+			}
+		else if(token == KTestExecuteCommandLineFlagSeparateLogFileMode)
+			{
+			// if the command line contains the token '-slf'
+			aSeparateLogFiles = ETrue;
+			}
+		else if(token == KTestExecuteCommandLineFlagIncludeSelectiveCases)
+			{
+			// if the command line contains the token '-tci'
+			aIncludeSelectiveCases= ETrue;
+			}
+		else if(token == KTestExecuteCommandLineFlagExcludeSelectiveCases)
+			{
+			// if the command line contains the token '-tcx'
+			aExcludeSelectiveCases= ETrue;
+			}
+		else if(token == KTestExecuteCommandLineFlagPipe)
+			{
+			aPipe = ETrue ; 
+			}
+		else if(token == KTestExecuteCommandLineHelp)
+			{
+			// if the command line contains the token '-help'
+			aHelpRequest = ETrue;
+			}
+		else if(token == KTestExecuteCommandLineVersion)
+			{
+			// if the command line contains the token '-v'
+			aVersionRequest = ETrue;
+			}
+		}
+	}
+
+LOCAL_C void DistinguishElement(const TPtrC& aElement, RArray<TRange>& aSelectiveCaseRange)
+{
+
+	TInt colonOccurance = aElement.FindC(KTEFColon);
+	//we are expecting only a range or a test case ID over here...
+	if( colonOccurance!=KErrNotFound )
+		{
+		//then this is a range of testcases, split it at the colon
+		TRange newRange(aElement.Left(colonOccurance),aElement.Mid(colonOccurance+1));
+		aSelectiveCaseRange.Append(newRange);
+		}
+	else
+		{
+		TRange newRange(aElement,aElement);
+		aSelectiveCaseRange.Append(newRange);	
+		}
+}
+
+/**
+ * Read the Cfg File data into a heap buffer
+ * And populate the arrays of selective test case IDs and 
+ * Ranges to be used by the state machine
+ * NOTE: we do not support nested cfgs...
+ */
+LOCAL_C void CreateCfgDataFromFileL(TPtrC& aCfgFilePath,RArray<TRange>& aSelectiveCaseRange, TDesC*& aSelTestCfgFileData)
+	{
+	
+	RFs fS;
+	User::LeaveIfError(fS.Connect());
+	CleanupClosePushL(fS);
+	RFile cfgFile;
+	User::LeaveIfError(cfgFile.Open(fS,aCfgFilePath,EFileRead | EFileShareAny));
+	CleanupClosePushL(cfgFile);
+	TInt fileSize;
+	User::LeaveIfError(cfgFile.Size(fileSize));
+	// Create a 16bit heap buffer
+	HBufC* cfgData = HBufC::NewL(fileSize);
+	CleanupStack::PushL(cfgData);
+	HBufC8* narrowData = HBufC8::NewL(fileSize);
+	CleanupStack::PushL(narrowData);
+	TPtr8 narrowPtr=narrowData->Des();
+	// Read the file into an 8bit heap buffer
+	User::LeaveIfError(cfgFile.Read(narrowPtr));
+	TPtr widePtr(cfgData->Des());
+	// Copy it to the 16bit buffer
+	widePtr.Copy(narrowData->Des());
+	CleanupStack::PopAndDestroy(narrowData);
+	CleanupStack::Pop(cfgData);
+	CleanupStack::Pop(2);
+	cfgFile.Close();
+	fS.Close();
+	// Set up the instance token parser
+	TLex cfgLex = cfgData->Des();
+	aSelTestCfgFileData = cfgData; // to preserve the pointer of cfgdata and transfer the ownership to aSelTestCfgFileData 
+	cfgData = NULL; // relinquish the ownership
+	while(!cfgLex.Eos())
+		{
+		DistinguishElement(cfgLex.NextToken(),aSelectiveCaseRange) ; 
+		}
+	
+	}
+
+
+
+LOCAL_C void ParseCommandLineForSelectiveTestingOptions(const TDesC& aCommandLine,CTestExecuteIniData& aParseTestExecuteIni,RArray<TRange>& aSelectiveCaseRange,  TDesC*& aSelTestCfgFileData)
+	{
+	TLex flagLex(aCommandLine);
+	//first of all navigate the command line arguments to the selective test cases flag...
+	while(!flagLex.Eos())
+	{
+		TPtrC token(flagLex.NextToken());
+		if( (token.CompareF(KTestExecuteCommandLineFlagIncludeSelectiveCases) == 0) || (token.CompareF(KTestExecuteCommandLineFlagExcludeSelectiveCases) == 0) )
+			{
+			break;
+			}
+	}
+	
+	TPtrC argument(flagLex.NextToken()) ; 
+	while(argument.Length() > 0 )	
+		{
+		TInt commaOccurance = argument.FindC(KTEFComma) ;
+		TPtrC element ; 
+		if(commaOccurance == -1)	
+			{
+			//handle the case where no comma is found, 
+			//assume only one item in the list
+			element.Set(argument) ; 
+			//reset argument to break the while
+			argument.Set(KNull);
+			}
+		else
+			{
+			element.Set(argument.Left(commaOccurance));
+			//take the remaining in the argument
+			TInt len = argument.Length()-commaOccurance-1 ; 
+			argument.Set(argument.Right(len)) ; 	
+			}
+		
+		TInt cfgExtensionOccurance = element.FindC(KTEFCfgExtension) ; 
+		if (cfgExtensionOccurance!=KErrNotFound) //madatory extension to be given
+			{
+			
+			TPtrC cfgFilePath(element);
+			//its probably the cfg file path.
+			TBuf<KBuffSize> tempScriptPath(cfgFilePath);
+			// Check whether cfg name is provided along with folder path in the command line
+			// If not, take the path from testexecute.ini & name from the command line
+			if(cfgFilePath.FindC(KTEFColon)==KErrNotFound)
+				{
+				TBuf<KMaxTestExecuteNameLength> tempBuffer;
+				aParseTestExecuteIni.GetKeyValueFromIni(KTEFDefaultScriptPath, tempBuffer);
+				cfgFilePath.Set(tempBuffer);
+				// Construct the full file path from the values extracted from command line and ini file
+				TBuf<KBuffSize> storeScriptPathTemp(cfgFilePath);
+				storeScriptPathTemp.Append(tempScriptPath);
+				cfgFilePath.Set(storeScriptPathTemp);
+				tempScriptPath.Copy(cfgFilePath);
+				}
+				// and parse this cfg File to populate our structures
+				TRAP_IGNORE(CreateCfgDataFromFileL(cfgFilePath,aSelectiveCaseRange, aSelTestCfgFileData));
+				//actually do nothing with the error...
+			}
+		else
+			{
+			DistinguishElement(element,aSelectiveCaseRange  );
+			}
+		}
+	}
+
+/**
+ * Subroutine performing pre-processing tasks for testexecute execution
+ * Also, responsible for triggering the state machine through instance of ScriptMaster
+ * @param aScheduler - Instance of ActiveScheduler created through MainL()
+ * @param aSysDrive - Default system drive letter to be used for all script parsing
+ */
+LOCAL_C void ProcessMainL(CActiveScheduler* aScheduler, const TDriveName aSysDrive)
+	{
+	TDriveName defaultSysDrive(aSysDrive);
+	TDriveName testSysDrive(KTEFLegacySysDrive);
+	TInt waitForLoggingTime = 0;
+	TBuf<KMaxTestExecuteNameLength> htmlLogPath;
+	// Create a object of the Parser for TestExecute.ini
+	CTestExecuteIniData* parseTestExecuteIni = NULL;
+	TRAPD(err, parseTestExecuteIni = CTestExecuteIniData::NewL(defaultSysDrive));
+	if (err == KErrNone)
+		{
+		CleanupStack::PushL(parseTestExecuteIni);
+		// Extract all the key values within the object
+		parseTestExecuteIni->ExtractValuesFromIni();
+		}
+
+	// Read and parse the command line for the flags
+	// -d -slf -help and -v
+	TBuf<KMaxTestExecuteCommandLength> commandLine;
+	TDesC* selTestCfgFileData = NULL; //the pointer to the data of in the .tcs file
+	ReadCommandLineL(commandLine);
+	
+	// Make lower case because we parse it for flags and search for ".script"
+	commandLine.LowerCase();
+	TBool separateLogFiles(EFalse); // -slf
+	TBool justInTime(EFalse); // -d
+	TBool graphicalWindowServer(EFalse); // -gws
+	TBool helpRequest(EFalse); // -help
+	TBool versionRequest(EFalse); // -v
+
+	TBool includeSelectiveCases(EFalse); // -tci
+	TBool excludeSelectiveCases(EFalse); // -tcx
+	TBool pipe(EFalse) ; 
+	
+	// Set up the bools from the command line
+	ParseCommandLine(commandLine,separateLogFiles,justInTime,graphicalWindowServer,includeSelectiveCases, excludeSelectiveCases,pipe, helpRequest,versionRequest,*parseTestExecuteIni,err);
+	// If -d then set Just In Time debugging. Panicks break into debug on emulator
+	(justInTime) ? (User::SetJustInTime(ETrue)) : (User::SetJustInTime(EFalse)); 
+
+	// Hooks for creating the Graphical Window server
+	#ifdef GWS
+	#endif
+
+	// Create a console
+	_LIT(KMessage,"TestExecute Script Engine");
+	CConsoleBase* console = Console::NewL(KMessage,TSize(KConsFullScreen,KConsFullScreen));
+	CleanupStack::PushL(console);
+	console->SetCursorHeight(0);
+	RConsoleLogger consoleLogger(*console);
+	
+	CScriptControl::iRunScriptFailCount=0;
+	// A lex for getting the first command line argument, ie the script file path
+	TLex lex(commandLine);
+	TPtrC scriptFilePath(lex.NextToken());
+	TInt ret = KErrNotFound;
+	if (scriptFilePath.CompareF(KNull) != 0)
+		{
+		_LIT(KTEFSwitchPrefix, "-");
+		if(scriptFilePath.Mid(0,1).CompareF(KTEFSwitchPrefix) == 0)
+			{
+			// If the first command line argument is not the script file path but a optional switches
+			// Then set the script file path for the execution to be 'blank'
+			scriptFilePath.Set(KNull);
+			}
+		else
+			{
+			TBuf<KBuffSize> tempScriptPath(scriptFilePath);
+
+			// Check whether script name is provided along with folder path in the command line
+			// If not, take the path from testexecute.ini & name from the command line
+			ret=scriptFilePath.FindC(KTEFColon);
+			if(ret==KErrNotFound)
+				{
+				if (parseTestExecuteIni != NULL)
+					{
+					TBuf<KMaxTestExecuteNameLength> tempBuffer;
+					parseTestExecuteIni->GetKeyValueFromIni(KTEFDefaultScriptPath, tempBuffer);
+ 					// If the relative script file path does not refer to the root,
+ 					// we will look for DefaultScriptDir entry in testexecute.ini
+ 					// If available prepend it to the relative path
+ 					// else if the relative path refers to root,
+ 					// then set the default system drive, i.e. c:
+ 					// else leaving it as it is (considering invalid path)
+ 					if (scriptFilePath.Left(1).CompareF(KTEFSlash) != 0 &&
+ 					 tempBuffer.Length() > 0)
+ 						scriptFilePath.Set(tempBuffer);
+ 					else if (scriptFilePath.Left(1).CompareF(KTEFSlash) == 0)
+ 						scriptFilePath.Set(defaultSysDrive);
+ 					else
+ 						scriptFilePath.Set(KNull);
+					}
+				else
+					{
+					// If the file path is not provided in command line as well as in testexecute.ini
+					// then set the  script file path to be 'blank'
+					scriptFilePath.Set(KNull);
+					}
+
+				// Construct the full file path from the values extracted from command line and ini file
+				TBuf<KBuffSize> storeScriptPathTemp(scriptFilePath);
+				storeScriptPathTemp.Append(tempScriptPath);
+				scriptFilePath.Set(storeScriptPathTemp);
+				tempScriptPath.Copy(scriptFilePath);
+				}
+
+			//If scriptFilePath is not appended by .script Append .script 
+			if(scriptFilePath.Find(KTEFScriptExtension)==KErrNotFound)
+				{
+				tempScriptPath.Append(KTEFScriptExtension);
+				}
+			scriptFilePath.Set(tempScriptPath);
+			}
+		}
+
+	TPtrC pipeName ; 
+	if(pipe)
+		{
+		TLex flagLex(commandLine);
+		//first of all navigate the command line arguments to the selective test cases flag...
+		while(!flagLex.Eos())
+		{
+			TPtrC token(flagLex.NextToken());
+			if( (token.CompareF(KTestExecuteCommandLineFlagPipe) == 0) )
+				{
+				break;
+				}
+		}
+		pipeName.Set(flagLex.NextToken()) ; 	
+		}
+	
+	TSelectiveTestingOptions* selTestingOptions =NULL;
+	if (includeSelectiveCases && excludeSelectiveCases)
+		{
+			//mutually exclusive options have been encountered
+			includeSelectiveCases =EFalse;
+			excludeSelectiveCases =EFalse;					
+			console->Printf(KTEFInvalidCommandSetMessage);
+			console->Printf(KTEFEnterKeyMessage);
+			console->Getch();
+		}
+	else
+		{
+		if(includeSelectiveCases || excludeSelectiveCases)
+			{
+			RArray<TRange> selectiveCaseRange;
+			ParseCommandLineForSelectiveTestingOptions(commandLine,*parseTestExecuteIni,selectiveCaseRange, selTestCfgFileData);
+			
+			//you need to sort these two arrays first, and also if they are both empty ignore the entire option altogether.
+			if(  selectiveCaseRange.Count() > 0 )
+				{
+				CleanupStack::PushL(selTestCfgFileData);
+				TLinearOrder<TRange> orderingrng(TRange::CompareTRangeStartOrder) ; 
+				selectiveCaseRange.Sort(orderingrng );
+				ESelectiveTesting selectiveTestingType(iExclusive);
+				if(includeSelectiveCases)
+					{
+					selectiveTestingType = iInclusive ; 
+					}
+				selTestingOptions = new(ELeave) TSelectiveTestingOptions(selectiveCaseRange, selectiveTestingType);
+				}
+			else
+				{
+				//if no arguments to this option have been found, ignore it...
+				includeSelectiveCases =EFalse;
+				excludeSelectiveCases =EFalse;
+				delete selTestCfgFileData;
+				}
+			}
+		}
+
+	if (scriptFilePath.CompareF(KNull)==0)
+		{
+		if (!separateLogFiles && !justInTime)
+			{
+			// Print the product version details through console window
+			console->Printf(KTEFVersionMessage);
+			console->Printf(KTEFProductVersion);
+
+			if (!(versionRequest && !helpRequest))
+				{
+				// Print the help & usage informations through console window along with product version
+				console->Printf(KTEFConsoleHelpMessage1);
+				console->Printf(KTEFConsoleHelpMessage2);
+				console->Printf(KTEFConsoleHelpMessage3);
+				console->Printf(KTEFConsoleHelpMessage4);
+				console->Printf(KTEFConsoleHelpMessage5);
+				}
+			}
+		else
+			{
+			// Display a error message on the console window for invalid set of arguments
+			console->Printf(KTEFInvalidCommandSetMessage);
+			}
+		// Exit on a key press from user
+		console->Printf(KTEFEnterKeyMessage);
+		console->Getch();
+		}
+	else
+		{
+		// Create a Interface class object for generating HTML & XML logs
+		CTestExecuteLogger *tefLogger = new(ELeave) CTestExecuteLogger();
+		CleanupStack::PushL(tefLogger);
+
+		TInt logMode;
+		TInt logLevel;
+		TInt remotePanicDetection;
+		TBuf<KMaxTestExecuteNameLength> iniSysDrive;
+
+		if (parseTestExecuteIni != NULL)
+			{
+			// Parse ini for retrieving logging options set through ini
+			parseTestExecuteIni->GetKeyValueFromIni(KTEFLogMode, logMode);
+			parseTestExecuteIni->GetKeyValueFromIni(KTEFLogSeverityKey, logLevel);
+			parseTestExecuteIni->GetKeyValueFromIni(KTEFRemotePanicDetection, remotePanicDetection);
+			parseTestExecuteIni->GetKeyValueFromIni(KTEFDefaultSysDrive, iniSysDrive);
+			parseTestExecuteIni->GetKeyValueFromIni(KTEFWaitForLoggingTime, waitForLoggingTime);
+			parseTestExecuteIni->GetKeyValueFromIni(KTEFHtmlKey, htmlLogPath);
+			}
+		else
+			{
+			// Set default values for logging options if parser is not functioning
+			logMode = TLoggerOptions(ELogHTMLOnly);
+			logLevel = RFileFlogger::TLogSeverity(ESevrAll);
+			remotePanicDetection = 0;
+			iniSysDrive.Copy(KTEFIniSysDrive);
+			waitForLoggingTime = 5;
+			htmlLogPath.Copy(KTestExecuteLogPath);
+			htmlLogPath.Replace(0, 2, defaultSysDrive);
+			}
+		
+		tefLogger->SetLoggerOptions(logMode);
+		if(pipe)
+			{
+			tefLogger->SetPipeName(pipeName) ; 
+			}
+		
+		// Initialise the logging passing in the script file path & log level to the interface
+		tefLogger->InitialiseLoggingL(scriptFilePath, separateLogFiles, logLevel);
+
+		// Check to see if defaultsysdrive key is set in testexecute.ini
+		// if set to SYSDRIVE, assign the default system drive obtained from the plugin
+		// else, if a true value is set in testexecute.ini, use it as system drive for all test artifacts
+		if (iniSysDrive.Length() == 2 && iniSysDrive.Right(1).Compare(KTEFColon) == 0)
+			testSysDrive.Copy(iniSysDrive);
+		else if (iniSysDrive.CompareF(KTEFIniSysDrive) == 0)
+			testSysDrive.Copy(defaultSysDrive);
+
+
+		// Pass the first command line argument to the script master
+		// which is always the command script
+		CScriptMaster* scriptMaster = new (ELeave) CScriptMaster(scriptFilePath,*tefLogger, consoleLogger, defaultSysDrive, testSysDrive, selTestingOptions);
+		// To kick the state machine of the script master off -
+		// Call the kick method which jumps us into the RunL() of the CScriptMaster class
+		// CScriptMaster is the top AO in the hierarchy.
+		scriptMaster->Kick();
+
+		// Construct and Install a test watcher object for capturing remote panics during test execution
+		CTestWatcher* testWatcher = NULL;
+		if (remotePanicDetection != 0)
+			{
+			testWatcher = CTestWatcher::NewL();
+			testWatcher->StartL();
+			}
+
+		// Enter the Active Scheduler
+		aScheduler->Start();
+		
+		// Cleanup
+		delete scriptMaster;
+		
+		TInt commentedCommandsCnt=CScriptControl::commentedCommandsCount;
+		if(commentedCommandsCnt==-1)
+			{
+			CScriptControl::commentedCommandsCount=0;
+			//If the path specified fails check out for path from testexecute.ini
+			if(ret!=KErrNotFound)
+				{
+				//To get scriptFile name  i.e get sampleFile.script
+				TInt posOfLastSlash=scriptFilePath.LocateReverse('\\') ;
+				scriptFilePath.Set(scriptFilePath.Mid(posOfLastSlash+1));
+				TBuf<KBuffSize> tempStore(scriptFilePath);
+				if (parseTestExecuteIni != NULL)
+					{
+					TBuf<KMaxTestExecuteNameLength> tempBuffer;
+					parseTestExecuteIni->GetKeyValueFromIni(KTEFDefaultScriptPath, tempBuffer);
+					if (tempBuffer.CompareF(KNull) != 0)
+						{
+						scriptFilePath.Set(tempBuffer);
+						TBuf<KBuffSize> tempStoreScriptPath(scriptFilePath);
+						tempStoreScriptPath.Append(tempStore);
+						scriptFilePath.Set(tempStoreScriptPath);
+						TBuf<KMaxTestExecuteNameLength> scriptFileLocation(scriptFilePath);
+						CScriptMaster* scriptMaster = new (ELeave) CScriptMaster(scriptFilePath,*tefLogger, consoleLogger, defaultSysDrive, testSysDrive, selTestingOptions);
+						// To kick the state machine of the script master off -
+						// Call the kick method which jumps us into the RunL() of the CScriptMaster class
+						// CScriptMaster is the top AO in the hierarchy.
+						scriptMaster->Kick();
+						// Enter the Active Scheduler
+						aScheduler->Start();
+						
+						commentedCommandsCnt=CScriptControl::commentedCommandsCount;
+						if(commentedCommandsCnt==-1)
+							{
+							CScriptControl::commentedCommandsCount=0;
+							}
+							
+						// Cleanup
+						delete scriptMaster;
+						}
+					}
+				}
+			}
+		delete selTestingOptions;
+		
+		TInt commandsCount = CScriptControl::commentedCommandsCount;
+		TInt countOfRemotePanics = 0;
+
+		// Stop and Process the test watcher object for extracting panic informations and print them to the log files
+		if (remotePanicDetection != 0)
+			{
+			testWatcher->Stop();
+			countOfRemotePanics = testWatcher->iSharedData->iPanicDetails.Count();
+			if (countOfRemotePanics > 0)
+				{
+				tefLogger->LogExtra((TText8*)__FILE__,__LINE__,ESevrErr,
+					_L("The panic detection thread detected %d panics:"), countOfRemotePanics);
+				for (TInt count = 0; count < countOfRemotePanics; count++)
+					tefLogger->LogExtra((TText8*)__FILE__,__LINE__,ESevrErr,_L("Remote Panic %d - Name of Panicked Thread: %S, Exit Reason: %d, Exit Category %S"), count+1, &(testWatcher->iSharedData->iPanicDetails)[count]->iThreadName,(testWatcher->iSharedData->iPanicDetails)[count]->iReason,&(testWatcher->iSharedData->iPanicDetails)[count]->iCategory);
+				}
+			delete testWatcher;
+			}
+
+		// Call the Termination routine for logging within the interface
+		tefLogger->TerminateLoggingL(commandsCount, countOfRemotePanics, CScriptControl::iRunScriptFailCount);
+		CleanupStack::Pop(tefLogger);
+		delete tefLogger;
+		}
+	if(includeSelectiveCases || excludeSelectiveCases)
+		{	
+		CleanupStack::PopAndDestroy(selTestCfgFileData);
+		selTestCfgFileData = NULL;
+		}
+	// Close the parser instance if it is active
+	CleanupStack::PopAndDestroy(console);
+	if (parseTestExecuteIni != NULL)
+		{
+		CleanupStack::PopAndDestroy(parseTestExecuteIni);
+		}
+
+	if (scriptFilePath.CompareF(KNull)!=0)
+		{
+		// Wait for flogger to write to file
+		_LIT(KHtmExtension,".htm");
+		TParse fileNameParse;
+		fileNameParse.Set(scriptFilePath, NULL, NULL);
+		
+		TPtrC fileName = fileNameParse.Name();
+		htmlLogPath.Append(fileName);
+		htmlLogPath.Append(KHtmExtension);
+
+	#ifdef _DEBUG
+		RDebug::Print(_L("Log file path--> %S"), &htmlLogPath);
+	#endif
+		RFs fs;
+		fs.Connect();
+		TBool answer = EFalse;
+		while(ETrue)
+			{
+			TInt err = fs.IsFileOpen(htmlLogPath, answer);
+			if ((KErrNone==err&&!answer) || KErrNotFound==err || KErrPathNotFound==err) 
+				{
+				break;
+				}
+			User::After(100000);
+			}
+		
+		if (waitForLoggingTime > 0)
+			{
+			User::After(waitForLoggingTime*1000000);
+			}
+		}
+	}
+
+/**
+ * Top level function inside the TRAP harness
+ * TEF system calls for:
+ *		Active scheduler initialisation
+ *		Command line read and parse
+ *		Console creation
+ *		Logging Initialisation
+ *		Entry to script engine
+ *		Logging termination
+ * @param aSysDrive - Default system drive letter to be used for all script parsing
+ */
+LOCAL_C void MainL(const TDriveName aSysDrive)
+	{
+#if (defined __DATA_CAGING__)
+	// Platform security hooks
+	RProcess().DataCaging(RProcess::EDataCagingOn);
+	RProcess().SecureApi(RProcess::ESecureApiOn);
+#endif
+	CActiveScheduler* sched = new (ELeave) CActiveScheduler();
+	CleanupStack::PushL(sched);
+	CActiveScheduler::Install(sched);
+
+	// Call up the subroutine to perform pre-processing tasks and to start test execution
+	ProcessMainL(sched, aSysDrive);
+
+	// Cleanup the scheduler object
+	CleanupStack::PopAndDestroy(sched);
+	}
+
+#if !(defined TEF_LITE)
+LOCAL_C void StartSystemL()
+	{
+	CActiveScheduler* theScheduler = new (ELeave) CActiveScheduler();
+	CleanupStack::PushL(theScheduler);
+	CActiveScheduler::Install(theScheduler);
+	
+	RLibrary pluginLibrary;
+	CWrapperUtilsPlugin* plugin = TEFUtils::WrapperPluginNew(pluginLibrary);
+	
+	if (plugin!=NULL)
+		{
+		plugin->WaitForSystemStartL();
+		delete plugin;
+		pluginLibrary.Close();
+		}
+	else
+		{
+		User::Leave(KErrGeneral);
+		}
+	
+	CleanupStack::PopAndDestroy(theScheduler);
+	}
+#endif
+
+/**
+ * Executable Entry Point
+ * Top level always creates TRAP harness.
+ * Calls MainL() inside the TRAP harness
+ */
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if(cleanup == NULL)
+		{
+		return KErrNoMemory;
+		}
+
+  // Fix PDEF124952, set the priority EPriorityAbsoluteHigh. In this case, the timeout will 
+  // take effect even if the server executes with almost 100% CPU usage.
+  RThread().SetPriority(EPriorityAbsoluteHigh);
+  // End PDEF124952
+  
+	// Check to see if the plugin wrapper around the GetSystemDrive is loadable
+	// If yes, then instantiate the wrapper object and obtain the default system drive
+	// Else, use the hardcoded default drive as c:
+	TDriveName defaultSysDrive(KTEFLegacySysDrive);	
+	
+	RLibrary pluginLibrary;
+	CWrapperUtilsPlugin* plugin = TEFUtils::WrapperPluginNew(pluginLibrary);
+	
+	if (plugin!=NULL)
+		{
+		TDriveUnit driveUnit(plugin->GetSystemDrive());
+		defaultSysDrive.Copy(driveUnit.Name());
+		delete plugin;
+		pluginLibrary.Close();
+		}
+	
+	TBool enableSysStart = ETrue;
+	CTestExecuteIniData* iniData = NULL;
+	TRAPD(err, iniData = CTestExecuteIniData::NewL(defaultSysDrive));
+	if (err == KErrNone)
+		{
+		// Extract all the key values within the object
+		iniData->ExtractValuesFromIni();
+		iniData->GetKeyValueFromIni(KTEFSystemStarter, enableSysStart);
+		}
+
+	err = KErrNone;
+	#if !(defined TEF_LITE)
+	if (enableSysStart)
+		{
+		TRAP(err, StartSystemL());
+		__ASSERT_ALWAYS(!err, User::Panic(KTestExecuteName,err));
+		}
+	#endif
+	if (iniData != NULL)
+		{
+		delete iniData;
+		}	
+	
+	err = KErrNone;
+	TRAP(err,MainL(defaultSysDrive));
+	__ASSERT_ALWAYS(!err, User::Panic(KTestExecuteName,err));
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return KErrNone;
+    }
+