testexecmdw/tef/tef/scriptengine/src/testexecute.cpp
branchRCL_3
changeset 3 9397a16b6eb8
parent 1 6edeef394eb7
equal deleted inserted replaced
1:6edeef394eb7 3:9397a16b6eb8
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 * Script Engine executable entry point.
       
    16 * Log initialisation.
       
    17 * Command line read.
       
    18 * Trigger entry into the top level state machine.
       
    19 *
       
    20 */
       
    21 
       
    22 
       
    23 
       
    24 /**
       
    25  @file testexecute.cpp
       
    26 */
       
    27 
       
    28 #include <test/testexecuteclient.h>
       
    29 #include "scriptengine.h"
       
    30 #include <test/testexecutelogger.h>
       
    31 #include "testwatcher.h"
       
    32 #include "version.h"
       
    33 #include "tefutils.h"
       
    34 
       
    35 #include <f32file.h>
       
    36 #include <test/wrapperutilsplugin.h>
       
    37 
       
    38 
       
    39 const TInt KBuffSize= 500;
       
    40 GLDEF_D TInt CScriptControl::commentedCommandsCount;
       
    41 GLDEF_D TInt CScriptControl::iRunScriptFailCount;
       
    42 
       
    43 /**
       
    44  * Code for reading commandline set when testexecute is invoked
       
    45  * @param aCommandLine - Function fills descriptor with space separated command line args
       
    46  */
       
    47 LOCAL_C void ReadCommandLineL(TDes& aCommandLine)
       
    48 	{
       
    49 	// Far simpler for EKA2
       
    50 	if(User::CommandLineLength() > aCommandLine.MaxLength())
       
    51 		User::Leave(KErrTooBig);
       
    52 	User::CommandLine(aCommandLine);
       
    53 	}
       
    54 
       
    55 /**
       
    56  * Function to parse command line and set optional flags with ON/OFF status acordingly
       
    57  * @param aCommandLine - Command line descriptor with ' ' separated arguments/tokens
       
    58  * @param aSeparateLogFiles - Function sets to ETrue if -slf is detected in command line
       
    59  * @param aJustInTime - Function sets to ETrue if -d is detected in command line
       
    60  * @param aGraphicalWindowServer - Function sets to ETrue if -gws is detected in command line
       
    61  * @param HelpRequest - Function sets to ETrue if -help is detected in command line
       
    62  * @param aVersionRequest - Function sets to ETrue if -v is detected in command line
       
    63  * @param aParseTestExecuteIni - Object of the parser class for checking options set through testexecute.ini
       
    64  * @param aParserState - TInt value representing whether the parser object instance is active or not
       
    65  */
       
    66 LOCAL_C void ParseCommandLine(const TDesC& aCommandLine,TBool& aSeparateLogFiles,TBool& aJustInTime,
       
    67 TBool& aGraphicalWindowServer,TBool& aIncludeSelectiveCases,TBool& aExcludeSelectiveCases, TBool& aPipe, TBool& aHelpRequest, TBool& aVersionRequest, 
       
    68 CTestExecuteIniData& aParseTestExecuteIni, TInt& aParserState)
       
    69 	{
       
    70 	// Set up a lex for looping through the command line arguments
       
    71 	TLex flagLex(aCommandLine);
       
    72 	// Initialise all flags to false
       
    73 	aJustInTime = EFalse;
       
    74 	aSeparateLogFiles = EFalse;
       
    75 	aGraphicalWindowServer = EFalse;
       
    76 	aHelpRequest = EFalse;
       
    77 	aVersionRequest = EFalse;
       
    78 
       
    79 	_LIT(KTestExecuteCommandLineHelp, "-help");
       
    80 	_LIT(KTestExecuteCommandLineVersion, "-v");
       
    81 
       
    82 	while(!flagLex.Eos())
       
    83 		{
       
    84 		TPtrC token(flagLex.NextToken());
       
    85 		TInt result = 0;
       
    86 		// Get the value for JustInTimeDebug from the TestExecute.ini parser 
       
    87 		if (aParserState == KErrNone)
       
    88 			{
       
    89 			// Get the value from testexecute.ini for optional flag 'JustInTimeDebug'
       
    90 			aParseTestExecuteIni.GetKeyValueFromIni(KTEFJustInTimeDebug, result);
       
    91 			}
       
    92 		const TInt KOne = 1;
       
    93 		if(token == KTestExecuteCommandLineFlagDebugMode || result == KOne)
       
    94 			{
       
    95 			// if the command line contains the token '-d' or the testexecute.ini flag options for JustinTime is set to 'ON'
       
    96 			aJustInTime = ETrue;
       
    97 			}
       
    98 		else if(token == KTestExecuteCommandLineFlagSeparateLogFileMode)
       
    99 			{
       
   100 			// if the command line contains the token '-slf'
       
   101 			aSeparateLogFiles = ETrue;
       
   102 			}
       
   103 		else if(token == KTestExecuteCommandLineFlagIncludeSelectiveCases)
       
   104 			{
       
   105 			// if the command line contains the token '-tci'
       
   106 			aIncludeSelectiveCases= ETrue;
       
   107 			}
       
   108 		else if(token == KTestExecuteCommandLineFlagExcludeSelectiveCases)
       
   109 			{
       
   110 			// if the command line contains the token '-tcx'
       
   111 			aExcludeSelectiveCases= ETrue;
       
   112 			}
       
   113 		else if(token == KTestExecuteCommandLineFlagPipe)
       
   114 			{
       
   115 			aPipe = ETrue ; 
       
   116 			}
       
   117 		else if(token == KTestExecuteCommandLineHelp)
       
   118 			{
       
   119 			// if the command line contains the token '-help'
       
   120 			aHelpRequest = ETrue;
       
   121 			}
       
   122 		else if(token == KTestExecuteCommandLineVersion)
       
   123 			{
       
   124 			// if the command line contains the token '-v'
       
   125 			aVersionRequest = ETrue;
       
   126 			}
       
   127 		}
       
   128 	}
       
   129 
       
   130 LOCAL_C void DistinguishElement(const TPtrC& aElement, RArray<TRange>& aSelectiveCaseRange)
       
   131 {
       
   132 
       
   133 	TInt colonOccurance = aElement.FindC(KTEFColon);
       
   134 	//we are expecting only a range or a test case ID over here...
       
   135 	if( colonOccurance!=KErrNotFound )
       
   136 		{
       
   137 		//then this is a range of testcases, split it at the colon
       
   138 		TRange newRange(aElement.Left(colonOccurance),aElement.Mid(colonOccurance+1));
       
   139 		aSelectiveCaseRange.Append(newRange);
       
   140 		}
       
   141 	else
       
   142 		{
       
   143 		TRange newRange(aElement,aElement);
       
   144 		aSelectiveCaseRange.Append(newRange);	
       
   145 		}
       
   146 }
       
   147 
       
   148 /**
       
   149  * Read the Cfg File data into a heap buffer
       
   150  * And populate the arrays of selective test case IDs and 
       
   151  * Ranges to be used by the state machine
       
   152  * NOTE: we do not support nested cfgs...
       
   153  */
       
   154 LOCAL_C void CreateCfgDataFromFileL(TPtrC& aCfgFilePath,RArray<TRange>& aSelectiveCaseRange, TDesC*& aSelTestCfgFileData)
       
   155 	{
       
   156 	
       
   157 	RFs fS;
       
   158 	User::LeaveIfError(fS.Connect());
       
   159 	CleanupClosePushL(fS);
       
   160 	RFile cfgFile;
       
   161 	User::LeaveIfError(cfgFile.Open(fS,aCfgFilePath,EFileRead | EFileShareAny));
       
   162 	CleanupClosePushL(cfgFile);
       
   163 	TInt fileSize;
       
   164 	User::LeaveIfError(cfgFile.Size(fileSize));
       
   165 	// Create a 16bit heap buffer
       
   166 	HBufC* cfgData = HBufC::NewL(fileSize);
       
   167 	CleanupStack::PushL(cfgData);
       
   168 	HBufC8* narrowData = HBufC8::NewL(fileSize);
       
   169 	CleanupStack::PushL(narrowData);
       
   170 	TPtr8 narrowPtr=narrowData->Des();
       
   171 	// Read the file into an 8bit heap buffer
       
   172 	User::LeaveIfError(cfgFile.Read(narrowPtr));
       
   173 	TPtr widePtr(cfgData->Des());
       
   174 	// Copy it to the 16bit buffer
       
   175 	widePtr.Copy(narrowData->Des());
       
   176 	CleanupStack::PopAndDestroy(narrowData);
       
   177 	CleanupStack::Pop(cfgData);
       
   178 	CleanupStack::Pop(2);
       
   179 	cfgFile.Close();
       
   180 	fS.Close();
       
   181 	// Set up the instance token parser
       
   182 	TLex cfgLex = cfgData->Des();
       
   183 	aSelTestCfgFileData = cfgData; // to preserve the pointer of cfgdata and transfer the ownership to aSelTestCfgFileData 
       
   184 	cfgData = NULL; // relinquish the ownership
       
   185 	while(!cfgLex.Eos())
       
   186 		{
       
   187 		DistinguishElement(cfgLex.NextToken(),aSelectiveCaseRange) ; 
       
   188 		}
       
   189 	
       
   190 	}
       
   191 
       
   192 
       
   193 
       
   194 LOCAL_C void ParseCommandLineForSelectiveTestingOptions(const TDesC& aCommandLine,CTestExecuteIniData& aParseTestExecuteIni,RArray<TRange>& aSelectiveCaseRange,  TDesC*& aSelTestCfgFileData)
       
   195 	{
       
   196 	TLex flagLex(aCommandLine);
       
   197 	//first of all navigate the command line arguments to the selective test cases flag...
       
   198 	while(!flagLex.Eos())
       
   199 	{
       
   200 		TPtrC token(flagLex.NextToken());
       
   201 		if( (token.CompareF(KTestExecuteCommandLineFlagIncludeSelectiveCases) == 0) || (token.CompareF(KTestExecuteCommandLineFlagExcludeSelectiveCases) == 0) )
       
   202 			{
       
   203 			break;
       
   204 			}
       
   205 	}
       
   206 	
       
   207 	TPtrC argument(flagLex.NextToken()) ; 
       
   208 	while(argument.Length() > 0 )	
       
   209 		{
       
   210 		TInt commaOccurance = argument.FindC(KTEFComma) ;
       
   211 		TPtrC element ; 
       
   212 		if(commaOccurance == -1)	
       
   213 			{
       
   214 			//handle the case where no comma is found, 
       
   215 			//assume only one item in the list
       
   216 			element.Set(argument) ; 
       
   217 			//reset argument to break the while
       
   218 			argument.Set(KNull);
       
   219 			}
       
   220 		else
       
   221 			{
       
   222 			element.Set(argument.Left(commaOccurance));
       
   223 			//take the remaining in the argument
       
   224 			TInt len = argument.Length()-commaOccurance-1 ; 
       
   225 			argument.Set(argument.Right(len)) ; 	
       
   226 			}
       
   227 		
       
   228 		TInt cfgExtensionOccurance = element.FindC(KTEFCfgExtension) ; 
       
   229 		if (cfgExtensionOccurance!=KErrNotFound) //madatory extension to be given
       
   230 			{
       
   231 			
       
   232 			TPtrC cfgFilePath(element);
       
   233 			//its probably the cfg file path.
       
   234 			TBuf<KBuffSize> tempScriptPath(cfgFilePath);
       
   235 			// Check whether cfg name is provided along with folder path in the command line
       
   236 			// If not, take the path from testexecute.ini & name from the command line
       
   237 			if(cfgFilePath.FindC(KTEFColon)==KErrNotFound)
       
   238 				{
       
   239 				TBuf<KMaxTestExecuteNameLength> tempBuffer;
       
   240 				aParseTestExecuteIni.GetKeyValueFromIni(KTEFDefaultScriptPath, tempBuffer);
       
   241 				cfgFilePath.Set(tempBuffer);
       
   242 				// Construct the full file path from the values extracted from command line and ini file
       
   243 				TBuf<KBuffSize> storeScriptPathTemp(cfgFilePath);
       
   244 				storeScriptPathTemp.Append(tempScriptPath);
       
   245 				cfgFilePath.Set(storeScriptPathTemp);
       
   246 				tempScriptPath.Copy(cfgFilePath);
       
   247 				}
       
   248 				// and parse this cfg File to populate our structures
       
   249 				TRAP_IGNORE(CreateCfgDataFromFileL(cfgFilePath,aSelectiveCaseRange, aSelTestCfgFileData));
       
   250 				//actually do nothing with the error...
       
   251 			}
       
   252 		else
       
   253 			{
       
   254 			DistinguishElement(element,aSelectiveCaseRange  );
       
   255 			}
       
   256 		}
       
   257 	}
       
   258 
       
   259 /**
       
   260  * Subroutine performing pre-processing tasks for testexecute execution
       
   261  * Also, responsible for triggering the state machine through instance of ScriptMaster
       
   262  * @param aScheduler - Instance of ActiveScheduler created through MainL()
       
   263  * @param aSysDrive - Default system drive letter to be used for all script parsing
       
   264  */
       
   265 LOCAL_C void ProcessMainL(CActiveScheduler* aScheduler, const TDriveName aSysDrive)
       
   266 	{
       
   267 	TDriveName defaultSysDrive(aSysDrive);
       
   268 	TDriveName testSysDrive(KTEFLegacySysDrive);
       
   269 	TInt waitForLoggingTime = 0;
       
   270 	TBuf<KMaxTestExecuteNameLength> htmlLogPath;
       
   271 	// Create a object of the Parser for TestExecute.ini
       
   272 	CTestExecuteIniData* parseTestExecuteIni = NULL;
       
   273 	TRAPD(err, parseTestExecuteIni = CTestExecuteIniData::NewL(defaultSysDrive));
       
   274 	if (err == KErrNone)
       
   275 		{
       
   276 		CleanupStack::PushL(parseTestExecuteIni);
       
   277 		// Extract all the key values within the object
       
   278 		parseTestExecuteIni->ExtractValuesFromIni();
       
   279 		}
       
   280 
       
   281 	// Read and parse the command line for the flags
       
   282 	// -d -slf -help and -v
       
   283 	TBuf<KMaxTestExecuteCommandLength> commandLine;
       
   284 	TDesC* selTestCfgFileData = NULL; //the pointer to the data of in the .tcs file
       
   285 	ReadCommandLineL(commandLine);
       
   286 	
       
   287 	// Make lower case because we parse it for flags and search for ".script"
       
   288 	commandLine.LowerCase();
       
   289 	TBool separateLogFiles(EFalse); // -slf
       
   290 	TBool justInTime(EFalse); // -d
       
   291 	TBool graphicalWindowServer(EFalse); // -gws
       
   292 	TBool helpRequest(EFalse); // -help
       
   293 	TBool versionRequest(EFalse); // -v
       
   294 
       
   295 	TBool includeSelectiveCases(EFalse); // -tci
       
   296 	TBool excludeSelectiveCases(EFalse); // -tcx
       
   297 	TBool pipe(EFalse) ; 
       
   298 	
       
   299 	// Set up the bools from the command line
       
   300 	ParseCommandLine(commandLine,separateLogFiles,justInTime,graphicalWindowServer,includeSelectiveCases, excludeSelectiveCases,pipe, helpRequest,versionRequest,*parseTestExecuteIni,err);
       
   301 	// If -d then set Just In Time debugging. Panicks break into debug on emulator
       
   302 	(justInTime) ? (User::SetJustInTime(ETrue)) : (User::SetJustInTime(EFalse)); 
       
   303 
       
   304 	// Hooks for creating the Graphical Window server
       
   305 	#ifdef GWS
       
   306 	#endif
       
   307 
       
   308 	// Create a console
       
   309 	_LIT(KMessage,"TestExecute Script Engine");
       
   310 	CConsoleBase* console = Console::NewL(KMessage,TSize(KConsFullScreen,KConsFullScreen));
       
   311 	CleanupStack::PushL(console);
       
   312 	console->SetCursorHeight(0);
       
   313 	RConsoleLogger consoleLogger(*console);
       
   314 	
       
   315 	CScriptControl::iRunScriptFailCount=0;
       
   316 	// A lex for getting the first command line argument, ie the script file path
       
   317 	TLex lex(commandLine);
       
   318 	TPtrC scriptFilePath(lex.NextToken());
       
   319 	TInt ret = KErrNotFound;
       
   320 	if (scriptFilePath.CompareF(KNull) != 0)
       
   321 		{
       
   322 		_LIT(KTEFSwitchPrefix, "-");
       
   323 		if(scriptFilePath.Mid(0,1).CompareF(KTEFSwitchPrefix) == 0)
       
   324 			{
       
   325 			// If the first command line argument is not the script file path but a optional switches
       
   326 			// Then set the script file path for the execution to be 'blank'
       
   327 			scriptFilePath.Set(KNull);
       
   328 			}
       
   329 		else
       
   330 			{
       
   331 			TBuf<KBuffSize> tempScriptPath(scriptFilePath);
       
   332 
       
   333 			// Check whether script name is provided along with folder path in the command line
       
   334 			// If not, take the path from testexecute.ini & name from the command line
       
   335 			ret=scriptFilePath.FindC(KTEFColon);
       
   336 			if(ret==KErrNotFound)
       
   337 				{
       
   338 				if (parseTestExecuteIni != NULL)
       
   339 					{
       
   340 					TBuf<KMaxTestExecuteNameLength> tempBuffer;
       
   341 					parseTestExecuteIni->GetKeyValueFromIni(KTEFDefaultScriptPath, tempBuffer);
       
   342  					// If the relative script file path does not refer to the root,
       
   343  					// we will look for DefaultScriptDir entry in testexecute.ini
       
   344  					// If available prepend it to the relative path
       
   345  					// else if the relative path refers to root,
       
   346  					// then set the default system drive, i.e. c:
       
   347  					// else leaving it as it is (considering invalid path)
       
   348  					if (scriptFilePath.Left(1).CompareF(KTEFSlash) != 0 &&
       
   349  					 tempBuffer.Length() > 0)
       
   350  						scriptFilePath.Set(tempBuffer);
       
   351  					else if (scriptFilePath.Left(1).CompareF(KTEFSlash) == 0)
       
   352  						scriptFilePath.Set(defaultSysDrive);
       
   353  					else
       
   354  						scriptFilePath.Set(KNull);
       
   355 					}
       
   356 				else
       
   357 					{
       
   358 					// If the file path is not provided in command line as well as in testexecute.ini
       
   359 					// then set the  script file path to be 'blank'
       
   360 					scriptFilePath.Set(KNull);
       
   361 					}
       
   362 
       
   363 				// Construct the full file path from the values extracted from command line and ini file
       
   364 				TBuf<KBuffSize> storeScriptPathTemp(scriptFilePath);
       
   365 				storeScriptPathTemp.Append(tempScriptPath);
       
   366 				scriptFilePath.Set(storeScriptPathTemp);
       
   367 				tempScriptPath.Copy(scriptFilePath);
       
   368 				}
       
   369 
       
   370 			//If scriptFilePath is not appended by .script Append .script 
       
   371 			if(scriptFilePath.Find(KTEFScriptExtension)==KErrNotFound)
       
   372 				{
       
   373 				tempScriptPath.Append(KTEFScriptExtension);
       
   374 				}
       
   375 			scriptFilePath.Set(tempScriptPath);
       
   376 			}
       
   377 		}
       
   378 
       
   379 	TPtrC pipeName ; 
       
   380 	if(pipe)
       
   381 		{
       
   382 		TLex flagLex(commandLine);
       
   383 		//first of all navigate the command line arguments to the selective test cases flag...
       
   384 		while(!flagLex.Eos())
       
   385 		{
       
   386 			TPtrC token(flagLex.NextToken());
       
   387 			if( (token.CompareF(KTestExecuteCommandLineFlagPipe) == 0) )
       
   388 				{
       
   389 				break;
       
   390 				}
       
   391 		}
       
   392 		pipeName.Set(flagLex.NextToken()) ; 	
       
   393 		}
       
   394 	
       
   395 	TSelectiveTestingOptions* selTestingOptions =NULL;
       
   396 	if (includeSelectiveCases && excludeSelectiveCases)
       
   397 		{
       
   398 			//mutually exclusive options have been encountered
       
   399 			includeSelectiveCases =EFalse;
       
   400 			excludeSelectiveCases =EFalse;					
       
   401 			console->Printf(KTEFInvalidCommandSetMessage);
       
   402 			console->Printf(KTEFEnterKeyMessage);
       
   403 			console->Getch();
       
   404 		}
       
   405 	else
       
   406 		{
       
   407 		if(includeSelectiveCases || excludeSelectiveCases)
       
   408 			{
       
   409 			RArray<TRange> selectiveCaseRange;
       
   410 			ParseCommandLineForSelectiveTestingOptions(commandLine,*parseTestExecuteIni,selectiveCaseRange, selTestCfgFileData);
       
   411 			
       
   412 			//you need to sort these two arrays first, and also if they are both empty ignore the entire option altogether.
       
   413 			if(  selectiveCaseRange.Count() > 0 )
       
   414 				{
       
   415 				CleanupStack::PushL(selTestCfgFileData);
       
   416 				TLinearOrder<TRange> orderingrng(TRange::CompareTRangeStartOrder) ; 
       
   417 				selectiveCaseRange.Sort(orderingrng );
       
   418 				ESelectiveTesting selectiveTestingType(iExclusive);
       
   419 				if(includeSelectiveCases)
       
   420 					{
       
   421 					selectiveTestingType = iInclusive ; 
       
   422 					}
       
   423 				selTestingOptions = new(ELeave) TSelectiveTestingOptions(selectiveCaseRange, selectiveTestingType);
       
   424 				}
       
   425 			else
       
   426 				{
       
   427 				//if no arguments to this option have been found, ignore it...
       
   428 				includeSelectiveCases =EFalse;
       
   429 				excludeSelectiveCases =EFalse;
       
   430 				delete selTestCfgFileData;
       
   431 				}
       
   432 			}
       
   433 		}
       
   434 
       
   435 	if (scriptFilePath.CompareF(KNull)==0)
       
   436 		{
       
   437 		if (!separateLogFiles && !justInTime)
       
   438 			{
       
   439 			// Print the product version details through console window
       
   440 			console->Printf(KTEFVersionMessage);
       
   441 			console->Printf(KTEFProductVersion);
       
   442 
       
   443 			if (!(versionRequest && !helpRequest))
       
   444 				{
       
   445 				// Print the help & usage informations through console window along with product version
       
   446 				console->Printf(KTEFConsoleHelpMessage1);
       
   447 				console->Printf(KTEFConsoleHelpMessage2);
       
   448 				console->Printf(KTEFConsoleHelpMessage3);
       
   449 				console->Printf(KTEFConsoleHelpMessage4);
       
   450 				console->Printf(KTEFConsoleHelpMessage5);
       
   451 				}
       
   452 			}
       
   453 		else
       
   454 			{
       
   455 			// Display a error message on the console window for invalid set of arguments
       
   456 			console->Printf(KTEFInvalidCommandSetMessage);
       
   457 			}
       
   458 		// Exit on a key press from user
       
   459 		console->Printf(KTEFEnterKeyMessage);
       
   460 		console->Getch();
       
   461 		}
       
   462 	else
       
   463 		{
       
   464 		// Create a Interface class object for generating HTML & XML logs
       
   465 		CTestExecuteLogger *tefLogger = new(ELeave) CTestExecuteLogger();
       
   466 		CleanupStack::PushL(tefLogger);
       
   467 
       
   468 		TInt logMode;
       
   469 		TInt logLevel;
       
   470 		TInt remotePanicDetection;
       
   471 		TBuf<KMaxTestExecuteNameLength> iniSysDrive;
       
   472 
       
   473 		if (parseTestExecuteIni != NULL)
       
   474 			{
       
   475 			// Parse ini for retrieving logging options set through ini
       
   476 			parseTestExecuteIni->GetKeyValueFromIni(KTEFLogMode, logMode);
       
   477 			parseTestExecuteIni->GetKeyValueFromIni(KTEFLogSeverityKey, logLevel);
       
   478 			parseTestExecuteIni->GetKeyValueFromIni(KTEFRemotePanicDetection, remotePanicDetection);
       
   479 			parseTestExecuteIni->GetKeyValueFromIni(KTEFDefaultSysDrive, iniSysDrive);
       
   480 			parseTestExecuteIni->GetKeyValueFromIni(KTEFWaitForLoggingTime, waitForLoggingTime);
       
   481 			parseTestExecuteIni->GetKeyValueFromIni(KTEFHtmlKey, htmlLogPath);
       
   482 			}
       
   483 		else
       
   484 			{
       
   485 			// Set default values for logging options if parser is not functioning
       
   486 			logMode = TLoggerOptions(ELogHTMLOnly);
       
   487 			logLevel = RFileFlogger::TLogSeverity(ESevrAll);
       
   488 			remotePanicDetection = 0;
       
   489 			iniSysDrive.Copy(KTEFIniSysDrive);
       
   490 			waitForLoggingTime = 5;
       
   491 			htmlLogPath.Copy(KTestExecuteLogPath);
       
   492 			htmlLogPath.Replace(0, 2, defaultSysDrive);
       
   493 			}
       
   494 		
       
   495 		tefLogger->SetLoggerOptions(logMode);
       
   496 		if(pipe)
       
   497 			{
       
   498 			tefLogger->SetPipeName(pipeName) ; 
       
   499 			}
       
   500 		
       
   501 		// Initialise the logging passing in the script file path & log level to the interface
       
   502 		tefLogger->InitialiseLoggingL(scriptFilePath, separateLogFiles, logLevel);
       
   503 
       
   504 		// Check to see if defaultsysdrive key is set in testexecute.ini
       
   505 		// if set to SYSDRIVE, assign the default system drive obtained from the plugin
       
   506 		// else, if a true value is set in testexecute.ini, use it as system drive for all test artifacts
       
   507 		if (iniSysDrive.Length() == 2 && iniSysDrive.Right(1).Compare(KTEFColon) == 0)
       
   508 			testSysDrive.Copy(iniSysDrive);
       
   509 		else if (iniSysDrive.CompareF(KTEFIniSysDrive) == 0)
       
   510 			testSysDrive.Copy(defaultSysDrive);
       
   511 
       
   512 
       
   513 		// Pass the first command line argument to the script master
       
   514 		// which is always the command script
       
   515 		CScriptMaster* scriptMaster = new (ELeave) CScriptMaster(scriptFilePath,*tefLogger, consoleLogger, defaultSysDrive, testSysDrive, selTestingOptions);
       
   516 		// To kick the state machine of the script master off -
       
   517 		// Call the kick method which jumps us into the RunL() of the CScriptMaster class
       
   518 		// CScriptMaster is the top AO in the hierarchy.
       
   519 		scriptMaster->Kick();
       
   520 
       
   521 		// Construct and Install a test watcher object for capturing remote panics during test execution
       
   522 		CTestWatcher* testWatcher = NULL;
       
   523 		if (remotePanicDetection != 0)
       
   524 			{
       
   525 			testWatcher = CTestWatcher::NewL();
       
   526 			testWatcher->StartL();
       
   527 			}
       
   528 
       
   529 		// Enter the Active Scheduler
       
   530 		aScheduler->Start();
       
   531 		
       
   532 		// Cleanup
       
   533 		delete scriptMaster;
       
   534 		
       
   535 		TInt commentedCommandsCnt=CScriptControl::commentedCommandsCount;
       
   536 		if(commentedCommandsCnt==-1)
       
   537 			{
       
   538 			CScriptControl::commentedCommandsCount=0;
       
   539 			//If the path specified fails check out for path from testexecute.ini
       
   540 			if(ret!=KErrNotFound)
       
   541 				{
       
   542 				//To get scriptFile name  i.e get sampleFile.script
       
   543 				TInt posOfLastSlash=scriptFilePath.LocateReverse('\\') ;
       
   544 				scriptFilePath.Set(scriptFilePath.Mid(posOfLastSlash+1));
       
   545 				TBuf<KBuffSize> tempStore(scriptFilePath);
       
   546 				if (parseTestExecuteIni != NULL)
       
   547 					{
       
   548 					TBuf<KMaxTestExecuteNameLength> tempBuffer;
       
   549 					parseTestExecuteIni->GetKeyValueFromIni(KTEFDefaultScriptPath, tempBuffer);
       
   550 					if (tempBuffer.CompareF(KNull) != 0)
       
   551 						{
       
   552 						scriptFilePath.Set(tempBuffer);
       
   553 						TBuf<KBuffSize> tempStoreScriptPath(scriptFilePath);
       
   554 						tempStoreScriptPath.Append(tempStore);
       
   555 						scriptFilePath.Set(tempStoreScriptPath);
       
   556 						TBuf<KMaxTestExecuteNameLength> scriptFileLocation(scriptFilePath);
       
   557 						CScriptMaster* scriptMaster = new (ELeave) CScriptMaster(scriptFilePath,*tefLogger, consoleLogger, defaultSysDrive, testSysDrive, selTestingOptions);
       
   558 						// To kick the state machine of the script master off -
       
   559 						// Call the kick method which jumps us into the RunL() of the CScriptMaster class
       
   560 						// CScriptMaster is the top AO in the hierarchy.
       
   561 						scriptMaster->Kick();
       
   562 						// Enter the Active Scheduler
       
   563 						aScheduler->Start();
       
   564 						
       
   565 						commentedCommandsCnt=CScriptControl::commentedCommandsCount;
       
   566 						if(commentedCommandsCnt==-1)
       
   567 							{
       
   568 							CScriptControl::commentedCommandsCount=0;
       
   569 							}
       
   570 							
       
   571 						// Cleanup
       
   572 						delete scriptMaster;
       
   573 						}
       
   574 					}
       
   575 				}
       
   576 			}
       
   577 		delete selTestingOptions;
       
   578 		
       
   579 		TInt commandsCount = CScriptControl::commentedCommandsCount;
       
   580 		TInt countOfRemotePanics = 0;
       
   581 
       
   582 		// Stop and Process the test watcher object for extracting panic informations and print them to the log files
       
   583 		if (remotePanicDetection != 0)
       
   584 			{
       
   585 			testWatcher->Stop();
       
   586 			countOfRemotePanics = testWatcher->iSharedData->iPanicDetails.Count();
       
   587 			if (countOfRemotePanics > 0)
       
   588 				{
       
   589 				tefLogger->LogExtra((TText8*)__FILE__,__LINE__,ESevrErr,
       
   590 					_L("The panic detection thread detected %d panics:"), countOfRemotePanics);
       
   591 				for (TInt count = 0; count < countOfRemotePanics; count++)
       
   592 					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);
       
   593 				}
       
   594 			delete testWatcher;
       
   595 			}
       
   596 
       
   597 		// Call the Termination routine for logging within the interface
       
   598 		tefLogger->TerminateLoggingL(commandsCount, countOfRemotePanics, CScriptControl::iRunScriptFailCount);
       
   599 		CleanupStack::Pop(tefLogger);
       
   600 		delete tefLogger;
       
   601 		}
       
   602 	if(includeSelectiveCases || excludeSelectiveCases)
       
   603 		{	
       
   604 		CleanupStack::PopAndDestroy(selTestCfgFileData);
       
   605 		selTestCfgFileData = NULL;
       
   606 		}
       
   607 	// Close the parser instance if it is active
       
   608 	CleanupStack::PopAndDestroy(console);
       
   609 	if (parseTestExecuteIni != NULL)
       
   610 		{
       
   611 		CleanupStack::PopAndDestroy(parseTestExecuteIni);
       
   612 		}
       
   613 
       
   614 	if (scriptFilePath.CompareF(KNull)!=0)
       
   615 		{
       
   616 		// Wait for flogger to write to file
       
   617 		_LIT(KHtmExtension,".htm");
       
   618 		TParse fileNameParse;
       
   619 		fileNameParse.Set(scriptFilePath, NULL, NULL);
       
   620 		
       
   621 		TPtrC fileName = fileNameParse.Name();
       
   622 		htmlLogPath.Append(fileName);
       
   623 		htmlLogPath.Append(KHtmExtension);
       
   624 
       
   625 	#ifdef _DEBUG
       
   626 		RDebug::Print(_L("Log file path--> %S"), &htmlLogPath);
       
   627 	#endif
       
   628 		RFs fs;
       
   629 		fs.Connect();
       
   630 		TBool answer = EFalse;
       
   631 		while(ETrue)
       
   632 			{
       
   633 			TInt err = fs.IsFileOpen(htmlLogPath, answer);
       
   634 			if ((KErrNone==err&&!answer) || KErrNotFound==err || KErrPathNotFound==err) 
       
   635 				{
       
   636 				break;
       
   637 				}
       
   638 			User::After(100000);
       
   639 			}
       
   640 		
       
   641 		if (waitForLoggingTime > 0)
       
   642 			{
       
   643 			User::After(waitForLoggingTime*1000000);
       
   644 			}
       
   645 		}
       
   646 	}
       
   647 
       
   648 /**
       
   649  * Top level function inside the TRAP harness
       
   650  * TEF system calls for:
       
   651  *		Active scheduler initialisation
       
   652  *		Command line read and parse
       
   653  *		Console creation
       
   654  *		Logging Initialisation
       
   655  *		Entry to script engine
       
   656  *		Logging termination
       
   657  * @param aSysDrive - Default system drive letter to be used for all script parsing
       
   658  */
       
   659 LOCAL_C void MainL(const TDriveName aSysDrive)
       
   660 	{
       
   661 #if (defined __DATA_CAGING__)
       
   662 	// Platform security hooks
       
   663 	RProcess().DataCaging(RProcess::EDataCagingOn);
       
   664 	RProcess().SecureApi(RProcess::ESecureApiOn);
       
   665 #endif
       
   666 	CActiveScheduler* sched = new (ELeave) CActiveScheduler();
       
   667 	CleanupStack::PushL(sched);
       
   668 	CActiveScheduler::Install(sched);
       
   669 
       
   670 	// Call up the subroutine to perform pre-processing tasks and to start test execution
       
   671 	ProcessMainL(sched, aSysDrive);
       
   672 
       
   673 	// Cleanup the scheduler object
       
   674 	CleanupStack::PopAndDestroy(sched);
       
   675 	}
       
   676 
       
   677 #if !(defined TEF_LITE)
       
   678 LOCAL_C void StartSystemL()
       
   679 	{
       
   680 	CActiveScheduler* theScheduler = new (ELeave) CActiveScheduler();
       
   681 	CleanupStack::PushL(theScheduler);
       
   682 	CActiveScheduler::Install(theScheduler);
       
   683 	
       
   684 	RLibrary pluginLibrary;
       
   685 	CWrapperUtilsPlugin* plugin = TEFUtils::WrapperPluginNew(pluginLibrary);
       
   686 	
       
   687 	if (plugin!=NULL)
       
   688 		{
       
   689 		plugin->WaitForSystemStartL();
       
   690 		delete plugin;
       
   691 		pluginLibrary.Close();
       
   692 		}
       
   693 	else
       
   694 		{
       
   695 		User::Leave(KErrGeneral);
       
   696 		}
       
   697 	
       
   698 	CleanupStack::PopAndDestroy(theScheduler);
       
   699 	}
       
   700 #endif
       
   701 
       
   702 /**
       
   703  * Executable Entry Point
       
   704  * Top level always creates TRAP harness.
       
   705  * Calls MainL() inside the TRAP harness
       
   706  */
       
   707 GLDEF_C TInt E32Main()
       
   708 	{
       
   709 	__UHEAP_MARK;
       
   710 	CTrapCleanup* cleanup = CTrapCleanup::New();
       
   711 	if(cleanup == NULL)
       
   712 		{
       
   713 		return KErrNoMemory;
       
   714 		}
       
   715 
       
   716   // Fix PDEF124952, set the priority EPriorityAbsoluteHigh. In this case, the timeout will 
       
   717   // take effect even if the server executes with almost 100% CPU usage.
       
   718   RThread().SetPriority(EPriorityAbsoluteHigh);
       
   719   // End PDEF124952
       
   720   
       
   721 	// Check to see if the plugin wrapper around the GetSystemDrive is loadable
       
   722 	// If yes, then instantiate the wrapper object and obtain the default system drive
       
   723 	// Else, use the hardcoded default drive as c:
       
   724 	TDriveName defaultSysDrive(KTEFLegacySysDrive);	
       
   725 	
       
   726 	RLibrary pluginLibrary;
       
   727 	CWrapperUtilsPlugin* plugin = TEFUtils::WrapperPluginNew(pluginLibrary);
       
   728 	
       
   729 	if (plugin!=NULL)
       
   730 		{
       
   731 		TDriveUnit driveUnit(plugin->GetSystemDrive());
       
   732 		defaultSysDrive.Copy(driveUnit.Name());
       
   733 		delete plugin;
       
   734 		pluginLibrary.Close();
       
   735 		}
       
   736 	
       
   737 	TBool enableSysStart = ETrue;
       
   738 	CTestExecuteIniData* iniData = NULL;
       
   739 	TRAPD(err, iniData = CTestExecuteIniData::NewL(defaultSysDrive));
       
   740 	if (err == KErrNone)
       
   741 		{
       
   742 		// Extract all the key values within the object
       
   743 		iniData->ExtractValuesFromIni();
       
   744 		iniData->GetKeyValueFromIni(KTEFSystemStarter, enableSysStart);
       
   745 		}
       
   746 
       
   747 	err = KErrNone;
       
   748 	#if !(defined TEF_LITE)
       
   749 	if (enableSysStart)
       
   750 		{
       
   751 		TRAP(err, StartSystemL());
       
   752 		__ASSERT_ALWAYS(!err, User::Panic(KTestExecuteName,err));
       
   753 		}
       
   754 	#endif
       
   755 	if (iniData != NULL)
       
   756 		{
       
   757 		delete iniData;
       
   758 		}	
       
   759 	
       
   760 	err = KErrNone;
       
   761 	TRAP(err,MainL(defaultSysDrive));
       
   762 	__ASSERT_ALWAYS(!err, User::Panic(KTestExecuteName,err));
       
   763 	delete cleanup;
       
   764 	__UHEAP_MARKEND;
       
   765 	return KErrNone;
       
   766     }
       
   767