testexecfw/stf/stfext/testmodules/teftestmod/teftestmodulefw/teftestmodule/src/scriptengine.cpp
changeset 2 8bb370ba6d1d
equal deleted inserted replaced
1:bbd31066657e 2:8bb370ba6d1d
       
     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 * Design Overview:
       
    16 * The diagram below shows the Script Engine classes and their parent child
       
    17 * hierarchy. All classes have a CActive base, and apart from CTaskTimer, all classes
       
    18 * have their own state machine. Apart from CScriptMaster, all classes have a reference
       
    19 * to a Mixin/Interface completion call of its parent, which it calls when the object
       
    20 * needs to notify the parent of an event.
       
    21 * CScriptMaster (derived CActive)
       
    22 * CScriptControl (derived CActiveBase - Can go recursive)
       
    23 * CProgramControl (derived CTaskControlBase) CClientControl ( derived CTaskControlBase maps to n x test steps)
       
    24 * CTaskTimer                                 CTaskTimer (derived CTimer)
       
    25 *  state transition tables for CScriptMaster, CScriptControl & CClientControl
       
    26 * CActiveBase:
       
    27 * Derives CActive.
       
    28 * Contains code for priming, triggering and completing AO's
       
    29 * Implements the pure abstract MChildCompletion::ChildCompletion() method
       
    30 * CTaskControlBase:
       
    31 * Derives CActiveBase.
       
    32 * Abstract class. Base for CClientControl and CProgramControl.
       
    33 * CScriptMaster:
       
    34 * Derives CActiveBase.
       
    35 * Master control active object with simple state machine.
       
    36 * Instantiates the top level CScriptControl object and triggers its state machine.
       
    37 * CScriptContol:
       
    38 * Derives CActiveBase.
       
    39 * Main script interpreter state machine. Creates one or more CClientControl and/or
       
    40 * CProgramControl objects.
       
    41 * In CONCURRENT mode, it can create as many instances as there are RUN_TEST_STEP and/or 
       
    42 * RUN_PROGRAM calls.
       
    43 * Creates root sessions with the xxxtest servers using the RTestServ::Connect() client call.
       
    44 * In the case of non-nested scripts, the parent object is CScriptMaster.
       
    45 * When scripts are nested and it goes recursive, the parent object could be another 
       
    46 * CScriptControl.
       
    47 * Implements the MTaskCompletion pure abstract class for callbacks from
       
    48 * CClientControl or CProgramControl objects
       
    49 * Calls back into its parent object when the script is complete and all async commands have
       
    50 * completed.
       
    51 * CClientControl:
       
    52 * Derives CTaskControlBase.
       
    53 * Test Step Controler. Instantiated by CScriptControl when a RUN_TEST_STEP line is interpreted
       
    54 * Creates and kicks off a CTaskTimer object set to the timeout value for the test step.
       
    55 * Opens a test step using the RTestSession::Open() client call.
       
    56 * Executes a test step using the RTestSession::RunTestStep() client call.
       
    57 * This method issues the client RTestSession::AbortTestStep() call and
       
    58 * the RunL() state machine handles the completion from the test server.
       
    59 * Implements the MTaskTimerCompletion pure abstract class for callbacks from the
       
    60 * CTaskTimer class.
       
    61 * Calls back into its parent CScriptControl object when a test step completes.
       
    62 * CProgramControl
       
    63 * Derives CTaskControlBase
       
    64 * Kicks off an executable in its own process and handles process completion asynchronously
       
    65 * CTaskTimer:
       
    66 * Derives CTimer.
       
    67 * Calls back into its parent object if the timer expires.
       
    68 * EPOC include
       
    69 *
       
    70 */
       
    71 
       
    72 
       
    73 
       
    74 /**
       
    75  @file scriptengine.cpp
       
    76 */
       
    77 
       
    78 //#include <utf.h>
       
    79 #if !(defined TEF_LITE)
       
    80 #include <apacmdln.h>
       
    81 #include <apgtask.h>
       
    82 #endif
       
    83 
       
    84 // User include
       
    85 #include <test/testexecuteclient.h>
       
    86 #include "scriptengine.h"
       
    87 
       
    88 // Fix defect 119337, initialize the integer to zero
       
    89 GLDEF_D TInt CScriptControl::iNestedNumRunScriptInLoop=0;
       
    90 // End defect 119337
       
    91 
       
    92 /**
       
    93  * @param aPtrC1 - Instance of TPtrC to compare
       
    94  * @param aPtrC2 - Instance of TPtrC to compare
       
    95  * Function to implement the comparison algo for RArray::Find to work with
       
    96  */
       
    97 TBool TSelectiveTestingOptions::CompareTPtrC(const TPtrC& aPtrC1, const TPtrC& aPtrC2)
       
    98 	{
       
    99 	TInt ret =aPtrC1.CompareF(aPtrC2);
       
   100 	return (ret==0) ? ETrue : EFalse;
       
   101 	} 
       
   102 
       
   103 /**
       
   104  * @param aRng1 - Instance of TRange to compare
       
   105  * @param aRng2 - Instance of TRange to compare
       
   106  * Function to implement the comparison algo for RArray::Find to work with.
       
   107  * TRange::iStartTestCase determines the match
       
   108  */
       
   109 TBool TRange::CompareTRangeStartCase(const TRange& aRng1, const TRange& aRng2) 
       
   110 	{
       
   111 	TInt ret =aRng2.iStartTestCase.CompareF(aRng1.iStartTestCase);
       
   112 	return (ret==0) ? ETrue : EFalse;
       
   113 	}
       
   114 
       
   115 /**
       
   116  * @param aRng1 - Instance of TRange to compare
       
   117  * @param aRng2 - Instance of TRange to compare
       
   118  * Function to implement the comparison algo for RArray::Find to work with.
       
   119  * TRange::iEndTestCase determines the match
       
   120  */
       
   121 TBool TRange::CompareTRangeEnd(const TRange& aRng1, const TRange& aRng2) 
       
   122 	{
       
   123 	TInt ret =aRng2.iEndTestCase.CompareF(aRng1.iEndTestCase);
       
   124 	return (ret==0) ? ETrue : EFalse;  
       
   125 	}
       
   126 
       
   127 /**
       
   128  * @param aRng1 - Instance of TRange to compare
       
   129  * @param aRng2 - Instance of TRange to compare
       
   130  * Function to implement the comparison algo for RArray::Sort to work with.
       
   131  * TRange::iStartTestCase is used as the sort key
       
   132  */
       
   133 TInt TRange::CompareTRangeStartOrder(const TRange& aRng1, const TRange& aRng2) 
       
   134 	{
       
   135 	return aRng1.iStartTestCase.CompareF( aRng2.iStartTestCase);
       
   136 	}
       
   137 
       
   138 /**
       
   139  * @param aPtrC1 - Instance of TPtrC to compare
       
   140  * @param aPtrC2 - Instance of TPtrC to compare
       
   141  * Function to implement the comparison algo for RArray::Sort to work with.
       
   142  */
       
   143 TInt TSelectiveTestingOptions::CompareTPtrCOrder(const TPtrC& aPtrC1, const TPtrC& aPtrC2) 
       
   144 	{
       
   145 	return aPtrC1.CompareF(aPtrC2);
       
   146 	}
       
   147 
       
   148 /**
       
   149  * @param aServ - Instance of the test server handle
       
   150  * @param aStepName - Test step name
       
   151  * Wrapper around the RTestServ class. Performs counting on test step sessions
       
   152  */
       
   153 TInt RScriptTestSession::Open(RScriptTestServ& aServ, const TBool aIsTestStep, const TDesC& aStepName )
       
   154 	{
       
   155 	if(aServ.SharedData() && aServ.SessionCount())
       
   156 			return KErrInUse;
       
   157 	TInt ret = KErrNone;
       
   158 	
       
   159 	if( aIsTestStep )
       
   160 		{
       
   161 		ret = RTestSession::Open(aServ, aStepName, aServ.SharedData());
       
   162 		}
       
   163 	else
       
   164 		{
       
   165 		ret = RTestSession::Open(aServ, aServ.SharedData());
       
   166 		}
       
   167 	if(ret)
       
   168 		return ret;
       
   169 	aServ.AddSession();
       
   170 	iServ = &aServ;
       
   171 	return KErrNone;
       
   172 	}
       
   173 	
       
   174 /**
       
   175  * @param aScriptFilePath - The full path and filename of a script command file.
       
   176  * @param aLogger - Reference to a logger interface object that contains HTML & XML log client sessions.
       
   177  * @param aConsole - Reference to console object for printing script line during test execution
       
   178  * @param aSysDrive - Default System drive letter
       
   179  * @param aTestSysDrive - Default System drive letter overwritten through testexecute.ini
       
   180  * Constructor
       
   181  */
       
   182 CScriptMaster::CScriptMaster(const TDesC& aScriptFilePath, CTestExecuteLogger& aLogger, RConsoleLogger& aConsole, const TDriveName& aSysDrive, const TDriveName& aTestSysDrive, TSelectiveTestingOptions* aSelTestingOptions ) :
       
   183 	iState(EInit), iScriptFilePath(aScriptFilePath), iLogger(aLogger), iConsoleLogger(aConsole), iDefaultSysDrive(aSysDrive), iTestSysDrive(aTestSysDrive), iSelTestingOptions(aSelTestingOptions)
       
   184 	{
       
   185 	}
       
   186 
       
   187 /**
       
   188  * Destructor
       
   189  */
       
   190 CScriptMaster::~CScriptMaster()
       
   191 	{
       
   192 	}
       
   193 
       
   194 /**
       
   195  * Pure virtual implementation.
       
   196  * The Top level state machine Kick'd() into by MainL()
       
   197  * Picks up the completion from a CScriptControl instance then exits the scheduler
       
   198  */
       
   199 void CScriptMaster::RunL()
       
   200 	{
       
   201 	switch (iState)
       
   202 		{
       
   203 	case EInit	:
       
   204 		{
       
   205 		// Create the master CScriptControl instance. 
       
   206 		CScriptControl* scriptControl = new (ELeave) CScriptControl(*this,iScriptFilePath,Logger(),ConsoleLogger(),iStartLooping,iLoop,iDefaultSysDrive,iTestSysDrive,iSelTestingOptions);
       
   207 		iState = ERunning;
       
   208 		// Set our AO up ready for completion
       
   209 		Prime();
       
   210 		// Kick the CScriptControl state machine
       
   211 		scriptControl->Kick();
       
   212 		}
       
   213 		break;
       
   214 	case ERunning	:
       
   215 		{
       
   216 		// All child AO's have completed and been deleted so it's safe to exit.
       
   217 		CActiveScheduler::Stop();
       
   218 		}
       
   219 		break;
       
   220 	default:
       
   221 		break;
       
   222 		}
       
   223 	}
       
   224 
       
   225 /**
       
   226  * @param aCompletion - Callback into the parent object.
       
   227  * @param aScriptFilePath - The full path and filename of a script file
       
   228  * @param aLogger - Reference to a logger instance
       
   229  * @param aConsole - Reference to console object for printing script line during test execution
       
   230  * @param aStartLooping - Initiate the looping
       
   231  * @param aLoop - Check for nesting of loops
       
   232  * @param aSysDrive - Default System drive letter
       
   233  * @param aTestSysDrive - System drive letter overwritten from testexecute.ini
       
   234  * Constructor
       
   235  */
       
   236 CScriptControl::CScriptControl(MChildCompletion& aCompletion, const TDesC& aScriptFilePath, CTestExecuteLogger& aLogger, RConsoleLogger& aConsole, TBool aStartLooping, TBool aLoop, const TDriveName& aSysDrive, const TDriveName& aTestSysDrive, TSelectiveTestingOptions* aSelTestingOptions):
       
   237 	iScriptFile(aScriptFilePath),
       
   238 	iState(EInit),
       
   239 	iParent(aCompletion),
       
   240 	iConcurrent(EFalse),
       
   241 	iCanComplete(ETrue),
       
   242 	iBreakOnError(EFalse),
       
   243 	iAsyncTasksOutstanding(0),
       
   244 	iCurrentScriptLineNumber(0),
       
   245 	iLogger(aLogger),
       
   246 	iConsoleLogger(aConsole),
       
   247 	iScriptLinePrefixSet(EFalse),
       
   248 	iStartLooping(aStartLooping),
       
   249 	iLoop(aLoop),
       
   250 	iSharedDataNum(KTEFZeroValue),
       
   251 	iIsSharedData(EFalse),
       
   252 	iSyncControl(NULL),
       
   253 	iTestCaseID(KTEFTestCaseDefault),
       
   254 	iDefaultSysDrive(aSysDrive),
       
   255 	iTestSysDrive(aTestSysDrive),
       
   256 	iSelTestingOptions(aSelTestingOptions),
       
   257 	iSelectOne(EFalse),
       
   258 	iRangeRefCounter(0),
       
   259 	iTestCaseCounter(0)
       
   260 	{
       
   261 	}
       
   262 
       
   263 /**
       
   264  * Destructor
       
   265  */
       
   266 CScriptControl::~CScriptControl()
       
   267 	{
       
   268 	iTimer.Cancel();
       
   269 	iTimer.Close();
       
   270 	// We read the complete script into the heap for parsing so:
       
   271 	delete iScriptData;
       
   272 	for (TInt index = 0; index < iSharedDataNum; index++)
       
   273 		{
       
   274 		delete iSharedDataArray[index];
       
   275 		}
       
   276 	// Instance has an array of pointers to RTestServer objects.
       
   277 	// Loop through deleting and closing
       
   278 	TInt i = 0;
       
   279 	TInt count = iServers.Count();
       
   280 	for(i=0;i<count;i++)
       
   281 		{
       
   282 		iServers[0]->Close();
       
   283 		delete iServers[0];
       
   284 		iServers.Remove(0);
       
   285 		}
       
   286 	iServers.Close();
       
   287 	if( iSyncControl )
       
   288 		{
       
   289 		delete iSyncControl;
       
   290 		}
       
   291 	}
       
   292 
       
   293 /**
       
   294  * @param aError - Integer error value returned by the active object while leaving
       
   295  * @return TInt - System-wide error codes
       
   296  * Error Handler for active object
       
   297  */
       
   298 TInt CScriptControl::RunError(TInt aError)
       
   299 	{
       
   300 	if (aError == KErrNoMemory)
       
   301 		{
       
   302 		ERR_PRINTF1(_L("Insufficient memory available to perform further operation.\n\tPlease increase the maximum heap size from the testexecute.mmp and try running the test again. Exiting test script..."));
       
   303 		}
       
   304 	else
       
   305 		{
       
   306 		ERR_PRINTF2(_L("Test execution failed with error %d. Terminating tests.."), aError);
       
   307 		}
       
   308 	iParent.ChildCompletion(KErrNone);
       
   309 	delete this;
       
   310 	return KErrNone;
       
   311 	}
       
   312 
       
   313 /**
       
   314  * Implementation of pure virtual
       
   315  * The main script interpreter state machine.
       
   316  * Kick'd() into by CScriptMaster or, in the case of nested scripts, another CScriptControl
       
   317  * instance.
       
   318  * Picks up the completions from CClientControls and/or, in the case of nested scripts,
       
   319  * another CScriptControl instance.
       
   320  */
       
   321 void CScriptControl::RunL()
       
   322 	{
       
   323 	switch (iState)
       
   324 		{
       
   325 	case EInit		:
       
   326 		// First state after Kick() from parent
       
   327 		{
       
   328 		// Standard log output goes to flogger
       
   329 		// Result log goes to a propietary file in c:\logs\testexecute
       
   330 		User::LeaveIfError(iTimer.CreateLocal());
       
   331 		TRAPD(err,CreateScriptDataFromScriptFileL());
       
   332 		if(err)
       
   333 			{
       
   334 			// If we can't open the script file then log the fact and gracefully exit
       
   335 			// the state machine.
       
   336 			TBuf<KMaxTestExecuteCommandLength> buf(iScriptFile);
       
   337 			_LIT(KScriptFileError,"Failed Script File Open %S");
       
   338 			ERR_PRINTF2(KScriptFileError,&buf);
       
   339 			iState = EClosing;
       
   340 			//condition used for checking failure in testexecute.cpp
       
   341 			commentedCommandsCount=-1;
       
   342 			iRunScriptFailCount++;
       
   343 			Kick();
       
   344 			break;
       
   345 			}
       
   346 
       
   347 		// Script file reading state next
       
   348 		iState = ERunning;
       
   349 		// Kick ourselves into the next state
       
   350 		Kick();
       
   351 		}
       
   352 		break;
       
   353 
       
   354 	case ERunning	:
       
   355 		// Always in this state whilst we're reading lines from script file data member
       
   356 		{
       
   357 		TPtrC scriptLine;
       
   358 		if(!iStartLooping)
       
   359 			{
       
   360 			if(!GetNextScriptLine(scriptLine))
       
   361 				{
       
   362 				// End of the script file
       
   363 				// Check see if there are any async requests outstanding
       
   364 				// In concurrent mode there are very likely to be
       
   365 				if(iAsyncTasksOutstanding == 0)
       
   366 					{
       
   367 					// No requests outstanding so call into the parent
       
   368 					iParent.ChildCompletion(KErrNone);
       
   369 					delete this;
       
   370 					}
       
   371 				else
       
   372 					{
       
   373 					// Requests outstanding
       
   374 					// Next time we're completed we'll be in the closing state
       
   375 					iState = EClosing;
       
   376 					iCanComplete =ETrue;
       
   377 					// Prime ourselves for completion
       
   378 					Prime();
       
   379 					}
       
   380 				break;
       
   381 				}
       
   382 			}
       
   383 		//Get the script lines which are to be looped
       
   384 		else if(!GetLoopScriptLine(scriptLine))
       
   385 			{
       
   386 			// End of the script file
       
   387 			// Check see if there are any async requests outstanding
       
   388 			// In concurrent mode there are very likely to be
       
   389 			if(iAsyncTasksOutstanding == 0)
       
   390 				{
       
   391 				// No requests outstanding so call into the parent
       
   392 				iParent.ChildCompletion(KErrNone);
       
   393 				delete this;
       
   394 				}
       
   395 			else
       
   396 				{
       
   397 				// Requests outstanding
       
   398 				// Next time we're completed we'll be in the closing state
       
   399 				iState = EClosing;
       
   400 				iCanComplete =ETrue;
       
   401 				// Prime ourselves for completion
       
   402 				Prime();
       
   403 				}
       
   404 			break;
       
   405 			}
       
   406 
       
   407 		iCurrentScriptLine.Set(scriptLine);
       
   408 		
       
   409 		TBool commentedCommand = CheckCommentedCommands();
       
   410 		if(commentedCommand)
       
   411 			{
       
   412 			iCanComplete = EFalse;
       
   413 			Kick();
       
   414 			break;
       
   415 			}
       
   416 
       
   417 		if (iScriptLinePrefixSet )
       
   418 			{
       
   419 			TLex lookahead(iCurrentScriptLine);
       
   420 
       
   421 			TPtrC firstCommand(lookahead.NextToken());
       
   422 
       
   423 			if (firstCommand.CompareF(KTEFRemovePrefixCommand) != 0)
       
   424 				{
       
   425 				// If we aren't the Remove_Prefix command, prefix the current line...
       
   426 				iPrefixedCurrentScriptLine = iScriptLinePrefix;
       
   427 				iPrefixedCurrentScriptLine.Append(scriptLine);
       
   428 				iCurrentScriptLine.Set(iPrefixedCurrentScriptLine);
       
   429 				}
       
   430 			}
       
   431 
       
   432 		TRAPD(err, MakeAbsoluteFilePathsL(iCurrentScriptLine));
       
   433 		PrintCurrentScriptLine();
       
   434 		
       
   435 		TLex lex(iCurrentScriptLine);
       
   436 
       
   437 		TPtrC token(lex.NextToken());
       
   438 
       
   439 		if (err == KTEFErrInvalidRelPath)
       
   440 			{
       
   441 			_LIT(KTEFErrInvalidRelPathText,"Invalid relative path provided in the script file. Skipping the script line from execution..");
       
   442 			ERR_PRINTF1(KTEFErrInvalidRelPathText);
       
   443 
       
   444 			if (token.CompareF(KTEFRunTestStepCommand) == 0 ||
       
   445 				token.CompareF(KTEFRunPanicStepCommand) == 0 ||
       
   446 				token.CompareF(KTEFRunTestStepResultCommand) == 0 ||
       
   447 				token.CompareF(KTEFRunPanicStepResultCommand) == 0)
       
   448 				{
       
   449 				TExitCategoryName  blankPanicString; //Not a Panic
       
   450 				LogResult(EIgnore, blankPanicString, iCurrentScriptLineNumber, iCurrentScriptLine);
       
   451 				}
       
   452 			iCanComplete = EFalse;
       
   453 			Kick();
       
   454 			break;
       
   455 			}
       
   456 
       
   457 		if(err == KErrTooBig)
       
   458 			{
       
   459 			_LIT(KTEFErrTooBigArguments, "One or more arguments for the command exceeded allowed limit for length. Skipping test..");
       
   460 			ERR_PRINTF1(KTEFErrTooBigArguments);
       
   461 
       
   462 			if (token.CompareF(KTEFRunTestStepCommand) == 0 ||
       
   463 				token.CompareF(KTEFRunPanicStepCommand) == 0 ||
       
   464 				token.CompareF(KTEFRunTestStepResultCommand) == 0 ||
       
   465 				token.CompareF(KTEFRunPanicStepResultCommand) == 0)
       
   466 				{
       
   467 				TExitCategoryName  blankPanicString; //Not a Panic
       
   468 				LogResult(EIgnore, blankPanicString, iCurrentScriptLineNumber, iCurrentScriptLine);
       
   469 				}
       
   470 			iCanComplete = EFalse;
       
   471 			Kick();
       
   472 			break;
       
   473 			}
       
   474 
       
   475 		// Main parser
       
   476 		if(token.CompareF(KTEFLoadSuiteCommand) == 0 || token.CompareF(KTEFLoadServerCommand) == 0)
       
   477 			{
       
   478 			TRAPD(err,CreateServerFromScriptLineL());
       
   479 			
       
   480 			// Create a TLogField structure array
       
   481 			// Size of array equals to number of fields to be displayed for the command
       
   482 			TExtraLogField logField[2];
       
   483 
       
   484 			// The first member of the structure stores the field name
       
   485 			// The second one holds the value for the particular field
       
   486 			_LIT(KSuiteName, "SUITE_NAME");
       
   487 			logField[0].iLogFieldName.Copy(KSuiteName);
       
   488 			logField[0].iLogFieldValue.Copy(lex.NextToken());
       
   489 			
       
   490 			logField[1].iLogFieldName.Copy(KTEFResultString);
       
   491 			if(err != KErrNone)
       
   492 				{
       
   493 				logField[1].iLogFieldValue.Copy(KTEFResultFail);
       
   494 				if( KErrNotFound == err )
       
   495 					{
       
   496 					_LIT(KServerNotFound,"Failed to create server, either the server or one of its dependancies could not be found.");
       
   497 					ERR_PRINTF1(KServerNotFound);
       
   498 					}
       
   499 				else
       
   500 					{
       
   501 					_LIT(KServerCreateError,"Failed to Create Server Err = %d");
       
   502 					ERR_PRINTF2(KServerCreateError,err);
       
   503 					}
       
   504 				}
       
   505 			else
       
   506 				{
       
   507 				logField[1].iLogFieldValue.Copy(KTEFResultPass);
       
   508 				}
       
   509 			
       
   510 			// Call the Logger().LogToXml routine which handles XML logging for individual commands
       
   511 			// Takes in the command name, number of fields and the struture array
       
   512 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, token, 2, logField);
       
   513 			iCanComplete = EFalse;
       
   514 			Kick();
       
   515 			}
       
   516 		else if(token.CompareF(KTEFStartTestBlock)==0)
       
   517 			{
       
   518 			// Parse the START_TEST_BLOCK command line
       
   519 			TInt index = 0;
       
   520 			TBool taskCanComplete = ETrue;
       
   521 			TBool concurrent = iConcurrent;
       
   522 			// Make sure the server is loaded
       
   523 			if(!GetServerIndexFromScriptLine(index))
       
   524 				{
       
   525 				// Not loaded. Skip the line, but ensure its logged as a failure.
       
   526 				TExitCategoryName  blankPanicString; //Not a Panic
       
   527 				LogResult(EIgnore, blankPanicString, iCurrentScriptLineNumber, iCurrentScriptLine);
       
   528 
       
   529 				iCanComplete = EFalse;
       
   530 				Kick();
       
   531 				break;
       
   532 				}
       
   533 			
       
   534 			TBuf<KMaxTestExecuteCommandLength>	startBlockLine = iCurrentScriptLine;
       
   535 			
       
   536 			// Parse the test block of commands
       
   537 			TTEFItemArray* itemArray = new (ELeave) TTEFItemArray(1);
       
   538 			CleanupStack::PushL( itemArray );
       
   539 			TRAPD( err, ParseTestBlockL(*itemArray) );
       
   540 			
       
   541 			if( KErrNone == err )
       
   542 				{
       
   543 				if(!iConcurrent)
       
   544 					{
       
   545 					// If we're not in concurrent mode then child objects can complete us
       
   546 					taskCanComplete = ETrue;
       
   547 					// Prime ready for completion
       
   548 					Prime();
       
   549 					}
       
   550 				else
       
   551 					{
       
   552 					// In concurrent mode children can't complete us as we kick() ourselves.
       
   553 					taskCanComplete = EFalse;
       
   554 					Kick();
       
   555 					}
       
   556 				// Create the test block controler object
       
   557 				TInt loopIndex = -1;
       
   558 				if (iLoop)
       
   559 					{
       
   560 					loopIndex = iLoopCounter + 1;
       
   561 					}
       
   562 				
       
   563 				CClientControl* blockController = CClientControl::NewL(	*iServers[index],
       
   564 																		startBlockLine,
       
   565 																		*this,
       
   566 																		iCurrentScriptLineNumber,
       
   567 																		Logger(),
       
   568 																		loopIndex,
       
   569 																		iTestCaseID,
       
   570 																		iCurrentScriptLine,
       
   571 																		iScriptFile,
       
   572 																		*itemArray,
       
   573 																		iDefaultSysDrive,
       
   574 																		iTestSysDrive);
       
   575 
       
   576 				blockController->SetTaskComplete(taskCanComplete);
       
   577 				iAsyncTasksOutstanding++;
       
   578 				// Kick() the test step  object into its state machine
       
   579 				blockController->Kick();
       
   580 				}
       
   581 			else
       
   582 				{
       
   583 				iCanComplete = EFalse;
       
   584 				Kick();				
       
   585 				}
       
   586 
       
   587 			iConcurrent = concurrent;
       
   588 			CleanupStack::PopAndDestroy( itemArray );
       
   589 			}
       
   590 		else if(token.CompareF(KTEFEndTestBlock)==0)
       
   591 			{
       
   592 			// If this is called then there is a missing START_TEST_BLOCK command
       
   593 			TExitCategoryName  blankPanicString;
       
   594 			LogResult(EIgnore, blankPanicString, iCurrentScriptLineNumber, iCurrentScriptLine);
       
   595 			iCanComplete = EFalse;
       
   596 			Kick();
       
   597 			}
       
   598 		else if(token.CompareF(KTEFStartRepeat)==0)
       
   599 			{
       
   600 			TPtrC iniFile(lex.NextToken());
       
   601 			TPtrC iniSection(lex.NextToken());
       
   602 			TPtrC tempRepeatParam=lex.NextToken();
       
   603 			CIniData* configData = NULL;
       
   604 			TInt err = 0;
       
   605 			if(iniFile.Length())
       
   606 				{
       
   607 				TRAP(err,configData = CIniData::NewL(iniFile));
       
   608 				}
       
   609 			if(err != KErrNone)
       
   610 				{
       
   611 				_LIT(KTEFIniFileNotFound,"Ini file not found.. Looping Ignored");
       
   612 				ERR_PRINTF1(KTEFIniFileNotFound);
       
   613 				Kick();
       
   614 				break;
       
   615 				}
       
   616 			iRepeatParam=0;
       
   617 			CleanupStack::PushL(configData);
       
   618 			if(configData)
       
   619 				{
       
   620 				//For Syntax Error  continue ignoring looping
       
   621 				if (!configData->FindVar(iniSection, tempRepeatParam, iRepeatParam))
       
   622 					{
       
   623 					_LIT(KIniFailMessage,"The input data is not found in the ini specified");
       
   624 					INFO_PRINTF1(KIniFailMessage);
       
   625 					CleanupStack::PopAndDestroy(configData);
       
   626 					Kick();
       
   627 					break;
       
   628 					}
       
   629 				}
       
   630 				
       
   631 			CleanupStack::PopAndDestroy(configData);
       
   632 			TExtraLogField logField[1];
       
   633 			_LIT(KIterations,"ITERATIONS");
       
   634 			logField[0].iLogFieldName.Copy(KIterations);
       
   635 			logField[0].iLogFieldValue.Copy(KNull);
       
   636 			logField[0].iLogFieldValue.AppendNum(iRepeatParam);
       
   637 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, token, 1, logField);
       
   638 
       
   639 			if(tempRepeatParam.Compare(KNull)==0)
       
   640 				{
       
   641 				_LIT(KRepeatKeyNotFound,"Repeat Parameter Key Not Found");
       
   642 				INFO_PRINTF1(KRepeatKeyNotFound);
       
   643 				Kick();
       
   644 				break;
       
   645 				}
       
   646 			//Nesting of Control Logic is Not supported
       
   647 			if(iLoop)
       
   648 				{
       
   649 				_LIT(KNestingNotAllowed,"Nesting of START_REPEAT is not supported.. Looping Ignored");
       
   650 				WARN_PRINTF1(KNestingNotAllowed);
       
   651 				iLoop=EFalse;
       
   652 				Kick();
       
   653 				break;
       
   654 				}
       
   655 			//Looping is not to be started with Concurrent mode
       
   656 			if(iConcurrent)
       
   657 				{
       
   658 				_LIT(KConcurrentNotAllowed,"No concurrent Execution is Allowed in Looping");
       
   659 				INFO_PRINTF1(KConcurrentNotAllowed);
       
   660 				Kick();
       
   661 				break;
       
   662 				}
       
   663 				
       
   664 			iLoopCounter=0;
       
   665 			//For Invalid Parameter continue ignoring looping
       
   666 			if(iRepeatParam<1)
       
   667 				{
       
   668 				_LIT(KInvalidRepeatParam,"The repeat Parameter is invalid");
       
   669 				INFO_PRINTF1(KInvalidRepeatParam);
       
   670 				Kick();
       
   671 				break;
       
   672 				}
       
   673 			iLoop=ETrue;
       
   674 			iCheckVar=EFalse;
       
   675 			Kick();
       
   676 			}
       
   677 		else if(token.CompareF(KTEFEndRepeat)==0)
       
   678 			{
       
   679 			if(!iLoop)
       
   680 				{
       
   681 				_LIT(KLoopNotInitiated,"The Looping is Not Initiated");
       
   682 				INFO_PRINTF1(KLoopNotInitiated);
       
   683 				Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, token);
       
   684 				Kick();
       
   685 				break;
       
   686 				}
       
   687 				
       
   688 			iLoopCounter++;
       
   689 			if(iLoopCounter==iRepeatParam)
       
   690 				{
       
   691 				Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, token);
       
   692 				iStartLooping=EFalse;
       
   693 				iLoop=EFalse;
       
   694 				}
       
   695 			else
       
   696 				{
       
   697 				iStartLooping=ETrue;
       
   698 				//Looping needs to be started in CONSECUTIVE mode
       
   699 				if(iConcurrent)
       
   700 					{
       
   701 					iConcurrent=EFalse;
       
   702 					}
       
   703 				}
       
   704 			Kick();
       
   705 			}
       
   706 		else if(token.CompareF(KTEFRunTestStepCommand) == 0 ||
       
   707 				token.CompareF(KTEFRunPanicStepCommand) == 0 ||
       
   708 				token.CompareF(KTEFRunTestStepResultCommand) == 0 ||
       
   709 				token.CompareF(KTEFRunPanicStepResultCommand) == 0
       
   710 				)
       
   711 			{
       
   712 			if(!CheckValidScriptLine())
       
   713 				{
       
   714 				// Not a Valid Script Line
       
   715 
       
   716 				TExitCategoryName  blankPanicString; //Not a Panic
       
   717 				LogResult(EIgnore, blankPanicString, iCurrentScriptLineNumber, iCurrentScriptLine);
       
   718 				// End of defect 037066
       
   719 
       
   720 				iCanComplete = EFalse;
       
   721 				Kick();
       
   722 				break;
       
   723 				}
       
   724 			
       
   725 			TInt index;
       
   726 			TBool taskCanComplete = ETrue;
       
   727 			TBool concurrent = iConcurrent;
       
   728 			// Make sure the server is loaded
       
   729 			if(!GetServerIndexFromScriptLine(index))
       
   730 				{
       
   731 				// Not loaded. Skip the line, but ensure its logged as a failure.
       
   732 
       
   733 				// Start of defect 037066
       
   734 				TExitCategoryName  blankPanicString; //Not a Panic
       
   735 				LogResult(EIgnore, blankPanicString, iCurrentScriptLineNumber, iCurrentScriptLine);
       
   736 				// End of defect 037066
       
   737 
       
   738 				iCanComplete = EFalse;
       
   739 				Kick();
       
   740 				break;
       
   741 				}
       
   742 
       
   743 			if(!iConcurrent)
       
   744 				{
       
   745 				// If we're not in concurrent mode then child objects can complete us
       
   746 				taskCanComplete = ETrue;
       
   747 				// Prime ready for completion
       
   748 				Prime();
       
   749 				}
       
   750 			else
       
   751 				{
       
   752 				// In concurrent mode children can't complete us as we kick() ourselves.
       
   753 				taskCanComplete = EFalse;
       
   754 				Kick();
       
   755 				}
       
   756 			iConcurrent = concurrent;
       
   757 			// Create the test step controler object
       
   758 			TInt loopIndex = -1;
       
   759 			if (iLoop)
       
   760 				{
       
   761 				loopIndex = iLoopCounter + 1;
       
   762 				}
       
   763 			CClientControl* stepController = new (ELeave) CClientControl(*iServers[index],iCurrentScriptLine,*this,iCurrentScriptLineNumber,Logger(), loopIndex, iTestCaseID, iScriptFile, iDefaultSysDrive, iTestSysDrive);
       
   764 			stepController->SetTaskComplete(taskCanComplete);
       
   765 			iAsyncTasksOutstanding++;
       
   766 			// Kick() the test step  object into its state machine
       
   767 			stepController->Kick();
       
   768 			}
       
   769 		else if(token.CompareF(KTEFRunProgramCommand) == 0)
       
   770 			{
       
   771 			TBool taskCanComplete = ETrue;
       
   772 			if(!iConcurrent)
       
   773 				{
       
   774 				// If we're not in concurrent mode then child objects can complete us
       
   775 				taskCanComplete = ETrue;
       
   776 				// Prime ready for completion
       
   777 				Prime();
       
   778 				}
       
   779 			else
       
   780 				{
       
   781 				// In concurrent mode children can't complete us as we kick() ourselves.
       
   782 				taskCanComplete = EFalse;
       
   783 				Kick();
       
   784 				}
       
   785 			// Create the test step controller object
       
   786 			CProgramControl* programController = new (ELeave) CProgramControl(iCurrentScriptLine,*this,iCurrentScriptLineNumber,Logger());
       
   787 			programController->SetTaskComplete(taskCanComplete);
       
   788 			iAsyncTasksOutstanding++;
       
   789 			// Kick() the test step  object into its state machine
       
   790 			programController->Kick();
       
   791 			}
       
   792 		else if(token.CompareF(KTEFRunWSProgramCommand) == 0)
       
   793 			{
       
   794 			TBool taskCanComplete = ETrue;
       
   795 			if(!iConcurrent)
       
   796 				{
       
   797 				// If we're not in concurrent mode then child objects can complete us
       
   798 				taskCanComplete = ETrue;
       
   799 				// Prime ready for completion
       
   800 				Prime();
       
   801 				}
       
   802 			else
       
   803 				{
       
   804 				// In concurrent mode children can't complete us as we kick() ourselves.
       
   805 				taskCanComplete = EFalse;
       
   806 				Kick();
       
   807 				}
       
   808 			// Create the test step controller object
       
   809 			CProgramControl* programController = new (ELeave) CProgramControl(iCurrentScriptLine,*this,iCurrentScriptLineNumber,Logger(),ETrue);
       
   810 			iAsyncTasksOutstanding++;
       
   811 			programController->SetTaskComplete(taskCanComplete);
       
   812 			// Kick() the test step  object into its state machine
       
   813 			programController->Kick();
       
   814 			}
       
   815 		else if(token.CompareF(KTEFConcurrentCommand) == 0)
       
   816 			{
       
   817 			// Go into concurrent mode
       
   818 			// Whilst we're in concurrent mode we always kick() ourselves
       
   819 			// around the state engine
       
   820 				iConcurrent = ETrue;
       
   821 			// Call the Logger()'s LogToXml routine to handle XML logging
       
   822 			// Takes in just the command name without any field
       
   823 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, KTEFConcurrentCommand);
       
   824 			iCanComplete = EFalse;
       
   825 			Kick();
       
   826 			}
       
   827 		else if(token.CompareF(KTEFConsecutiveCommand) == 0)
       
   828 			{
       
   829 			// If we go into consecutive mode we have to make sure there are no
       
   830 			// requests outstanding.Set the state accordingly
       
   831 			iConcurrent = EFalse;
       
   832 
       
   833 			// Call the Logger()'s LogToXml routine to handle XML logging
       
   834 			// Takes in just the command name without any field
       
   835 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, KTEFConsecutiveCommand);
       
   836 			if(iAsyncTasksOutstanding)
       
   837 				{
       
   838 				iCanComplete = ETrue;
       
   839 				iState = EWaitCompletions;
       
   840 				Prime();
       
   841 				}
       
   842 			else
       
   843 				{
       
   844 				iCanComplete = EFalse;
       
   845 				iState = ERunning;
       
   846 				Kick();
       
   847 				}
       
   848 			}
       
   849 		else if(token.CompareF(KTEFRunUtilsCommand) == 0)
       
   850 			{
       
   851 			// All utils complete synchronously
       
   852 			TRAPD(err,RunUtilsFromScriptLineL());
       
   853 			
       
   854 			// Create a TLogField structure array
       
   855 			// Size of array equals to number of fields to be displayed for the command
       
   856 			TExtraLogField logField[2];
       
   857 
       
   858 			// The first member of the structure stores the field name
       
   859 			// The second one holds the value for the particular field
       
   860 			_LIT(KCommand,"COMMAND");
       
   861 			logField[0].iLogFieldName.Copy(KCommand);
       
   862 			logField[0].iLogFieldValue.Copy(lex.NextToken());
       
   863 			
       
   864 			logField[1].iLogFieldName.Copy(KTEFResultString);
       
   865 			if (err == KErrNone)
       
   866 				{
       
   867 				logField[1].iLogFieldValue.Copy(KTEFResultPass);
       
   868 				}
       
   869 			else
       
   870 				{
       
   871 				logField[1].iLogFieldValue.Copy(KTEFResultFail);
       
   872 				}
       
   873 
       
   874 			// Call the Logger().LogToXml routine which handles XML logging for individual commands
       
   875 			// Takes in the command name, number of fields and the struture array
       
   876 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, KTEFRunUtilsCommand, 2, logField);
       
   877 			
       
   878 			if(err != KErrNone)
       
   879 				{
       
   880 				_LIT(KRunUtilsError,"RUN_UTILS ret = %d");
       
   881 				INFO_PRINTF2(KRunUtilsError,err);
       
   882 				}
       
   883 			iCanComplete = EFalse;
       
   884 			Kick();
       
   885 			}
       
   886 		else if(token.CompareF(KTEFPrintCommand) == 0)
       
   887 			{
       
   888 			PrintFromScriptLine();
       
   889 			iCanComplete = EFalse;
       
   890 			Kick();
       
   891 			}
       
   892 		else if (token.CompareF(KTEFPrefixCommand) == 0)
       
   893 			{
       
   894 
       
   895 			if(iAsyncTasksOutstanding)
       
   896 				// Don't run Prefix until all outstanding requests have completed
       
   897 				{
       
   898 				iState = EPrefixPending;
       
   899 				iCanComplete = ETrue;
       
   900 				Prime();
       
   901 				}
       
   902 			else
       
   903 				{
       
   904 				// Ok to run PREFIX - Kick the stated machine so it's run next time in the RunL()
       
   905 				iState = ERunPrefix;
       
   906 				iCanComplete = EFalse;
       
   907 				Kick();
       
   908 				}
       
   909 
       
   910 			}
       
   911 		else if (token.CompareF(KTEFRemovePrefixCommand) == 0)
       
   912 			{
       
   913 			iScriptLinePrefixSet = EFalse;
       
   914 			iCanComplete = EFalse;
       
   915 			Kick();
       
   916 			}
       
   917 		else if (token.CompareF(KTEFStartTestCaseCommand) == 0) 
       
   918 			{
       
   919 			if(ProceedTestCase())
       
   920 				{	
       
   921 				LogTestCaseMarkerL();
       
   922 				iCanComplete = EFalse;
       
   923 				Kick();	
       
   924 				}
       
   925 			else
       
   926 				{
       
   927 				iState = ETestCaseIgnore;
       
   928 				iCanComplete = EFalse;
       
   929 				Kick();	
       
   930 				}
       
   931 			}
       
   932 		else if (token.CompareF(KTEFEndTestCaseCommand) == 0)
       
   933 			{
       
   934 			ProcessEndCase();
       
   935 			if(iAsyncTasksOutstanding)
       
   936 				// Don't run END_TESTCASE until all outstanding requests have completed
       
   937 				{
       
   938 				iState = EEndTestCasePending;
       
   939 				iCanComplete = ETrue;
       
   940 				Prime();
       
   941 				}
       
   942 			else
       
   943 				{
       
   944 				// Ok to run END_TESTCASE - Kick the stated machine so it's run next time in the RunL()
       
   945 				iState = ERunEndTestCase;
       
   946 				iCanComplete = EFalse;
       
   947 				Kick();
       
   948 				}
       
   949 			}
       
   950 		else if (token.CompareF(KTEFStartSyncTestCaseCommand) == 0) 
       
   951 			{
       
   952 			if(ProceedTestCase())
       
   953 				{
       
   954 				// Start Synchronised Test Case
       
   955 				// Check to see if the Sync Data has been created
       
   956 				// If not then create it
       
   957 				if( iSyncControl == NULL )
       
   958 					{
       
   959 					iSyncControl = CSyncControl::NewL();
       
   960 					}
       
   961 				LogTestCaseMarkerL();
       
   962 				iState = ERunStartSyncTestCase;
       
   963 				iCanComplete = EFalse;
       
   964 				Kick();	
       
   965 				}
       
   966 			else
       
   967 				{
       
   968 				//go into some sleep state until you 
       
   969 				//encounter an end test case for this...
       
   970 				iState = ETestCaseIgnore;
       
   971 				iCanComplete = EFalse;
       
   972 				Kick();	
       
   973 				}
       
   974 			}
       
   975 		else if (token.CompareF(KTEFEndSyncTestCaseCommand) == 0)
       
   976 			{
       
   977 			ProcessEndCase();
       
   978 			// End Synchronised Test Case
       
   979 			if(iAsyncTasksOutstanding)
       
   980 				// Don't run END_SYNCHRONISED_TESTCASE until all outstanding requests have completed
       
   981 				{
       
   982 				iState = EEndTestCasePending;
       
   983 				iCanComplete = ETrue;
       
   984 				Prime();
       
   985 				}
       
   986 			else
       
   987 				{
       
   988 				// Ok to run END_SYNCHRONISED_TESTCASE - Kick the stated machine so it's run next time in the RunL()
       
   989 				iState = ERunEndTestCase;
       
   990 				iCanComplete = EFalse;
       
   991 				Kick();
       
   992 				}
       
   993 			}
       
   994 		else if(token.CompareF(KTEFRunScriptCommand) == 0)
       
   995 			{
       
   996 			// Create a TLogField structure array
       
   997 			// Size of array equals to number of fields to be displayed for the command
       
   998 			TExtraLogField logField[1];
       
   999 
       
  1000 			// The first member of the structure stores the field name
       
  1001 			// The second one holds the value for the particular field
       
  1002 			_LIT(KScriptName,"SCRIPT_NAME");
       
  1003 			logField[0].iLogFieldName.Copy(KScriptName);
       
  1004 			logField[0].iLogFieldValue.Copy(lex.NextToken());
       
  1005 			
       
  1006 			// Call the Logger().LogToXml routine which handles XML logging for individual commands
       
  1007 			// Takes in the command name, number of fields and the struture array
       
  1008 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrHigh, KTEFRunScriptCommand, 1, logField);
       
  1009 			if(iAsyncTasksOutstanding)
       
  1010 				{
       
  1011 				// Don't recursively process a new script until this one's async
       
  1012 				// requests are completed
       
  1013 				iState = ERunScriptPending;
       
  1014 				iCanComplete = ETrue;
       
  1015 				Prime();
       
  1016 				}
       
  1017 			else
       
  1018 				{
       
  1019 				// Ok to process the script recursively
       
  1020 				iState = ERunScript;
       
  1021 				iCanComplete = EFalse;
       
  1022 				Kick();
       
  1023 				}
       
  1024 			}
       
  1025 		else if(token.CompareF(KTEFCedCommand) == 0)
       
  1026 			// Run the CED comms database editor
       
  1027 			{
       
  1028 			if(iAsyncTasksOutstanding)
       
  1029 				// Don't run CED until all outstanding requests have completed
       
  1030 				{
       
  1031 				iState = ERunCedPending;
       
  1032 				iCanComplete = ETrue;
       
  1033 				Prime();
       
  1034 				}
       
  1035 			else
       
  1036 				{
       
  1037 				// Ok to run CED - Kick the stated machine so it's run next time in the RunL()
       
  1038 				iState = ERunCed;
       
  1039 				iCanComplete = EFalse;
       
  1040 				Kick();
       
  1041 				}
       
  1042 			}
       
  1043 		else if(token.CompareF(KTEFDelayCommand) == 0)
       
  1044 			// Delay n milliseconds
       
  1045 			{
       
  1046 			if(iAsyncTasksOutstanding)
       
  1047 				// Don't delay until all outstanding requests have completed
       
  1048 				{
       
  1049 				iState = EDelayPending;
       
  1050 				iCanComplete = ETrue;
       
  1051 				Prime();
       
  1052 				}
       
  1053 			else
       
  1054 				{
       
  1055 				// Ok to delay
       
  1056 				iState = EDelay;
       
  1057 				iCanComplete = EFalse;
       
  1058 				Kick();
       
  1059 				}
       
  1060 			}
       
  1061 		// Script can exit on error
       
  1062 		// Flag is checked on async task completion
       
  1063 		else if(token.CompareF(KTEFBreakErrorOnCommand) == 0)
       
  1064 			{
       
  1065 			// Set the flag and process next line
       
  1066 			iCanComplete = EFalse;
       
  1067 			iBreakOnError = ETrue;
       
  1068 
       
  1069 			// Call the Logger()'s LogToXml routine to handle XML logging
       
  1070 			// Takes in just the command name without any field
       
  1071 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, KTEFBreakErrorOnCommand);
       
  1072 			Kick();
       
  1073 			}
       
  1074 		else if(token.CompareF(KTEFBreakErrorOffCommand) == 0)
       
  1075 			{
       
  1076 			// Reset the flag and process next line
       
  1077 			iCanComplete = EFalse;
       
  1078 			iBreakOnError = EFalse;
       
  1079 
       
  1080 			// Call the Logger()'s LogToXml routine to handle XML logging
       
  1081 			// Takes in just the command name without any field
       
  1082 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrMedium, KTEFBreakErrorOffCommand);
       
  1083 			Kick();
       
  1084 			}
       
  1085 		// We only implement the pause command if JustInTime debugging is switched on
       
  1086 		else if(token.CompareF(KTEFPauseCommand) == 0 && User::JustInTime())
       
  1087 			{
       
  1088 			// Create a TLogField structure array
       
  1089 			// Size of array equals to number of fields to be displayed for the command
       
  1090 			TExtraLogField logField[1];
       
  1091 
       
  1092 			// The first member of the structure stores the field name
       
  1093 			// The second one holds the value for the particular field
       
  1094 			_LIT(KDelay,"DELAY");
       
  1095 			logField[0].iLogFieldName.Copy(KDelay);
       
  1096 			logField[0].iLogFieldValue.Copy(lex.NextToken());
       
  1097 
       
  1098 			// Call the Logger().LogToXml routine which handles XML logging for individual commands
       
  1099 			// Takes in the command name, number of fields and the struture array
       
  1100 			Logger().LogToXml(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrLow, KTEFPauseCommand, 1, logField);
       
  1101 
       
  1102 			if(iAsyncTasksOutstanding)
       
  1103 				// Don't pause until all outstanding requests have completed
       
  1104 				{
       
  1105 				iState = EPausePending;
       
  1106 				iCanComplete = ETrue;
       
  1107 				Prime();
       
  1108 				}
       
  1109 			else
       
  1110 				{
       
  1111 				// Ok to Pause
       
  1112 				iState = EPause;
       
  1113 				iCanComplete = EFalse;
       
  1114 				Kick();
       
  1115 				}
       
  1116 			}
       
  1117 		// Handles the shared comand and also creates the shared object
       
  1118 		// on reading user inputs from ini file
       
  1119 		else if(token.CompareF(KTEFSharedDataCommand) == 0)
       
  1120 			{
       
  1121 			if (iIsSharedData)
       
  1122 				{
       
  1123 				WARN_PRINTF1(KTEFSharedDataCommandRepeated);
       
  1124 				}
       
  1125 			else
       
  1126 				{
       
  1127 				TRAPD(err,CreateSharedObjectsFromScriptLineL());
       
  1128 				if (err != KErrNone)
       
  1129 					{
       
  1130 					ERR_PRINTF1(KTEFErrInCreatingSharedObjects);
       
  1131 					}
       
  1132 				}
       
  1133 			iCanComplete = EFalse;
       
  1134 			Kick();
       
  1135 			}
       
  1136 		else
       
  1137 			{
       
  1138 			// Command not implemented or a comment line
       
  1139 			// Code implemented for defect 047340
       
  1140 			TBuf<KMaxTestExecuteCommandLength> bufWarning;
       
  1141 			if(token.Length())
       
  1142 				{
       
  1143 				TInt firstChar = iCurrentScriptLine[0];
       
  1144 				if(firstChar != '\r' && firstChar != '\n' && firstChar != '#' && firstChar != '/' && token.CompareF(KTEFPauseCommand) != 0)
       
  1145 					{
       
  1146 					_LIT(KUnrecognised,"Unrecognised Command - %S");
       
  1147 					if(token.Length() < bufWarning.MaxLength())
       
  1148 						{
       
  1149 						bufWarning.Copy(token);
       
  1150 						WARN_PRINTF2(KUnrecognised,&bufWarning);
       
  1151 						}
       
  1152 					else
       
  1153 						{
       
  1154 						_LIT(KLineTooLong,"Command line too long");
       
  1155 						bufWarning.Copy(KLineTooLong);
       
  1156 						WARN_PRINTF2(KUnrecognised,&bufWarning);
       
  1157 						}
       
  1158 					}
       
  1159 				}
       
  1160 			iCanComplete = EFalse;
       
  1161 			Kick();
       
  1162 			}
       
  1163 		}
       
  1164 		break;
       
  1165 
       
  1166 	case EClosing :
       
  1167 		// Script has been processed
       
  1168 		// Pick up the completions
       
  1169 		{
       
  1170 		if(iAsyncTasksOutstanding == 0)
       
  1171 			{
       
  1172 			// Script finished
       
  1173 			// Call into the parent
       
  1174 			iParent.ChildCompletion(KErrNone);
       
  1175 			delete this;
       
  1176 			}
       
  1177 		else
       
  1178 			{
       
  1179 			// More requests to complete
       
  1180 			iCanComplete = ETrue;
       
  1181 			Prime();
       
  1182 			}
       
  1183 		}
       
  1184 		break;
       
  1185 
       
  1186 	case ERunScriptPending :
       
  1187 	case EWaitCompletions :
       
  1188 	case ERunCedPending :
       
  1189 	case EDelayPending :
       
  1190 	case EPausePending :
       
  1191 	case EEndTestCasePending :
       
  1192 	case EPrefixPending:
       
  1193 		// We go into this state if we're waiting for RUN_TEST_STEP's
       
  1194 		// to complete before we execute another command
       
  1195 		{
       
  1196 		if(iAsyncTasksOutstanding == 0)
       
  1197 			{
       
  1198 			// All steps complete
       
  1199 			// Set up the next state and kick() the state machine
       
  1200 			if(iState == ERunScriptPending)
       
  1201 				iState = ERunScript;
       
  1202 			else if(iState == EWaitCompletions)
       
  1203 				iState = ERunning;
       
  1204 			else if(iState == ERunCedPending)
       
  1205 				iState = ERunCed;
       
  1206 			else if(iState == EDelayPending)
       
  1207 				iState = EDelay;
       
  1208 			else if(iState == EPausePending)
       
  1209 				iState = EPause;
       
  1210 			else if(iState == EEndTestCasePending)
       
  1211 				iState = ERunEndTestCase;
       
  1212 			else if(iState == EPrefixPending)
       
  1213 				iState = ERunPrefix;
       
  1214 			// Safe to Kick() the state machine again
       
  1215 			iCanComplete = EFalse;
       
  1216 			Kick();
       
  1217 			}
       
  1218 		else
       
  1219 			{
       
  1220 			// More requests outstanding
       
  1221 			iCanComplete = ETrue;
       
  1222 			Prime();
       
  1223 			}
       
  1224 		}
       
  1225 		break;
       
  1226 
       
  1227 	case ERunScript :
       
  1228 		// Recursively instantiate the CScriptControl class
       
  1229 		{
       
  1230 		GetScriptFileFromScriptLine();
       
  1231 		CScriptControl* scriptControl = new (ELeave) CScriptControl(*this,iChildScriptFile,Logger(),ConsoleLogger(),iStartLooping,iLoop,iDefaultSysDrive,iTestSysDrive,iSelTestingOptions);
       
  1232 		// Kick the nested CScriptControl state machine
       
  1233 		scriptControl->Kick();
       
  1234 		// Put our instance in the idling state, Prime()'d ready for clild-parent
       
  1235 		// completion by the nested one.
       
  1236 		iState = EIdling;
       
  1237 		iCanComplete = ETrue;
       
  1238 		Prime();
       
  1239 		}
       
  1240 		break;
       
  1241 
       
  1242 	case ERunCed :
       
  1243 		// Slightly tricky one
       
  1244 		// WIN32 & Non-secure means we execute CED synchronously
       
  1245 		{
       
  1246 		SetActive();
       
  1247 		TRAPD(err,RunCedFromScriptLineL());
       
  1248 		if(!err)
       
  1249 			// Expect completion asynchronously
       
  1250 			// We're set for completion so just set the state
       
  1251 			iState = EIdling;
       
  1252 		else
       
  1253 			{
       
  1254 			_LIT(KCedError,"CED Error = %d");
       
  1255 			ERR_PRINTF2(KCedError,err);
       
  1256 			// A CED error so kick the state machine
       
  1257 			iState = ERunning;
       
  1258 			Kick();
       
  1259 			}
       
  1260 		}
       
  1261 		break;
       
  1262 	
       
  1263 	case EDelay :
       
  1264 		{
       
  1265 		// Kick the timer and wait for completion
       
  1266 		SetActive();
       
  1267 		StartTimerFromScriptLine();
       
  1268 		iState = EIdling;
       
  1269 		}
       
  1270 		break;
       
  1271 
       
  1272 	case ERunEndTestCase :
       
  1273 		{
       
  1274 			LogTestCaseMarkerL();
       
  1275 			iState = ERunning;
       
  1276 			iCanComplete = EFalse;
       
  1277 			Kick();
       
  1278 		}
       
  1279 		break;
       
  1280 
       
  1281 	case ERunStartSyncTestCase :
       
  1282 		{
       
  1283 			// Check to see if the test case is ready to continue
       
  1284 			SetActive();
       
  1285 			iTimer.After( iStatus, KTEFStatusDelay*1000 );
       
  1286 			TBool syncContinue = iSyncControl->TestCaseContinueL();
       
  1287 			if( syncContinue )
       
  1288 				{
       
  1289 				iState = EIdling;
       
  1290 				}
       
  1291 		}
       
  1292 		break;
       
  1293 	case ERunPrefix :
       
  1294 		{
       
  1295 			SetPrefix();
       
  1296 			iState = ERunning;
       
  1297 			iCanComplete = EFalse;
       
  1298 			Kick();
       
  1299 		}
       
  1300 		break;
       
  1301 		
       
  1302 	case EIdling :
       
  1303 		{
       
  1304 		// Woken up due to either:
       
  1305 		// A child CScriptControl instance completing OR
       
  1306 		// the delay timer has completed.
       
  1307 		iState = ERunning;
       
  1308 		iCanComplete = EFalse;
       
  1309 		Kick();
       
  1310 		}
       
  1311 		break;
       
  1312 
       
  1313 	case EPause :
       
  1314 		{
       
  1315 		_LIT(KPaused,"PAUSED - Hit Any Key to Continue\n");
       
  1316 		ConsoleLogger().Console().Printf(KPaused);
       
  1317 		ConsoleLogger().Console().Getch();
       
  1318 		iState = ERunning;
       
  1319 		iCanComplete = EFalse;
       
  1320 		Kick();
       
  1321 		}
       
  1322 		//Start of defect 115942 
       
  1323 		break;
       
  1324 		//End of defect 115942
       
  1325 
       
  1326 	case ETestCaseIgnore:
       
  1327 		{
       
  1328 		TPtrC scriptLine;
       
  1329 		//do we want to while till we come to end of test case?
       
  1330 		while(GetNextScriptLine(scriptLine))
       
  1331 			{
       
  1332 			TLex lex(scriptLine);
       
  1333 			TPtrC token(lex.NextToken());
       
  1334 			if((token.CompareF(KTEFEndTestCaseCommand) == 0)
       
  1335 					|| (token.CompareF(KTEFEndSyncTestCaseCommand) == 0)) //we found an end test case one
       
  1336 				{
       
  1337 				TPtrC testCID(lex.NextToken());
       
  1338 				//to support nested test cases
       
  1339 				if(iTestCaseIDToIgnore.CompareF(testCID) == 0)
       
  1340 				{
       
  1341 					//in any case...go back to running and re-evaluate our position at
       
  1342 					iState = ERunning;
       
  1343 					iTestCaseIDToIgnore.Set(KTEFNull);
       
  1344 					iCanComplete = EFalse;
       
  1345 					iCurrentScriptLine.Set(scriptLine);
       
  1346 					//before going back to running re-evaluate the 
       
  1347 					//state of selective testing
       
  1348 					ProcessEndCase() ; 
       
  1349 					Kick();
       
  1350 					break;
       
  1351 				}
       
  1352 				}
       
  1353 			}
       
  1354 		break;
       
  1355 		}
       
  1356 
       
  1357 	default:
       
  1358 		break;
       
  1359 		}
       
  1360 	}
       
  1361 
       
  1362 /**
       
  1363  * Implement the PRINT command
       
  1364  * Print the string(s) following the PRINT command to the log file
       
  1365  */
       
  1366 void CScriptControl::PrintFromScriptLine() const
       
  1367 	{
       
  1368 	TLex lex(iCurrentScriptLine);
       
  1369 	lex.NextToken();
       
  1370 	TBuf<KMaxTestExecuteCommandLength> buf;
       
  1371 	buf.Copy(lex.Remainder());
       
  1372 
       
  1373 	_LIT(KCommentString, " //");
       
  1374 
       
  1375 	TInt offset = buf.Find(KCommentString);
       
  1376 	if (offset != KErrNotFound)
       
  1377 		{
       
  1378 		buf.SetLength(offset);
       
  1379 		}
       
  1380 
       
  1381 	_LIT(KS,"%S");
       
  1382 	INFO_PRINTF2(KS,&buf);
       
  1383 	}
       
  1384 
       
  1385 /**
       
  1386  * Implement the PREFIX command
       
  1387  * Stores the prefix for command line prefixing
       
  1388  */
       
  1389 void CScriptControl::SetPrefix() 
       
  1390 	{
       
  1391 	TLex lex(iCurrentScriptLine);
       
  1392 	// Bypass the PREFIX command
       
  1393 	lex.NextToken();
       
  1394 
       
  1395 	// Get rid of any leading spaces
       
  1396 	while(!lex.Eos())
       
  1397 		{
       
  1398 		TChar peek = lex.Peek();
       
  1399 		if(peek == ' ')
       
  1400 			{
       
  1401 			lex.Inc();
       
  1402 			}
       
  1403 		else
       
  1404 			break;
       
  1405 		}
       
  1406 
       
  1407 	// Chop off the carriage return and insert a space
       
  1408 	// If there  is a preceding comment line, get rid of that.
       
  1409 
       
  1410 	iScriptLinePrefix.Copy(lex.Remainder());
       
  1411 
       
  1412 	_LIT(KCarriageReturn, "\r\n");
       
  1413 	_LIT(KCommentString, " //");
       
  1414 
       
  1415 	TInt offset = iScriptLinePrefix.Find(KCommentString);
       
  1416 	if (offset != KErrNotFound)
       
  1417 		{
       
  1418 		iScriptLinePrefix.SetLength(offset);
       
  1419 		}
       
  1420 	else
       
  1421 		{
       
  1422 		offset = iScriptLinePrefix.Find(KCarriageReturn);
       
  1423 
       
  1424 		if (offset != KErrNotFound)
       
  1425 			{
       
  1426 			iScriptLinePrefix.SetLength(offset);
       
  1427 			}
       
  1428 		}
       
  1429 
       
  1430 	_LIT(KTEFSpace, " ");
       
  1431 	iScriptLinePrefix.Append(KTEFSpace);
       
  1432 
       
  1433 	iScriptLinePrefixSet = ETrue;
       
  1434 		
       
  1435 	}
       
  1436 
       
  1437 /**
       
  1438  * Function to evaluate the situation of selective testing 
       
  1439  * Returns whether the testcase on the current script line 
       
  1440  * should be run.
       
  1441  */
       
  1442 TBool CScriptControl::ProceedTestCase() 
       
  1443 	{ 
       
  1444 	
       
  1445 	//if selective testing is not on, dont bother
       
  1446 	if(iSelTestingOptions == NULL)
       
  1447 		return ETrue;
       
  1448 	iTestCaseCounter++;
       
  1449 	if(iTestCaseCounter > 1) //if this is nested, let it run unconditionally
       
  1450 		return ETrue;
       
  1451 	// the remaining continues only if selective testing is on
       
  1452 	// AND we have a non-null, and hopefully valid instance of
       
  1453 	// iSelTestingOptions
       
  1454 	TLex lex(iCurrentScriptLine);
       
  1455 	TPtrC token(lex.NextToken());
       
  1456 	TPtrC testCaseID(lex.NextToken());
       
  1457 	//evaluating class state variables...
       
  1458 	//check range
       
  1459 	TIdentityRelation<TPtrC> crackID(TSelectiveTestingOptions::CompareTPtrC);
       
  1460 	TIdentityRelation<TRange> rangeComprtr(TRange::CompareTRangeStartCase);
       
  1461 	TRange dummy(testCaseID,testCaseID);
       
  1462 	for ( TInt index=0; index<iSelTestingOptions->iSelectiveCaseRange.Count(); ++index )
       
  1463 		{
       
  1464 		if ( testCaseID.CompareF(iSelTestingOptions->iSelectiveCaseRange[index].iStartTestCase) == 0 )
       
  1465 			{
       
  1466 			iSelTestingOptions->iSelectiveCaseRange[index].iState=TRange::EStateInUse;
       
  1467 			++iRangeRefCounter;//number of ranges now in operation	
       
  1468 			}
       
  1469 		}
       
  1470 	
       
  1471 	
       
  1472 	TBool runCase = ETrue ; //run everything by def
       
  1473 	if( iSelTestingOptions->iSelectiveTestingType == iInclusive )
       
  1474 		{
       
  1475 		//so selective testing is on and also its inclusive...
       
  1476 		runCase = (iRangeRefCounter>0) || iSelectOne ; 
       
  1477 		}
       
  1478 	else if(iSelTestingOptions->iSelectiveTestingType == iExclusive)
       
  1479 		{
       
  1480 		//so selective testing is on and also its exclusive...
       
  1481 		runCase = (iRangeRefCounter<=0) && !iSelectOne ; 
       
  1482 		}
       
  1483 	if(!runCase)//if the test case is to be selectively skipped, log it...
       
  1484 		{
       
  1485 		//use this one to log unexecuted cases...
       
  1486 		Logger().LogTestCaseResult(iScriptFile, iCurrentScriptLineNumber, RFileFlogger::ESevrInfo, token, testCaseID,ESkippedSelectively);
       
  1487 		}
       
  1488 	if(runCase == EFalse)
       
  1489 		{
       
  1490 			iTestCaseIDToIgnore.Set(testCaseID) ; 
       
  1491 		}
       
  1492 		
       
  1493 	return runCase ; 	
       
  1494 	}
       
  1495 
       
  1496 /**
       
  1497  * Function to evaluate the state variables 
       
  1498  * at the end of test case 
       
  1499  */
       
  1500 void CScriptControl::ProcessEndCase()
       
  1501 	{
       
  1502 	if(iSelTestingOptions==NULL) //selective testing is not on
       
  1503 		return;					// dont bother
       
  1504 	iTestCaseCounter--;
       
  1505 	if(iTestCaseCounter<0) //in case we encountered unmatched end cases
       
  1506 		iTestCaseCounter=0;
       
  1507 	TLex lex(iCurrentScriptLine);
       
  1508 	TPtrC token(lex.NextToken());
       
  1509 	TPtrC testCaseID(lex.NextToken());	
       
  1510 	//check if this is ending a range
       
  1511 	TRange dummy(testCaseID,testCaseID);
       
  1512 	TIdentityRelation<TRange> crackIDRangeend(TRange::CompareTRangeEnd);
       
  1513 	for ( TInt index=0; index<iSelTestingOptions->iSelectiveCaseRange.Count(); ++index )
       
  1514 		{
       
  1515 		if ( testCaseID.CompareF(iSelTestingOptions->iSelectiveCaseRange[index].iEndTestCase) == 0 )
       
  1516 			{
       
  1517 			if ( iSelTestingOptions->iSelectiveCaseRange[index].iState == TRange::EStateInUse )
       
  1518 				{
       
  1519 				iSelTestingOptions->iSelectiveCaseRange[index].iState=TRange::EStateUsed;
       
  1520 				--iRangeRefCounter;
       
  1521 				}
       
  1522 			else
       
  1523 				{
       
  1524 				//	Error condition. An end test case has been matched to a range that has not processed the start test case
       
  1525 				//	Either the start test case does not exist or the start test case comes after the end test case in the script
       
  1526 				//or maybe do nothing
       
  1527 				
       
  1528 				}
       
  1529 			}
       
  1530 		}
       
  1531 	
       
  1532 		
       
  1533 	//always reset the onetime test case thing
       
  1534 	iSelectOne = EFalse;
       
  1535 	}
       
  1536 
       
  1537 /**
       
  1538  * Implement START_TESTCASE/ END_TESTCASE commands
       
  1539  * Write a testcase marker to the logfile
       
  1540  */
       
  1541 void CScriptControl::LogTestCaseMarkerL() 
       
  1542 	{
       
  1543 	TLex lex(iCurrentScriptLine);
       
  1544 	TPtrC token(lex.NextToken());
       
  1545 	TVerdict TestCaseResult(EFail);
       
  1546 
       
  1547 	TPtrC TestCaseMarker(lex.NextToken());
       
  1548 
       
  1549 	if (token.CompareF(KTEFStartTestCaseCommand) == 0 || token.CompareF(KTEFStartSyncTestCaseCommand) == 0)
       
  1550 		{
       
  1551 		// Call the interface routine for logging in HTML & XML format
       
  1552 		Logger().LogTestCaseResult(iScriptFile, iCurrentScriptLineNumber, RFileFlogger::ESevrHigh, token, TestCaseMarker);
       
  1553 		iTestCaseID.Copy(TestCaseMarker);
       
  1554 		}
       
  1555 	else
       
  1556 		{
       
  1557 		// Its an END_TESTCASE.
       
  1558 		// Need to identify whether all preceding test steps in the file
       
  1559 		// passed (back to a *matching* START_TESTCASE).
       
  1560 		TestCaseResult = HasTestCasePassedL(TestCaseMarker);
       
  1561 
       
  1562 			// Special case for KTEFEndSyncTestCaseCommand where the result in 
       
  1563 			// the shared data area needs to be updated so STAT can retrieve it later.
       
  1564 			if( token.CompareF(KTEFEndSyncTestCaseCommand) == 0 )
       
  1565 				{
       
  1566 				// Check to see if the Sync Data has been created
       
  1567 				if( iSyncControl != NULL )
       
  1568 					{
       
  1569 					// Update the TEFResult shared data value
       
  1570 					iSyncControl->SetResultL( TestCaseResult );
       
  1571 					}
       
  1572 				else
       
  1573 					{
       
  1574 					User::Leave( KErrNotReady );
       
  1575 					}
       
  1576 				}
       
  1577 		// Call the interface routine for logging in HTML & XML format
       
  1578 		Logger().LogTestCaseResult(iScriptFile, iCurrentScriptLineNumber, RFileFlogger::ESevrHigh, token, TestCaseMarker, TestCaseResult);
       
  1579 		iTestCaseID.Copy(KTEFTestCaseDefault);
       
  1580 		}
       
  1581 	}
       
  1582 
       
  1583 /**
       
  1584  *
       
  1585  * Implement TestCase pass checking
       
  1586  */
       
  1587 TVerdict CScriptControl::HasTestCasePassedL(TPtrC aTestCaseMarker)
       
  1588 	{
       
  1589 	// Looks from the top of the file for the equivalent Start_TestCase
       
  1590 	// when it finds it it checks that all the steps to the bottom of 
       
  1591 	// the file (the current position) 
       
  1592 
       
  1593 	// Create a Cinidata object to parse through the testexecute.ini
       
  1594 	// To retrieve the path where the log is to be placed
       
  1595 
       
  1596 	CTestExecuteIniData* parseTestExecuteIni = NULL;
       
  1597 	TBuf<KMaxTestExecuteNameLength> resultFilePath;
       
  1598 
       
  1599 	TRAPD(err,parseTestExecuteIni = CTestExecuteIniData::NewL(iDefaultSysDrive));
       
  1600 	if (err == KErrNone)
       
  1601 		{
       
  1602 		CleanupStack::PushL(parseTestExecuteIni);
       
  1603 		parseTestExecuteIni->ExtractValuesFromIni();
       
  1604 		parseTestExecuteIni->GetKeyValueFromIni(KTEFHtmlKey, resultFilePath);
       
  1605 		}
       
  1606 	else
       
  1607 		{
       
  1608 		resultFilePath.Copy(KTestExecuteLogPath);
       
  1609 		resultFilePath.Replace(0, 2, iDefaultSysDrive);
       
  1610 		}
       
  1611 
       
  1612 	TBuf<KMaxTestExecuteNameLength> resultFileName(resultFilePath);
       
  1613 	// loading the simplified test result in case of out-of-memory 
       
  1614 	resultFileName.Append(KTEFTestExecuteResultSimplifiedSummaryFile);
       
  1615 	if (parseTestExecuteIni != NULL)
       
  1616 		{
       
  1617 		CleanupStack::PopAndDestroy(parseTestExecuteIni);
       
  1618 		}
       
  1619 
       
  1620 	// Open the result summary file
       
  1621 	RFs fS;
       
  1622 	User::LeaveIfError(fS.Connect());
       
  1623 	CleanupClosePushL(fS);
       
  1624 
       
  1625 	RFile logFile;
       
  1626 	User::LeaveIfError(logFile.Open(fS,resultFileName, EFileWrite | EFileRead | EFileShareAny));
       
  1627 	CleanupClosePushL(logFile);
       
  1628 	TInt fileSize;
       
  1629 	// Read the complete result summary file onto the heap
       
  1630 	// It wont be that large
       
  1631 	User::LeaveIfError(logFile.Size(fileSize));
       
  1632 	HBufC* resultData = HBufC::NewLC(fileSize);
       
  1633 	HBufC8* resultData8 = HBufC8::NewLC(fileSize);	
       
  1634 	TPtr8 ptrData8(resultData8->Des());
       
  1635 	User::LeaveIfError(logFile.Read(ptrData8));
       
  1636 	TPtr ptrData(resultData->Des());
       
  1637 	ptrData.Copy(ptrData8);
       
  1638 	CleanupStack::PopAndDestroy(resultData8);
       
  1639 
       
  1640 	TBool foundMarker(EFalse);
       
  1641 	TBool foundNonPassResult(EFalse);
       
  1642 	TInt duplicatesCounter(0);
       
  1643 
       
  1644 	TLex lex(ptrData);
       
  1645 	while (!lex.Eos())
       
  1646 		{
       
  1647 		// Find the ***Result keywords
       
  1648 		TPtrC commandName( lex.NextToken() );
       
  1649 		if(	commandName.CompareF(KTEFStartTestCaseCommand) == 0 ||
       
  1650 			commandName.CompareF(KTEFStartSyncTestCaseCommand) == 0 )
       
  1651 			{
       
  1652 			if (lex.NextToken() == aTestCaseMarker)
       
  1653 				{
       
  1654 				// Increment the counter to identify that the test case id is duplicated
       
  1655 				duplicatesCounter++;
       
  1656 				if (duplicatesCounter == 2)
       
  1657 					{
       
  1658 					// If the test case id is duplicated for more than once,
       
  1659 					// issue a warning in the log file, mentioning duplicate of test case id
       
  1660 					_LIT(KWarnDuplicateTCID, "Test Case ID : %S re-used");
       
  1661 					WARN_PRINTF2(KWarnDuplicateTCID, &aTestCaseMarker);
       
  1662 					}
       
  1663 
       
  1664 				// When a matching test case id is found, the found marker is set to ETrue
       
  1665 				foundMarker = ETrue;
       
  1666 				// Initialise the foundNonPassResult to EFalse, on entry into each test case result in the log
       
  1667 				foundNonPassResult = EFalse;
       
  1668 				continue;
       
  1669 				}
       
  1670 			continue;
       
  1671 			}
       
  1672 		else if (foundMarker && commandName == KTEFResultTag)
       
  1673 			{
       
  1674 			// If the START_TESTCASE is found and a RESULT tag is found in the test result file,
       
  1675 			// Extract the result value set for every test step called within
       
  1676 			// and check to see if there are any non-pas results
       
  1677 			_LIT(KTEFEquals,"=");
       
  1678 			if (lex.NextToken() != KTEFEquals)
       
  1679 			continue;
       
  1680 			TPtrC result(lex.NextToken());
       
  1681 			if(result != KTEFResultPass)
       
  1682 				{
       
  1683 				// Set the foundNonPassResult to ETrue indicating the test case to fail
       
  1684 				foundNonPassResult = ETrue;
       
  1685 				}
       
  1686 			}			
       
  1687 		}
       
  1688 
       
  1689 	CleanupStack::PopAndDestroy(resultData);
       
  1690 	CleanupStack::Pop(&logFile);
       
  1691 	logFile.Close();
       
  1692 	CleanupStack::Pop(&fS);
       
  1693 	fS.Close();
       
  1694 
       
  1695 	if (foundMarker)
       
  1696 		{
       
  1697 		if (foundNonPassResult)
       
  1698 			{
       
  1699 			return EFail;
       
  1700 			}
       
  1701 		else
       
  1702 			{
       
  1703 			return EPass;
       
  1704 			}
       
  1705 		}
       
  1706 	else
       
  1707 		{
       
  1708 		return EInconclusive;
       
  1709 		}
       
  1710 	}
       
  1711 
       
  1712 /**
       
  1713  * Implement the DELAY command
       
  1714  */
       
  1715 void CScriptControl::StartTimerFromScriptLine()
       
  1716 	{
       
  1717 	TLex lex(iCurrentScriptLine);
       
  1718 	lex.NextToken();
       
  1719 	TLex delayLex(lex.NextToken());
       
  1720 	TInt delay;
       
  1721 	// Read the delay in milliseconds
       
  1722 	TInt err = delayLex.Val(delay);
       
  1723 	if(err)
       
  1724 		// Set the default
       
  1725 		delay = KDefaultDelayMilliseconds;
       
  1726 	iTimer.After(iStatus,delay*1000);
       
  1727 	}
       
  1728 
       
  1729 /**
       
  1730  * Secure - same for Target and Wins
       
  1731  */
       
  1732 void CScriptControl::RunCedFromScriptLineL()
       
  1733 	{
       
  1734 	TLex lex(iCurrentScriptLine);
       
  1735 	// Skip CED
       
  1736 	lex.NextToken();
       
  1737 	TPtrC cedCommandLine(lex.Remainder());
       
  1738 	iCurrentScriptLine.Set(cedCommandLine);
       
  1739 	RProcess process;
       
  1740 	User::LeaveIfError(process.Create(_L("ced.exe"),iCurrentScriptLine));
       
  1741 	process.Rendezvous(iStatus);
       
  1742 	// Run CED asynchronously
       
  1743 	process.Resume();
       
  1744 	process.Close();
       
  1745 	}
       
  1746 
       
  1747 /**
       
  1748  * Set up the path of a script file for a child CScriptControl object
       
  1749  */
       
  1750 void CScriptControl::GetScriptFileFromScriptLine()
       
  1751 	{
       
  1752 	TLex lex(iCurrentScriptLine);
       
  1753 	lex.NextToken();
       
  1754 	iChildScriptFile.Set(lex.NextToken());
       
  1755 	}
       
  1756 
       
  1757 /**
       
  1758  * @param aUtilsCommand - Command string for the utilities command
       
  1759  * Implement basic commands:
       
  1760  * NB: Always requires the full path
       
  1761  * Logic borrowed from Scheduletest
       
  1762  * Always complete synchronously
       
  1763  * 
       
  1764  * CopyFile
       
  1765  * MKDir
       
  1766  * MakeReadWrite
       
  1767  * Delete
       
  1768  * DeleteDirectory
       
  1769  */
       
  1770 void CScriptControl::RunUtilsFromScriptLineL() const
       
  1771 	{
       
  1772 	_LIT(KDefault,				"?:\\default");
       
  1773 	_LIT(KCDrive,				"?:\\"); 
       
  1774 	_LIT(KTEFBackslash,			"\\" );
       
  1775 
       
  1776 	TBuf<10> defaultPath(KDefault);
       
  1777 	defaultPath.Replace(0, 2, iTestSysDrive);
       
  1778 
       
  1779 	TBuf<3> cDrive(KCDrive);
       
  1780 	cDrive.Replace(0, 2, iTestSysDrive);
       
  1781 
       
  1782 	RFs fS;
       
  1783 	User::LeaveIfError(fS.Connect() );
       
  1784 	CleanupClosePushL(fS);
       
  1785 
       
  1786 	TLex lex(iCurrentScriptLine);
       
  1787 	lex.NextToken();
       
  1788 	TPtrC token(lex.NextToken());
       
  1789 	if(token.CompareF(KTEFRunUtilsCopyFile) == 0)
       
  1790 		{
       
  1791 		TPtrC file1=lex.NextToken();
       
  1792 		TPtrC file2=lex.NextToken();
       
  1793 		TParse source, dest;
       
  1794 		CFileMan* fMan = CFileMan::NewL(fS);
       
  1795 		CleanupStack::PushL(fMan);
       
  1796 		User::LeaveIfError(source.Set(file1, &defaultPath, NULL) );
       
  1797 		User::LeaveIfError(dest.Set(file2, &defaultPath, NULL) );
       
  1798 		User::LeaveIfError(fMan->Copy(source.FullName(), dest.FullName(), CFileMan::EOverWrite) );
       
  1799 		CleanupStack::PopAndDestroy(fMan);
       
  1800 		}
       
  1801 	else if(token.CompareF(KTEFRunUtilsMkDir) == 0)
       
  1802 		{
       
  1803 		token.Set(lex.NextToken());
       
  1804 		TParse fileName;
       
  1805 
       
  1806 		if (!token.Length())
       
  1807 			User::Leave(KErrPathNotFound);
       
  1808 		
       
  1809 		TPtrC lastChar(token.Mid(token.Length() - 1));
       
  1810 		if ( lastChar.CompareF(KTEFBackslash) != 0 )
       
  1811 			{
       
  1812 			TBuf<64> tempToken(token);
       
  1813 			tempToken.Append(KTEFBackslash);
       
  1814 			token.Set(tempToken);
       
  1815 			}
       
  1816 
       
  1817 		User::LeaveIfError( fileName.Set(token, &cDrive, NULL) );
       
  1818 		User::LeaveIfError( fS.MkDir( fileName.DriveAndPath() ) );
       
  1819 		}
       
  1820 	else if(token.CompareF(KTEFRunUtilsDeleteFile) == 0 ||
       
  1821 	         token.CompareF(KTEFRunUtilsDelete) == 0)
       
  1822 		{
       
  1823 		token.Set(lex.NextToken());
       
  1824 		// defect047128 - Code change for handling wildcard deletes
       
  1825 		CFileMan* fMan = CFileMan::NewL(fS);
       
  1826 		CleanupStack::PushL(fMan);
       
  1827 		User::LeaveIfError(fMan->Delete(token) );
       
  1828 		CleanupStack::PopAndDestroy(fMan);
       
  1829 		}
       
  1830 	else if(token.CompareF(KTEFRunUtilsMakeReadWrite) == 0)
       
  1831 		{
       
  1832 		token.Set(lex.NextToken());
       
  1833 		TParse fileName;
       
  1834 		User::LeaveIfError(fileName.Set(token, &defaultPath, NULL) );
       
  1835 		TInt err = fS.SetAtt(fileName.FullName(),0, KEntryAttReadOnly);
       
  1836 		if (err != KErrNone && err != KErrNotFound)
       
  1837 			User::Leave(err);
       
  1838 		}
       
  1839 	//It deletes the specified directory
       
  1840 	else if(token.CompareF(KTEFDeleteDirectory) == 0)
       
  1841 		{
       
  1842 		token.Set(lex.NextToken());
       
  1843 		TParse fileName;
       
  1844 
       
  1845 		if (!token.Length())
       
  1846 			User::Leave(KErrPathNotFound);
       
  1847 		
       
  1848 		TPtrC lastChar(token.Mid(token.Length() - 1));
       
  1849 		if ( lastChar.CompareF(KTEFBackslash) != 0 )
       
  1850 			{
       
  1851 			TBuf<64> tempToken(token);
       
  1852 			tempToken.Append(KTEFBackslash);
       
  1853 			token.Set(tempToken);
       
  1854 			}
       
  1855 
       
  1856 		CFileMan* fMan = CFileMan::NewL(fS);
       
  1857 		CleanupStack::PushL(fMan);
       
  1858 
       
  1859 		User::LeaveIfError(fileName.Set(token, &cDrive, NULL) );
       
  1860 		User::LeaveIfError( fMan->RmDir( fileName.DriveAndPath() ) );
       
  1861 
       
  1862 		CleanupStack::PopAndDestroy(fMan);
       
  1863 		}
       
  1864 	
       
  1865 	fS.Close();
       
  1866 	CleanupStack::Pop(&fS);	
       
  1867 	}
       
  1868 
       
  1869 /**
       
  1870  * Read the Script File data into a heap buffer
       
  1871  * We could read the file line by line but that would be cumbersome, and unless there
       
  1872  * is a heap size problem, this is tidier.
       
  1873  */
       
  1874 void CScriptControl::CreateScriptDataFromScriptFileL()
       
  1875 	{
       
  1876 	RFs fS;
       
  1877 	User::LeaveIfError(fS.Connect());
       
  1878 	CleanupClosePushL(fS);
       
  1879 	RFile scriptFile;
       
  1880 	User::LeaveIfError(scriptFile.Open(fS,iScriptFile,EFileRead | EFileShareAny));
       
  1881 	CleanupClosePushL(scriptFile);
       
  1882 	TInt fileSize;
       
  1883 	User::LeaveIfError(scriptFile.Size(fileSize));
       
  1884 	// Create a 16bit heap buffer
       
  1885 	iScriptData = HBufC::NewL(fileSize);
       
  1886 	HBufC8* narrowData = HBufC8::NewL(fileSize);
       
  1887 	CleanupStack::PushL(narrowData);
       
  1888 	TPtr8 narrowPtr=narrowData->Des();
       
  1889 	// Read the file into an 8bit heap buffer
       
  1890 	User::LeaveIfError(scriptFile.Read(narrowPtr));
       
  1891 	TPtr widePtr(iScriptData->Des());
       
  1892 	// Copy it to the 16bit buffer
       
  1893 	widePtr.Copy(narrowData->Des());
       
  1894 	CleanupStack::PopAndDestroy(narrowData);
       
  1895 	CleanupStack::Pop(2);
       
  1896 	scriptFile.Close();
       
  1897 	fS.Close();
       
  1898 	// Set up the instance token parser
       
  1899 	iScriptLex = iScriptData->Des();
       
  1900 	}
       
  1901 
       
  1902 /**
       
  1903  * Extracts the human readable server name from the current script line then
       
  1904  * calls Client RTestServ Interface to make a connection to the server.
       
  1905  */
       
  1906 void CScriptControl::CreateServerFromScriptLineL()
       
  1907 	{
       
  1908 	TLex lex(iCurrentScriptLine);
       
  1909 	lex.NextToken();
       
  1910 	TInt i=0;
       
  1911 	TInt count = iServers.Count();
       
  1912 	TPtrC serverName(lex.NextToken());
       
  1913 	
       
  1914 	// We loop through to see if the server has already been created
       
  1915 	for(i=0;i<count;i++)
       
  1916 		{
       
  1917 		if(iServers[i]->ServerName() == serverName)
       
  1918 			// Server already exists in our array
       
  1919 			break;
       
  1920 		}
       
  1921 	if(i == count)
       
  1922 		{
       
  1923 		// Create a new RTestServ pointer and add it to the list
       
  1924 		RScriptTestServ* serv = new (ELeave) RScriptTestServ;
       
  1925 		// Connect using the client API
       
  1926 		TInt err;
       
  1927 		if(lex.NextToken().CompareF(KTEFLoadSuiteSharedData) == 0)
       
  1928 			{
       
  1929 			err = serv->Connect(serverName,ETrue);
       
  1930 			}
       
  1931 		else
       
  1932 			err = serv->Connect(serverName,EFalse);
       
  1933 		if(err)
       
  1934 			{
       
  1935 			// Don't add the server to the array if we fail to connect.
       
  1936 			delete serv;
       
  1937 			// Caller TRAP's
       
  1938 			User::Leave(err);
       
  1939 			}
       
  1940 		iServers.Append(serv);
       
  1941 		}
       
  1942 	}
       
  1943 
       
  1944 /**
       
  1945  * @param aIndex - Return the index of the RTestServ instance - If found
       
  1946  * @return - EFalse if server not found. ETrue if server found.
       
  1947  * 
       
  1948  */
       
  1949 TBool CScriptControl::GetServerIndexFromScriptLine(TInt& aIndex)
       
  1950 	{
       
  1951 	TLex lex(iCurrentScriptLine);
       
  1952 	TLex lexTimeout;
       
  1953 	_LIT(KErrInvalidArgumentSet,"The arguments are not provided in proper format.\
       
  1954 			Unable to retrieve the details of the server from the command line");
       
  1955 
       
  1956 	TPtrC command(lex.NextToken());
       
  1957 	if(command.CompareF(KTEFRunTestStepResultCommand) == 0)
       
  1958 		{
       
  1959 		lex.NextToken();
       
  1960 		lex.SkipSpace();
       
  1961 		lex.Mark();
       
  1962 		}
       
  1963 		
       
  1964 	else if(command.CompareF(KTEFRunPanicStepResultCommand) == 0)
       
  1965 		{
       
  1966 		lex.NextToken();
       
  1967 		TPtrC panicString(lex.NextToken());
       
  1968 		// Check to see if the panic string contains open quotes and close quotes
       
  1969 		// If the panic string token contains open quote, it is understood that the panic string contains spaces
       
  1970 		// So, look for close quote in the subsequent tokens. If not found, return boolean false as return value
       
  1971 		if(panicString.Left(1).Compare(KTEFOpenQuotes) == 0 && panicString.Right(1).Compare(KTEFOpenQuotes) != 0)
       
  1972 			{
       
  1973 			TBool validCommandLine(EFalse);
       
  1974 			while(!lex.Eos() && !validCommandLine)
       
  1975 				{				
       
  1976 				panicString.Set(lex.NextToken());
       
  1977 				if(panicString.Right(1).Compare(KTEFOpenQuotes) == 0)
       
  1978 					validCommandLine = ETrue;
       
  1979 				}
       
  1980 			if (!validCommandLine)
       
  1981 				{
       
  1982 				ERR_PRINTF1(KErrInvalidArgumentSet);
       
  1983 				return EFalse;
       
  1984 				}
       
  1985 			}
       
  1986 		lex.SkipSpace();
       
  1987 		lex.Mark();
       
  1988 		}
       
  1989 	else if(command.CompareF(KTEFRunTestStepCommand) == 0 ||
       
  1990 			command.CompareF(KTEFStartTestBlock) == 0)
       
  1991 		{
       
  1992 		TInt firstChar;
       
  1993 		TPtrC commandStr;
       
  1994 		TBool panicStringComplete(ETrue);
       
  1995 		while(!lex.Eos())
       
  1996 			{
       
  1997 			lex.SkipSpace();
       
  1998 			lex.Mark();
       
  1999 			
       
  2000 			TPtrC	token = lex.NextToken();
       
  2001 			if( token.Length()>0 )
       
  2002 				{
       
  2003 				commandStr.Set( token );
       
  2004 				firstChar = commandStr[0];
       
  2005 				// 33 is the ascii value for "!". Used here for confirming switches
       
  2006 				if (firstChar != KTEFAsciiExclamation && panicStringComplete)
       
  2007 					{
       
  2008 					break;
       
  2009 					}
       
  2010 				// Check to see if !PanicString TEF parameter contains panic string with spaces
       
  2011 				// If so, see if they are enclosed within a open & close braces
       
  2012 				if(commandStr.Length() > 14 && 
       
  2013 					commandStr.Mid(0,14).Compare(_L("!PanicString=\"")) == 0)
       
  2014 						panicStringComplete = EFalse;
       
  2015 				if(!panicStringComplete && commandStr.Right(1).Compare(KTEFOpenQuotes) == 0)
       
  2016 					panicStringComplete = ETrue;
       
  2017 				}
       
  2018 			}
       
  2019 			if (!panicStringComplete)
       
  2020 				{
       
  2021 				ERR_PRINTF1(KErrInvalidArgumentSet);
       
  2022 				return EFalse;
       
  2023 				}
       
  2024 		}
       
  2025 	
       
  2026 	// We need to skip the timeout if it's there.
       
  2027 	if(	command.CompareF(KTEFRunTestStepCommand) == 0 ||
       
  2028 		command.CompareF(KTEFStartTestBlock) == 0)
       
  2029 		lexTimeout=lex.MarkedToken();
       
  2030 	else
       
  2031 		lexTimeout=lex.NextToken();
       
  2032 	TInt timeout;
       
  2033 	TPtrC serverName;
       
  2034 	if(lexTimeout.Val(timeout) != KErrNone)
       
  2035 		// No timeout so use the second token
       
  2036 		serverName.Set(lex.MarkedToken());
       
  2037 	else
       
  2038 		// Timeout value there
       
  2039 		serverName.Set(lex.NextToken());
       
  2040 	TInt i=0;
       
  2041 	// Loop through the installed servers
       
  2042 	TInt count = iServers.Count();
       
  2043 	for(i=0;i<count;i++)
       
  2044 		{
       
  2045 		if(iServers[i]->ServerName() == serverName)
       
  2046 			// Found server installed
       
  2047 			break;
       
  2048 		}
       
  2049 	// Return found or not found
       
  2050 	if(i == count)
       
  2051 		return EFalse;
       
  2052 	else
       
  2053 		{
       
  2054 		aIndex = i;
       
  2055 		if (iServers[i]->SharedData())
       
  2056 			{
       
  2057 			iConcurrent = EFalse;
       
  2058 			}
       
  2059 		return ETrue;
       
  2060 		}
       
  2061 	}
       
  2062 
       
  2063 /**
       
  2064  *  * @return - ETrue if the scriptline is valid, else retuens EFalse
       
  2065  */
       
  2066 TBool CScriptControl::CheckValidScriptLine() const
       
  2067 	{
       
  2068 	TLex lex(iCurrentScriptLine);
       
  2069 	TPtrC command(lex.NextToken());
       
  2070 	TBool panicCodeSet(EFalse);
       
  2071 	TBool panicStringSet(EFalse);
       
  2072 	TBool heapValueSet(EFalse);
       
  2073 	TBool validScript(ETrue);
       
  2074 	TBool oomRequestSet(EFalse);
       
  2075 	TBool setupOptionSet(EFalse);
       
  2076 	
       
  2077 	if(command.CompareF(KTEFRunTestStepCommand) == 0)
       
  2078 		{
       
  2079 		TInt firstChar;
       
  2080 		TPtrC commandStr;
       
  2081 		while(!lex.Eos())
       
  2082 			{
       
  2083 			lex.SkipSpace();
       
  2084 			commandStr.Set(lex.NextToken());
       
  2085 			firstChar = commandStr[0];
       
  2086 			// 33 is the ascii value for "!". Used here for confirming switches
       
  2087 			if (firstChar == KTEFAsciiExclamation)
       
  2088 				{
       
  2089 				if (commandStr.Length() >= KTEFMinErrorParamLength && commandStr.Mid(0,KTEFMinErrorParamLength).CompareF(KTEFError) == 0)
       
  2090 					{
       
  2091 					if(command.CompareF(KTEFRunTestStepCommand) == 0)
       
  2092 						command.Set(KTEFRunErrorStepResultCommand);
       
  2093 					else
       
  2094 						validScript = EFalse;
       
  2095 					}
       
  2096 				else if (commandStr.Length() >= KTEFMinSetupParamLength && commandStr.Mid(0,KTEFMinSetupParamLength).CompareF(KTEFSetUpParam) == 0)
       
  2097 					{
       
  2098 					if(command.CompareF(KTEFRunTestStepCommand) == 0 && !setupOptionSet)
       
  2099 						setupOptionSet = ETrue;
       
  2100 					else
       
  2101 						validScript = EFalse;
       
  2102 					}
       
  2103 				else if (commandStr.Length() > KTEFMinResultParamLength && commandStr.Mid(0,KTEFMinResultParamLength).CompareF(KTEFResult) == 0 && commandStr.Mid(KTEFMinResultParamLength).Length() <= KTEFMaxVerdictLength)
       
  2104 					{
       
  2105 					if (command.CompareF(KTEFRunTestStepCommand)  == 0)
       
  2106 						command.Set(KTEFRunTestStepResultCommand);
       
  2107 					else
       
  2108 						validScript = EFalse;
       
  2109 					}
       
  2110 				else if (commandStr.Length() >= KTEFMinPanicCodeParamLength && commandStr.Mid(0,KTEFMinPanicCodeParamLength).CompareF(KTEFPanicCode) == 0)
       
  2111 					{
       
  2112 					if ((command.CompareF(KTEFRunTestStepCommand) == 0 || command.CompareF(KTEFRunPanicStepResultCommand) == 0) && !panicCodeSet)
       
  2113 						{
       
  2114 						command.Set(KTEFRunPanicStepResultCommand);
       
  2115 						panicCodeSet=ETrue;
       
  2116 						}
       
  2117 					else
       
  2118 						validScript = EFalse;
       
  2119 					}
       
  2120 				else if (commandStr.Length() >= KTEFMinPanicStringParamLength && commandStr.Mid(0,KTEFMinPanicStringParamLength).CompareF(KTEFPanicString) == 0)
       
  2121 					{
       
  2122 					if ((command.CompareF(KTEFRunTestStepCommand) == 0 || command.CompareF(KTEFRunPanicStepResultCommand) == 0) && !panicStringSet)
       
  2123 						{
       
  2124 						command.Set(KTEFRunPanicStepResultCommand);
       
  2125 						panicStringSet = ETrue;
       
  2126 						}
       
  2127 					else
       
  2128 						validScript = EFalse;
       
  2129 					}
       
  2130 				else
       
  2131 					{
       
  2132 					if (commandStr.Length() >= KTEFMinHeapParamLength && commandStr.Mid(0,KTEFMinHeapParamLength).CompareF(KTEFHeap) == 0 && !heapValueSet)
       
  2133 						heapValueSet = ETrue;
       
  2134 					else if (commandStr.Length() >= KTEFMinOomParamLength && commandStr.Mid(0,KTEFMinOomParamLength).CompareF(KTEFOom) == 0 && !oomRequestSet)
       
  2135 						oomRequestSet = ETrue;
       
  2136 					else
       
  2137 						validScript = EFalse;
       
  2138 					}
       
  2139 				}
       
  2140 			else
       
  2141 				break;
       
  2142 			}
       
  2143 		}
       
  2144 		return validScript;
       
  2145 	}
       
  2146 
       
  2147 /**
       
  2148  * Return the next line in the script file
       
  2149  * @param aScriptLine - return line in the script file minus CRLF
       
  2150  * @return - True if line found, false for end of file.
       
  2151  */	
       
  2152 TBool CScriptControl::GetNextScriptLine(TPtrC& aScriptLine)
       
  2153 	{
       
  2154 	if(iScriptLex.Eos())
       
  2155 		{
       
  2156 		// Fix defect 1193337, check the value is zero or not. If zero, this should be no nested run script
       
  2157 		if((0 == iNestedNumRunScriptInLoop) && iLoop)
       
  2158 		// End defect 119337
       
  2159 			{
       
  2160 			_LIT(KEndRepeatNotFound,"The END_REPEAT command is not found");
       
  2161 			INFO_PRINTF1(KEndRepeatNotFound);
       
  2162 			}
       
  2163 		
       
  2164 		// Fix defect 119337, check if this is still in loop and this run script command is nested
       
  2165 		// decrease one shows that the nested number is decreased
       
  2166 		else if (iNestedNumRunScriptInLoop > 0 && iLoop)
       
  2167 			{
       
  2168 			--iNestedNumRunScriptInLoop;
       
  2169 			}
       
  2170 		// End defect 119337
       
  2171 		
       
  2172 		return EFalse;
       
  2173 		}
       
  2174 	// Mark the current script line to return
       
  2175 	iScriptLex.Mark();
       
  2176 	if(iLoop && !iCheckVar)
       
  2177 		{
       
  2178 		iStoreLoop.Assign(iScriptLex.RemainderFromMark());
       
  2179 		iTempStoreLoop.Assign(iScriptLex.RemainderFromMark());
       
  2180 		iCheckVar=ETrue;
       
  2181 		}
       
  2182 	// Place the lex marker for the next read
       
  2183 	while(!iScriptLex.Eos())
       
  2184 		{
       
  2185 		TChar peek = iScriptLex.Peek();
       
  2186 		if(peek == '\n')
       
  2187 			{
       
  2188 			iScriptLex.Inc();
       
  2189 			iCurrentScriptLineNumber++;
       
  2190 			break;
       
  2191 			}
       
  2192 		else
       
  2193 			iScriptLex.Inc();
       
  2194 		}
       
  2195 	aScriptLine.Set(iScriptLex.MarkedToken());
       
  2196 	if(aScriptLine.FindF(KTEFRunScriptCommand)!=KErrNotFound && iLoop)
       
  2197 		{
       
  2198 		// Fix defect 119337, add this integer shows a nested run script added.
       
  2199 		++iNestedNumRunScriptInLoop;
       
  2200 		// End Fix defect 119337
       
  2201 		}
       
  2202 	if(aScriptLine.Length() || !iScriptLex.Eos())
       
  2203 		return ETrue;
       
  2204 	else
       
  2205 		return EFalse;
       
  2206 	}
       
  2207 
       
  2208 /**
       
  2209  * Return the next line from script file which is to be looped
       
  2210  * @param aScriptLine - return line in the script file which is under loop minus CRLF
       
  2211  * @return -True if line is found else return false
       
  2212  * 
       
  2213  * If RUN_SCRIPT command has been encountered return the line from GetNextScriptLine Function
       
  2214  */
       
  2215 TBool CScriptControl::GetLoopScriptLine(TPtrC& aScriptLine)
       
  2216 	{
       
  2217 	// Fix defect 119337, check if the run script is nested
       
  2218 	if (0 != iNestedNumRunScriptInLoop)
       
  2219 	// End defect 119337
       
  2220 		return(GetNextScriptLine(aScriptLine));
       
  2221 	if(iStoreLoop.Eos())
       
  2222 		return EFalse;
       
  2223 	iStoreLoop.Mark();
       
  2224 	while(!iStoreLoop.Eos())
       
  2225 		{
       
  2226 		TChar peek = iStoreLoop.Peek();
       
  2227 		if(peek == '\n')
       
  2228 			{
       
  2229 			iStoreLoop.Inc();
       
  2230 			break;
       
  2231 			}
       
  2232 		else
       
  2233 			iStoreLoop.Inc();
       
  2234 		}
       
  2235 	aScriptLine.Set(iStoreLoop.MarkedToken());
       
  2236 	if(aScriptLine.Find(KTEFEndRepeat)!=KErrNotFound)
       
  2237 		{
       
  2238 		iStoreLoop.Assign(iTempStoreLoop);	
       
  2239 		}
       
  2240 	if(aScriptLine.FindF(KTEFRunScriptCommand)!=KErrNotFound)
       
  2241 		{
       
  2242 		// Fix defect 119337, add this integer shows a nested run script added.
       
  2243 		++iNestedNumRunScriptInLoop;
       
  2244 		// End defect 119337
       
  2245 		}
       
  2246 	if(aScriptLine.Length() || !iStoreLoop.Eos())
       
  2247 		return ETrue;
       
  2248 	else
       
  2249 		return EFalse;
       
  2250 	}
       
  2251 
       
  2252 /**
       
  2253  * @param aErr - The completion code
       
  2254  * @param aPanicString - Descriptor reference containing the panic string if a test were to panic
       
  2255  * @param aScriptLineNumber - Script line number used for printing result into log file
       
  2256  * @param aCommand - Command name also used for printing result into log file
       
  2257  * Called by a CClientControl or CProgramControl child object
       
  2258  */
       
  2259 void CScriptControl::TaskCompletion(TInt aErr, const TDesC& aPanicString, TInt aScriptLineNumber,const TDesC& aCommand,TBool aTaskCanComplete,TTEFItemArray* aItemArray)
       
  2260 	{
       
  2261 	if(aItemArray)
       
  2262 		{
       
  2263 		TVerdict err = Logger().LogBlock( aItemArray, aScriptLineNumber );
       
  2264 		
       
  2265 		// If no error was set on the server side (ie. a panic) then set
       
  2266 		//  it here with the post processing result
       
  2267 		if( EPass == aErr && aPanicString.Length() == 0 )
       
  2268 			{
       
  2269 			aErr = err;
       
  2270 			}
       
  2271 		}
       
  2272 	// Log the test step result to the output file
       
  2273 	LogResult((TVerdict)aErr, aPanicString, aScriptLineNumber, aCommand);
       
  2274 		
       
  2275 	if(aErr != KErrNone && aErr != KErrNotSupported && iBreakOnError)
       
  2276 		// Put this instance of the script engine into the closing state as we've
       
  2277 		// encountered the BREAK_ERROR_ON command.
       
  2278 		// KErrNotSupported is considered a benign error 
       
  2279 		{
       
  2280 		iState = EClosing;
       
  2281 		}
       
  2282 	iAsyncTasksOutstanding--;
       
  2283 	// Check the flag first then trigger our own RunL()
       
  2284 	if(aTaskCanComplete || iCanComplete)
       
  2285 		Complete(aErr);
       
  2286 	}
       
  2287 
       
  2288 /**
       
  2289  * Print the current script line to the console
       
  2290  */
       
  2291 void CScriptControl::PrintCurrentScriptLine() const
       
  2292 	{
       
  2293 	// Check we don't overflow
       
  2294 	TBuf<KMaxTestExecuteLogLineLength> output;
       
  2295 	if((iCurrentScriptLine.Length() + iScriptFile.Length() + 4 ) > output.MaxLength())
       
  2296 		{
       
  2297 		output.Copy(iAlteredScriptLine);
       
  2298 		Logger().PrintCurrentScriptLine(output);
       
  2299 		return;
       
  2300 		}
       
  2301 	// Copy the script filename. Handy for recursion
       
  2302 	output.Copy(iScriptFile);
       
  2303 	output.Append(KTEFSpace);
       
  2304 	// Append the script file line
       
  2305 	output.Append(iCurrentScriptLine);
       
  2306 	// Write to console
       
  2307 	ConsoleLogger().Console().Printf(KTEFStringFormat,&output);
       
  2308 
       
  2309 	Logger().PrintCurrentScriptLine(output);
       
  2310 	}
       
  2311 
       
  2312 /**
       
  2313  * Checks for commented commands and increments a counter for logging
       
  2314  */
       
  2315 TBool CScriptControl::CheckCommentedCommands() const
       
  2316 	{
       
  2317 	if(!iCurrentScriptLine.Length())
       
  2318 		return ETrue;
       
  2319 	
       
  2320 	TLex lex(iCurrentScriptLine);
       
  2321 	TPtrC token(lex.NextToken());
       
  2322 	if (!token.Length())
       
  2323 		return ETrue;
       
  2324 	
       
  2325 	TInt firstChar = iCurrentScriptLine[0];
       
  2326 	if(firstChar == '/')
       
  2327 		{
       
  2328 		TInt findRunTestStep;
       
  2329 		TInt findRunPanicStep;
       
  2330 		TInt findRunScript;
       
  2331 		TInt findRunProgram;
       
  2332 		TInt findRunWSProgram;
       
  2333 		TInt findStartTestBlock;
       
  2334 		findRunTestStep=iCurrentScriptLine.Find(KTEFRunTestStepCommand);
       
  2335 		findRunScript=iCurrentScriptLine.Find(KTEFRunScriptCommand);
       
  2336 		findRunPanicStep=iCurrentScriptLine.Find(KTEFRunPanicStepCommand);
       
  2337 		findRunProgram=iCurrentScriptLine.Find(KTEFRunProgramCommand);
       
  2338 		findRunWSProgram=iCurrentScriptLine.Find(KTEFRunWSProgramCommand);
       
  2339 		findStartTestBlock=iCurrentScriptLine.Find(KTEFStartTestBlock);
       
  2340 		if(findRunTestStep>0 || findRunScript>0 || findRunPanicStep>0 || findRunProgram>0 || findRunWSProgram>0 || findStartTestBlock>0 && !iStartLooping)
       
  2341 			{
       
  2342 			commentedCommandsCount++;
       
  2343 			}
       
  2344 		}
       
  2345 	if(firstChar == '\r' || firstChar == '\n' || firstChar == '#' || firstChar == '/')
       
  2346 		return ETrue;
       
  2347 	return EFalse;
       
  2348 	}
       
  2349 
       
  2350 /**
       
  2351  * @param aResult - Test Step result
       
  2352  * @param aPanicString - Descriptor containing the panic string if test were to panic
       
  2353  * @param aScriptLineNumber - The line in the script file
       
  2354  * @param aCommand - Command name whose result is set for logging
       
  2355  * Log a RUN_TEST_STEP, RUN_PANIC_STEP or RUN_PROGRAM result to file
       
  2356  */
       
  2357 void CScriptControl::LogResult(TVerdict aResult, const TDesC& aPanicString, TInt aScriptLineNumber,const TDesC& aCommand)
       
  2358 	{
       
  2359 	// Call the Logger()'s LogResult() routine to manipulate results of RUN_TEST_STEP command/variants
       
  2360 	// Also controls the fields for logging both HTML & XML logging
       
  2361 	Logger().LogResult(aResult, aPanicString, aScriptLineNumber, aCommand, iScriptFile, RFileFlogger::ESevrHigh);
       
  2362 	}
       
  2363 
       
  2364 /**
       
  2365  * Constructor
       
  2366  * @param RTestServ - Reference to a root RTestServer instance
       
  2367  * @param aCommand - Reference to a RUN_TEST_STEP script line
       
  2368  * @param MTaskCompletion - Reference to the parent completion interface
       
  2369  * @param aScriptLineNumber - The line in script file
       
  2370  * @param aLogger - Reference to the Logger class
       
  2371  * @param aLoopIndex - TInt reference that provides the loop index for the test. The value is 0 if not in loop.
       
  2372  * @param aTestCaseID - Descriptor containing the test case id, if test run is within a test case
       
  2373  * @param aScriptFilePath - The path of the script file being executed
       
  2374  * @param aSysDrive - Default system drive letter
       
  2375  * @param aTestSysDrive - System drive letter overwritten from testexecute.ini
       
  2376  */
       
  2377 CClientControl::CClientControl(RScriptTestServ& aServ,const TDesC& aCommand, MTaskCompletion& aCompletion, TInt aScriptLineNumber, CTestExecuteLogger& aLogger, TInt aLoopIndex, const TDesC& aTestCaseID, TPtrC& aScriptFilePath, const TDriveName& aSysDrive, const TDriveName& aTestSysDrive)
       
  2378 :	CTaskControlBase(aCommand,aCompletion,aScriptLineNumber,aLogger)
       
  2379 ,	iServ(aServ)
       
  2380 ,	iRetryCount(0)
       
  2381 ,	iLoopIndex(aLoopIndex)
       
  2382 ,	iTestCaseID(aTestCaseID)
       
  2383 ,	iBlockArrayPkg(NULL)
       
  2384 ,	iBlockArrayPtr(STATIC_CAST(TUint8*,NULL), 0)
       
  2385 ,	iScriptFilePath(aScriptFilePath)
       
  2386 ,	iDefaultSysDrive(aSysDrive)
       
  2387 ,	iTestSysDrive(aTestSysDrive)
       
  2388 	{
       
  2389 	// Extract the parameters to the test step and store them in the class
       
  2390 	GetStepParamsFromStepCommand();
       
  2391 	}
       
  2392 
       
  2393 CClientControl* CClientControl::NewL(	RScriptTestServ& aTestServ,
       
  2394 										const TDesC& aCommand,
       
  2395 										MTaskCompletion& aCompletion,
       
  2396 										TInt aScriptLineNumber,
       
  2397 										CTestExecuteLogger& aLogger,
       
  2398 										TInt aLoopIndex,
       
  2399 										const TDesC& aTestCaseID,
       
  2400 										const TDesC& aEndBlockCommand,
       
  2401 										TPtrC& aScriptFilePath,
       
  2402 										const TTEFItemArray& aBlockArray,
       
  2403 										const TDriveName& aSysDrive,
       
  2404 										const TDriveName& aTestSysDrive)
       
  2405 	{
       
  2406 	CClientControl* self = new (ELeave) CClientControl(	aTestServ,
       
  2407 														aCommand,
       
  2408 														aCompletion,
       
  2409 														aScriptLineNumber,
       
  2410 														aLogger,
       
  2411 														aLoopIndex,
       
  2412 														aTestCaseID,
       
  2413 														aScriptFilePath,
       
  2414 														aSysDrive,
       
  2415 														aTestSysDrive);
       
  2416 	CleanupStack::PushL(self);
       
  2417 	self->ConstructL(aEndBlockCommand, aBlockArray);
       
  2418 	CleanupStack::Pop();
       
  2419 	return self;
       
  2420 	}
       
  2421 
       
  2422 void CClientControl::ConstructL( const TDesC& aEndBlockCommand, const TTEFItemArray& aBlockArray )
       
  2423 	{
       
  2424 	iEndBlockCommand.Set( aEndBlockCommand );
       
  2425 	TTEFItemPkgBuf	itemPckgBuf;
       
  2426 	TInt			count = aBlockArray.Count();
       
  2427 	iBlockArrayPkg	= HBufC8::NewL( count * itemPckgBuf.Size() );
       
  2428 	iBlockArrayPtr.Set( iBlockArrayPkg->Des() );
       
  2429 	for( TInt i=0; i<count; i++ )
       
  2430 		{
       
  2431 		itemPckgBuf = aBlockArray.At(i);
       
  2432 		iBlockArrayPtr.Append( itemPckgBuf );
       
  2433 		}
       
  2434 	}
       
  2435 
       
  2436 TTEFItemArray* CClientControl::CreateBlockArrayLC()
       
  2437 	{
       
  2438 	TTEFItemPkgBuf	itemPckgBuf;
       
  2439 	TPtr8			blockArrayPtr(iBlockArrayPkg->Des());
       
  2440 	TInt			count = blockArrayPtr.Size()/itemPckgBuf.Size();
       
  2441 	TTEFItemArray*	itemArray = new (ELeave) TTEFItemArray( count );
       
  2442 	CleanupStack::PushL( itemArray );
       
  2443 
       
  2444 	TInt	pos = 0;
       
  2445 	for( TInt i=0; i<count; i++ )
       
  2446 		{
       
  2447 		itemPckgBuf.Copy(blockArrayPtr.Mid(pos, itemPckgBuf.Size()));
       
  2448 		pos += itemPckgBuf.Size();
       
  2449 		itemArray->AppendL( itemPckgBuf() );
       
  2450 		}
       
  2451 
       
  2452 	return itemArray;
       
  2453 	}
       
  2454 	
       
  2455 /**
       
  2456  * Destructor
       
  2457  */
       
  2458 CClientControl::~CClientControl()
       
  2459 	{
       
  2460 	iTimer.Cancel();
       
  2461 	iTimer.Close();
       
  2462 	
       
  2463 	if( iBlockArrayPkg )
       
  2464 		{
       
  2465 		delete iBlockArrayPkg;
       
  2466 		iBlockArrayPkg = NULL;
       
  2467 		}
       
  2468 	}
       
  2469 const TInt KDisableTimer = -1;
       
  2470 
       
  2471 /** 
       
  2472  * Test step has done. log the test result. 
       
  2473  */
       
  2474 void CClientControl::TestStepComplete()
       
  2475 	{
       
  2476 	iSession.Close();
       
  2477 	if(iBlockArrayPkg)
       
  2478 		{
       
  2479 		TTEFItemArray *itemArray = CreateBlockArrayLC();
       
  2480 		iParent.TaskCompletion(iStatus.Int(), iTaskExitCategory, iScriptLineNumber, iEndBlockCommand, iTaskCanComplete, itemArray);
       
  2481 		CleanupStack::PopAndDestroy(itemArray);
       
  2482 		}
       
  2483 	else
       
  2484 		{
       
  2485 		iParent.TaskCompletion(iStatus.Int(), iTaskExitCategory, iScriptLineNumber, iCommandLine, iTaskCanComplete);
       
  2486 		}
       
  2487 	}
       
  2488 
       
  2489 /**
       
  2490  * Pure virtual
       
  2491  * Test step handling state machine
       
  2492  * Kick'd() into by the parent CScriptControl object. Constructed in the EInit state
       
  2493  */
       
  2494 void CClientControl::RunL()
       
  2495 	{
       
  2496 	switch(iState)
       
  2497 		{
       
  2498 	case EInit	:
       
  2499 		User::LeaveIfError(iTimer.CreateLocal());
       
  2500 		if(iBlockArrayPkg)
       
  2501 			{
       
  2502 			User::LeaveIfError(iSession.Open(iServ, EFalse));		
       
  2503 			}
       
  2504 		else
       
  2505 			{
       
  2506 			User::LeaveIfError(iSession.Open(iServ, ETrue, iStepName));
       
  2507 			}
       
  2508 		// Whilst testing concurrent mode, the OS occasionally completes with
       
  2509 		// KErrServerBusy or KErrInUse.
       
  2510 		
       
  2511 		// clean up retry counter. case ERetry will using.
       
  2512 		iRetryCount = 0;
       
  2513 	case EServerRetry :
       
  2514 		{
       
  2515 		SetActive();
       
  2516 		
       
  2517 		// Set the heap size for creating the thread heap size
       
  2518 		iTaskExitCategory.Copy(iTaskHeapSize);
       
  2519 
       
  2520 		TBuf<5> checkOOMArgsBuf;
       
  2521 
       
  2522 		// Check if the step args has the OOM arguments already
       
  2523 		// A minimum 5 chars expected to check this : "OOM=0" or "OOM=1"
       
  2524 		if (iStepArgs.Length() >=5)
       
  2525 			{
       
  2526 			// Extract the first 5 chars from the start of step args string
       
  2527 			checkOOMArgsBuf.Copy(iStepArgs.Mid(0,5));
       
  2528 			}
       
  2529 
       
  2530 		_LIT(KOOMOne,"OOM=1");
       
  2531 		_LIT(KOOMZero,"OOM=0");
       
  2532 
       
  2533 		// Set the OOM argument after checking for existence of OOM param already
       
  2534 		if ((checkOOMArgsBuf.CompareF(KOOMOne) != KErrNone) && (checkOOMArgsBuf.CompareF(KOOMZero) != KErrNone))
       
  2535 			{
       
  2536 			// Insert the OOM arguments to the start of iStepArgs string
       
  2537 			if (iOOMRequestSet) // Set OOM=1 if !OOM is used in the RUN_TEST_STEP command
       
  2538 				iStepArgs.Insert(0,_L("OOM=1 "));
       
  2539 			else
       
  2540 				iStepArgs.Insert(0,_L("OOM=0 "));
       
  2541 			}
       
  2542 
       
  2543 		TBuf<KMaxTestExecuteCommandLength> checkSetUpArgsBuf;
       
  2544 
       
  2545 		// Check if the step args has the Setup arguments already
       
  2546 		// A min of 13 chars expected to check this : "OOM=0 !Setup=" or "OOM=1 !Setup="
       
  2547 		if (iStepArgs.Length() >=13)
       
  2548 			{
       
  2549 			// Extract 7 chars after skipping the OOM arguments "OOM=0 " or "OOM=1 "
       
  2550 			checkSetUpArgsBuf.Copy(iStepArgs.Mid(6,7));
       
  2551 			}
       
  2552 
       
  2553 		// Set the !Setup argument after checking for existence !Setup param already
       
  2554 		if (checkSetUpArgsBuf.CompareF(KTEFSetUpParam) != KErrNone)
       
  2555 			{
       
  2556 			// Retain the !Setup value from RUN_TEST_STEP command, if available
       
  2557 			if (iSetUpParamValue.Length() == KTEFZeroValue)
       
  2558 				{
       
  2559 				// If !Setup is not used in RUN_TEST_STEP, set the !Setup to TTestSetupState::ESetupNone (0)
       
  2560 				iSetUpParamValue.Copy(KTEFSetUpParam);
       
  2561 				iSetUpParamValue.AppendNum(TTestSetupState(ESetupNone));
       
  2562 				}
       
  2563 
       
  2564 			// Append a space and also include the loop index
       
  2565 			iSetUpParamValue.Append(KTEFSpace);
       
  2566 			// The loop index is 0 if the test is not in loop; loop index, otherwise
       
  2567 			iSetUpParamValue.AppendNum(iLoopIndex);
       
  2568 			iSetUpParamValue.Append(KTEFSpace);
       
  2569 			
       
  2570 			// Append the TestCaseID along with the Setup params
       
  2571 			iSetUpParamValue.Append(iTestCaseID);
       
  2572 			iSetUpParamValue.Append(KTEFSpace);
       
  2573 
       
  2574 			// Insert the !Setup arguments after the OOM arguments within the iStepArgs
       
  2575 			iStepArgs.Insert(6, iSetUpParamValue);
       
  2576 			}
       
  2577 		
       
  2578 		// Call the async client API to run the test step
       
  2579 		if(iBlockArrayPkg)
       
  2580 			{
       
  2581 			iSession.RunTestBlock(iStepArgs,iTaskExitCategory,iBlockArrayPtr,iStatus);
       
  2582 			}
       
  2583 		else
       
  2584 			{
       
  2585 			iSession.RunTestStep(iStepArgs,iTaskExitCategory,iStatus);
       
  2586 			}
       
  2587 		// Start a timer and provide it with our callback MTaskCompletion
       
  2588 		iState = ERunning;
       
  2589 		// Only start the timer if the disable value is not set
       
  2590 		if(iTaskTimeout != KDisableTimer)
       
  2591 			{
       
  2592 			iTaskTimer = CTaskTimer::NewL(*this);
       
  2593 			iTaskTimer->Timeout(iTaskTimeout);
       
  2594 			}
       
  2595 		}
       
  2596 		break;
       
  2597 
       
  2598 	case ERunning :
       
  2599 		{
       
  2600 		// We have been completed but we need to find out the source
       
  2601 		// If the timer expires it Aborts the server test step which results in
       
  2602 		// the RunTestStep call completing with KErrAbort.
       
  2603 		// When the timer expires it calls us back and we delete it then NULL it.
       
  2604 		if(iTaskTimer)
       
  2605 			{
       
  2606 			// The timer did not expire
       
  2607 			iTaskTimer->Cancel();
       
  2608 			delete iTaskTimer;
       
  2609 			iTaskTimer = NULL;
       
  2610 			}
       
  2611 		const TInt KRetry10Microseconds = 100000;
       
  2612 		const TInt KMaxRetryCount = 20;
       
  2613 		if(iStatus.Int() == KErrInUse && iRetryCount < KMaxRetryCount)
       
  2614 			{
       
  2615 			// OS (not the server) has rejected the call.
       
  2616 			// Timed retry
       
  2617 			// Noticed this one after panic's in shared data mode
       
  2618 			iState = EServerRetry;
       
  2619 			// Keep increasing the timeout
       
  2620 			iRetryCount++;
       
  2621 			SetActive();
       
  2622 			iLogger.LogExtra((TText8*)__FILE__,__LINE__,ESevrInfo,
       
  2623 					_L("Error Message :: The Task Is Retrying "));
       
  2624 			iTimer.After(iStatus,KRetry10Microseconds * iRetryCount);							
       
  2625 			}		
       
  2626 		else if(iStatus.Int() == KErrServerBusy)
       
  2627 			{
       
  2628 			// tempt to do test again when test server return busy.
       
  2629 			iState = EServerRetry;
       
  2630 			iRetryCount++;
       
  2631 			if(iRetryCount < KMaxRetryCount)
       
  2632 				{
       
  2633 				iState = EServerRetry;
       
  2634 				SetActive();
       
  2635 				iLogger.LogExtra((TText8*)__FILE__,__LINE__,ESevrInfo,
       
  2636 						_L("Error Message : Server return -16 = KErrServerBusy : Retrying %d"),iRetryCount);
       
  2637 				iTimer.After(iStatus,KRetry10Microseconds );
       
  2638 				}
       
  2639 			else//server alwayse busy. stop test. 
       
  2640 				{
       
  2641 				iLogger.LogExtra((TText8*)__FILE__,__LINE__,ESevrErr,
       
  2642 										_L("Error Message : Server Busy Retrying %d times. Test Teminated!"),iRetryCount);
       
  2643 				iParent.TaskCompletion(iStatus.Int(),iTaskExitCategory,iScriptLineNumber,iCommandLine,iTaskCanComplete);
       
  2644 
       
  2645 				iSession.Close();
       
  2646 				delete this;				
       
  2647 				}
       
  2648 			}			
       
  2649 		else
       
  2650 			{
       
  2651 			// see testserverbase.cpp::void SytemWideErrToTefErr(TInt &aErr). converting thi value.
       
  2652 			//Check the status, if the status is KErrTestExecuteInUse
       
  2653 			//then log the information  and change it back to 
       
  2654 			if(iStatus.Int() == KErrTestExecuteInUse)
       
  2655 				{
       
  2656 				//Convert the status back to KErrInUse
       
  2657 				iStatus=KErrInUse;
       
  2658 				}
       
  2659 			else if(iStatus.Int() == KErrTestExecuteServerBusy)
       
  2660 				{
       
  2661 				//this is not server really busy! we should change the server side iStatus back to -16
       
  2662 				//Convert the status back to KErrServerBusy
       
  2663 				iStatus = KErrServerBusy;
       
  2664 				}
       
  2665 			// Step completion
       
  2666 			TestStepComplete();
       
  2667 			delete this;
       
  2668 			}
       
  2669 		}
       
  2670 		break;
       
  2671 
       
  2672 	default:
       
  2673 		break;
       
  2674 		}
       
  2675 	}
       
  2676 
       
  2677 /**
       
  2678  * @param aError - TInt value representing error returned due to processing request from RunL()
       
  2679  * Handles the leave from RunL() and cleans up the allocated objects
       
  2680  * Also returns KErrNone upon sucessful handling of leave
       
  2681  */
       
  2682 TInt CClientControl::RunError(TInt aError)
       
  2683 	{
       
  2684 	if(iBlockArrayPkg)
       
  2685 		{
       
  2686 		TTEFItemArray*	itemArray = CreateBlockArrayLC();
       
  2687 		iParent.TaskCompletion(aError,iTaskExitCategory,iScriptLineNumber,iEndBlockCommand,iTaskCanComplete,itemArray);
       
  2688 		CleanupStack::PopAndDestroy( itemArray );
       
  2689 		}
       
  2690 	else
       
  2691 		{
       
  2692 		iParent.TaskCompletion(aError,iTaskExitCategory,iScriptLineNumber,iCommandLine,iTaskCanComplete);
       
  2693 		}
       
  2694 	delete this;
       
  2695 	return KErrNone;
       
  2696 	}
       
  2697 
       
  2698 /**
       
  2699  * Extract and save the timeout, step name and test step arguments
       
  2700  */
       
  2701 void CClientControl::GetStepParamsFromStepCommand()
       
  2702 	{
       
  2703 	TLex scriptLineLex(iCommandLine);
       
  2704 	TPtrC command(scriptLineLex.NextToken());
       
  2705 	if(command.CompareF(KTEFRunTestStepResultCommand) == 0)
       
  2706 		scriptLineLex.NextToken();
       
  2707 	else if(command.CompareF(KTEFRunPanicStepResultCommand) == 0)
       
  2708 		{
       
  2709 		scriptLineLex.NextToken();
       
  2710 		TPtrC panicString(scriptLineLex.NextToken());
       
  2711 		if(panicString.Left(1).Compare(KTEFOpenQuotes) == 0 && panicString.Right(1).Compare(KTEFOpenQuotes) != 0)
       
  2712 			{
       
  2713 			TBool validCommandLine(EFalse);
       
  2714 			while(!scriptLineLex.Eos() && !validCommandLine)
       
  2715 				{				
       
  2716 				panicString.Set(scriptLineLex.NextToken());
       
  2717 				if(panicString.Right(1).Compare(KTEFOpenQuotes) == 0)
       
  2718 					validCommandLine = ETrue;
       
  2719 				}
       
  2720 			}
       
  2721 		}
       
  2722 	else if(command.CompareF(KTEFRunTestStepCommand) == 0 ||
       
  2723 			command.CompareF(KTEFStartTestBlock) == 0 )
       
  2724 		{
       
  2725 		TInt firstChar;
       
  2726 		TPtrC commandStr;
       
  2727 		TBool panicStringComplete(ETrue);
       
  2728 		while(!scriptLineLex.Eos())
       
  2729 			{
       
  2730 			scriptLineLex.SkipSpace();
       
  2731 			scriptLineLex.Mark();
       
  2732 			
       
  2733 			TPtrC	token = scriptLineLex.NextToken();
       
  2734 			if( token.Length()>0 )
       
  2735 				{
       
  2736 				commandStr.Set( token );
       
  2737 				firstChar = commandStr[0];
       
  2738 				// 33 is the ascii value for "!". Used here for confirming switches
       
  2739 				if (firstChar != KTEFAsciiExclamation && panicStringComplete)
       
  2740 					{
       
  2741 					break;
       
  2742 					}
       
  2743 				if(commandStr.Length() > 14 && 
       
  2744 					commandStr.Mid(0,14).Compare(_L("!PanicString=\"")) == 0)
       
  2745 						panicStringComplete = EFalse;
       
  2746 				if(!panicStringComplete && commandStr.Right(1).Compare(KTEFOpenQuotes) == 0)
       
  2747 					panicStringComplete = ETrue;
       
  2748 				if (commandStr.Length() >= KTEFMinHeapParamLength && commandStr.Mid(0,KTEFMinHeapParamLength).CompareF(KTEFHeap) == 0)
       
  2749 					iTaskHeapSize.Set(commandStr.Mid(KTEFMinHeapParamLength));
       
  2750 				else if (commandStr.Length() >= KTEFMinSetupParamLength && commandStr.Mid(0,KTEFMinSetupParamLength).CompareF(KTEFSetUpParam) == 0)
       
  2751 					iSetUpParamValue.Copy(commandStr);
       
  2752 				else if (commandStr.Length() >= KTEFMinOomParamLength && commandStr.Mid(0,KTEFMinOomParamLength).CompareF(KTEFOom) == 0)
       
  2753 					{
       
  2754 					// Out of memory cannot be supported for UREL builds due to UHEAP macros
       
  2755 					// not being supported in UREL builds
       
  2756 					#if defined(_DEBUG)
       
  2757 						iOOMRequestSet = ETrue;
       
  2758 					#else
       
  2759 						iOOMRequestSet = EFalse;
       
  2760 						iLogger.LogExtra((TText8*)__FILE__,__LINE__,ESevrWarn,
       
  2761 								_L("Out of Memory Testing is not supported for UREL builds"));
       
  2762 					#endif
       
  2763 					}
       
  2764 				}
       
  2765 			}
       
  2766 		}
       
  2767 
       
  2768 	TLex timeoutLex;
       
  2769 	if(	command.CompareF(KTEFRunTestStepCommand) == 0 ||
       
  2770 		command.CompareF(KTEFStartTestBlock) == 0)
       
  2771 		timeoutLex = scriptLineLex.MarkedToken();
       
  2772 	else
       
  2773 		timeoutLex = scriptLineLex.NextToken();
       
  2774 	TInt err = timeoutLex.Val(iTaskTimeout);
       
  2775 	if(err)
       
  2776 		{
       
  2777 		// No timeout specified
       
  2778 		iTaskTimeout = KDefaultTimeoutSeconds;
       
  2779 		iStepName.Set(scriptLineLex.NextToken());
       
  2780 		}
       
  2781 	else
       
  2782 		{
       
  2783 		scriptLineLex.NextToken();
       
  2784 		if( command.CompareF(KTEFRunTestStepCommand) == 0 ||
       
  2785 			command.CompareF(KTEFRunTestStepResultCommand) == 0 ||
       
  2786 			command.CompareF(KTEFRunPanicStepResultCommand) == 0 ||
       
  2787 			command.CompareF(KTEFRunPanicStepCommand) == 0||
       
  2788 			command.CompareF(KTEFRunErrorStepResultCommand) == 0)
       
  2789 			{
       
  2790 			// Save the step name
       
  2791 			iStepName.Set(scriptLineLex.NextToken());
       
  2792 			}
       
  2793 		}
       
  2794 	// The rest is sent to the server
       
  2795 	scriptLineLex.SkipSpace();
       
  2796   	iStepArgs.Copy(iScriptFilePath.Mid(0,2));
       
  2797   	iStepArgs.Append(KTEFSpace);
       
  2798 	iStepArgs.Append(iDefaultSysDrive);
       
  2799 	iStepArgs.Append(KTEFSpace);
       
  2800 	iStepArgs.Append(iTestSysDrive);
       
  2801 	iStepArgs.Append(KTEFSpace);
       
  2802   	iStepArgs.Append(scriptLineLex.Remainder());
       
  2803 	}
       
  2804 
       
  2805 /**
       
  2806  * Callback from a CTaskTimer object
       
  2807  * Abort the test step, NULL the timer so we know that a timeout has caused test step completion
       
  2808  */
       
  2809 void CClientControl::TaskTimerCompletion()
       
  2810 	{
       
  2811 	delete iTaskTimer;
       
  2812 	iTaskTimer = NULL;
       
  2813 	iSession.AbortTestStep();
       
  2814 	}
       
  2815 
       
  2816 /**
       
  2817  * Constructor
       
  2818  * @param aCompletion - Reference to a callback method in the CClientControl parent object
       
  2819  */
       
  2820 CTaskTimer::CTaskTimer(MTaskTimerCompletion& aCompletion) : CTimer(EPriorityUserInput), iParent(aCompletion)
       
  2821 	{
       
  2822 	CActiveScheduler::Add(this);
       
  2823 	}
       
  2824 
       
  2825 /**
       
  2826  * Iterate till the timer has expired and callback into the parent
       
  2827  */
       
  2828 void CTaskTimer::RunL()
       
  2829 	{
       
  2830 	if (iTimesAfter > 0 || iSecondsRemaining > 0)
       
  2831 		{
       
  2832 		RunTimeout(); // Function call implementing the After() routines
       
  2833 		}
       
  2834 	else
       
  2835 		{
       
  2836 		iParent.TaskTimerCompletion(); // Call the completion routine for the timeout
       
  2837 		}
       
  2838 	}
       
  2839 
       
  2840 /**
       
  2841  * Implements a timeout based using CTimer::After()
       
  2842  * Modified for handling huge timeout values
       
  2843  * @param aSeconds - Timeout value in seconds
       
  2844  */
       
  2845  void CTaskTimer::Timeout(TInt aSeconds)
       
  2846 	{
       
  2847 	iTimesAfter = aSeconds/60; // Convert the aSeconds to equivalent minutes
       
  2848 	iSecondsRemaining = (aSeconds - (iTimesAfter*60)); // Remainder of seconds after converting to equivalent minutes
       
  2849 	RunTimeout();
       
  2850 	}
       
  2851 
       
  2852 /**
       
  2853  * Implements the After() routines for the timeout value specified
       
  2854  * The call is initiated from Timeout() & is iterated from the RunL()
       
  2855  */
       
  2856 void CTaskTimer::RunTimeout()
       
  2857 	{
       
  2858 	if (iTimesAfter > 0)
       
  2859 		{
       
  2860 		After(60*1000000); // Call After() for every minute until iTimesAfter is >0
       
  2861 		iTimesAfter--;
       
  2862 		}
       
  2863 	else if (iSecondsRemaining > 0)
       
  2864 		{
       
  2865 		After(iSecondsRemaining*1000000); // Call After() for remainder of microsec
       
  2866 		iSecondsRemaining = 0;
       
  2867 		}
       
  2868 	}
       
  2869 
       
  2870 /**
       
  2871  * Destructor
       
  2872  */
       
  2873 CTaskTimer::~CTaskTimer()
       
  2874 	{
       
  2875 	}
       
  2876 
       
  2877 /*
       
  2878  * @param aCompletion - Reference to a callback method in a CTaskControlBase parent object
       
  2879  * Two phase contruction
       
  2880  */
       
  2881 CTaskTimer* CTaskTimer::NewL(MTaskTimerCompletion& aCompletion)
       
  2882 	{
       
  2883 	CTaskTimer* taskTimer = new(ELeave) CTaskTimer(aCompletion);
       
  2884 	CleanupStack::PushL(taskTimer);
       
  2885 	// We have to call the base class second phase constructor
       
  2886 	taskTimer->ConstructL();
       
  2887 	CleanupStack::Pop(taskTimer);
       
  2888 	return taskTimer;
       
  2889 	}
       
  2890 
       
  2891 /**
       
  2892  * @param aCommand - Command for the derived class
       
  2893  * @param aCompletion - Reference to the parent class callback method
       
  2894  * @param aScriptLineNumber - The script file line number of this command
       
  2895  * @param aLogger - Reference to a Flogger derived session
       
  2896  * Constructor - Just initialise the abstract class data
       
  2897  */
       
  2898 CTaskControlBase::CTaskControlBase(const TDesC& aCommand, MTaskCompletion& aCompletion,TInt aScriptLineNumber, CTestExecuteLogger& aLogger) :
       
  2899 	iCommandLine(aCommand),
       
  2900 	iParent(aCompletion),
       
  2901 	iScriptLineNumber(aScriptLineNumber),
       
  2902 	iLogger(aLogger),
       
  2903 	iTaskTimer(NULL)
       
  2904 	{
       
  2905 	}
       
  2906 
       
  2907 /**
       
  2908  * Destructor
       
  2909  */
       
  2910 CTaskControlBase::~CTaskControlBase()
       
  2911 	{
       
  2912 	}
       
  2913 
       
  2914 /**
       
  2915  * @param aCommand - Command line for the program (Store in base class)
       
  2916  * @param aCompletion - Reference to the parent class callback method (Store in base class)
       
  2917  * @param aScriptLineNumber - The script file line number of this command (Store in base class)
       
  2918  * @param aLogger - Reference to a Flogger derived session (Store in base class)
       
  2919  * @param aWSProgRun - Boolean value used for identifying window server programs
       
  2920  */
       
  2921 CProgramControl::CProgramControl(const TDesC& aCommand,MTaskCompletion& aCompletion,TInt aScriptLineNumber, CTestExecuteLogger& aLogger, TBool aWSProgRun) : CTaskControlBase(aCommand,aCompletion,aScriptLineNumber,aLogger),
       
  2922 	iState(EInit)
       
  2923 	{
       
  2924  	// Extract the program arguments from the command line
       
  2925 	GetProgramArgsFromCommand();
       
  2926 
       
  2927 	// Try to connect to the window server (if available)
       
  2928 	iWSProgRun = aWSProgRun;
       
  2929   	#if !defined TEF_LITE
       
  2930 	if( iWSProgRun )
       
  2931 		{
       
  2932 		iWs.Connect();
       
  2933 		}
       
  2934   	#else
       
  2935   	// Always set to false if TEF_LITE is set
       
  2936   	//iWSProgRun = EFalse;
       
  2937   	#endif
       
  2938 	}
       
  2939 
       
  2940 /**
       
  2941  * Destructor
       
  2942  */
       
  2943 CProgramControl::~CProgramControl()
       
  2944 	{
       
  2945 	#if !defined TEF_LITE
       
  2946 	if( iWSProgRun )
       
  2947 		{
       
  2948 		iWs.Close();
       
  2949 		}
       
  2950 	#endif
       
  2951 	}
       
  2952 
       
  2953 /**
       
  2954  * Simple State machine.
       
  2955  * Kick()'d into by parent object.
       
  2956  * Runs an executable in its own process.
       
  2957  */
       
  2958 void CProgramControl::RunL()
       
  2959 	{
       
  2960 	switch(iState)
       
  2961 		{
       
  2962 	case EInit	:
       
  2963 		{
       
  2964 		TRAPD(err,RunProgramL());
       
  2965 		if(err != KErrNone)
       
  2966 			{
       
  2967 			// Special case where the executable has already completed
       
  2968 			if( err == KErrCompletion )
       
  2969 				{
       
  2970 				// Reset the error code
       
  2971 				err = KErrNone;
       
  2972 				}
       
  2973 			// Failed so complete immediately
       
  2974 			iParent.TaskCompletion(err,iTaskExitCategory,iScriptLineNumber,iCommandLine,iTaskCanComplete);
       
  2975 			delete this;
       
  2976 			}
       
  2977 		else
       
  2978 			{
       
  2979 			SetActive();
       
  2980 			iState = ERunning;
       
  2981 			// Only start the timer if the disable value is not set
       
  2982 			if(iTaskTimeout != KDisableTimer)
       
  2983 				{
       
  2984 				iTaskTimer = CTaskTimer::NewL(*this);
       
  2985 				iTaskTimer->Timeout(iTaskTimeout);
       
  2986 				}
       
  2987 			if (iProgRenamed == 1)
       
  2988  				{
       
  2989   				iLogger.LogExtra((TText8*)__FILE__,__LINE__,ESevrInfo,
       
  2990   					_L(".EXE not found - .APP run instead"));
       
  2991   				}
       
  2992 
       
  2993 			}
       
  2994 		}
       
  2995 		break;
       
  2996 
       
  2997 	case ERunning :
       
  2998 		{
       
  2999 		if(iTaskTimer)
       
  3000 			{
       
  3001 			// The timer did not expire
       
  3002 			iTaskTimer->Cancel();
       
  3003 			delete iTaskTimer;
       
  3004 			iTaskTimer = NULL;
       
  3005 			}
       
  3006 		// Set up the panic string if the program panicked
       
  3007 		if( !iWSProgRun )
       
  3008 			{
       
  3009 			if(iProgram.ExitType() == EExitPanic)
       
  3010 				{
       
  3011 				iTaskExitCategory.Copy(KPanicEquals);
       
  3012 				iTaskExitCategory.Append(iProgram.ExitCategory());
       
  3013 				}
       
  3014 			else if (iProgram.ExitType() == EExitPending)
       
  3015 				{
       
  3016 				iProgram.Kill(KErrAbort);
       
  3017 				iLogger.LogExtra((TText8*)__FILE__,__LINE__,ESevrWarn,
       
  3018 				  	_L("Program has been killed as the timeout is achieved."));
       
  3019 				}
       
  3020 			iProgram.Close();
       
  3021 			}
       
  3022   		#if !defined TEF_LITE
       
  3023 		else
       
  3024 			{
       
  3025 			if(iProgramWS.ExitType() == EExitPanic)
       
  3026 				{
       
  3027 				iTaskExitCategory.Copy(KPanicEquals);
       
  3028 				iTaskExitCategory.Append(iProgramWS.ExitCategory());
       
  3029 				}
       
  3030 			
       
  3031 			// Close the application
       
  3032 			TInt prev = 0;
       
  3033 			TInt winGid = iWs.FindWindowGroupIdentifier(prev, iProgramWS.Id());
       
  3034 			TApaTask task(iWs);
       
  3035 			task.SetWgId(winGid);
       
  3036 			if( task.Exists() )
       
  3037 				{
       
  3038 				task.KillTask();
       
  3039 				}
       
  3040 			iProgramWS.Close();
       
  3041 			}
       
  3042 		#endif
       
  3043 		
       
  3044 		// Complete to the parent object.
       
  3045 		iParent.TaskCompletion(iStatus.Int(),iTaskExitCategory,iScriptLineNumber,iCommandLine,iTaskCanComplete);
       
  3046 		delete this;
       
  3047 		}
       
  3048 		break;
       
  3049 
       
  3050 	default:
       
  3051 		break;
       
  3052 		}
       
  3053 	}
       
  3054 
       
  3055 /**
       
  3056  * Retrieve the program arguments from the script line.
       
  3057  */
       
  3058 void CProgramControl::GetProgramArgsFromCommand()
       
  3059 	{
       
  3060 	TLex scriptLineLex(iCommandLine);
       
  3061 	// Skip the RUN_PROGRAM command
       
  3062 	scriptLineLex.NextToken();
       
  3063 	TLex lex(scriptLineLex);
       
  3064 	// Get the timer if it's been included
       
  3065 	TLex timeoutLex(lex.NextToken());
       
  3066 	TInt err = timeoutLex.Val(iTaskTimeout);
       
  3067 	if(err)
       
  3068 		// No timeout specified
       
  3069 		iTaskTimeout = KDefaultTimeoutSeconds;
       
  3070 	else
       
  3071 		// Skip the timeout value
       
  3072 		scriptLineLex.NextToken();
       
  3073 	scriptLineLex.SkipSpace();
       
  3074 	// Use the rest
       
  3075 	iProgramArgs.Set(scriptLineLex.Remainder());
       
  3076 	}
       
  3077 
       
  3078 /**
       
  3079  * Task timer expired
       
  3080  */
       
  3081 void CProgramControl::TaskTimerCompletion()
       
  3082 	{
       
  3083 	delete iTaskTimer;
       
  3084 	iTaskTimer = NULL;
       
  3085 		if( !iWSProgRun )
       
  3086 			{
       
  3087 			iProgram.RendezvousCancel(iStatus);
       
  3088 			}
       
  3089 		#if !defined TEF_LITE
       
  3090 		else
       
  3091 			{
       
  3092 			iProgramWS.RendezvousCancel(iStatus);
       
  3093 			}
       
  3094 		#endif
       
  3095 		// We ORPHAN the process
       
  3096 		// Our RunL() gets called immediately
       
  3097 		// Kill requires KillAnyProcess capability
       
  3098 		// ups the stakes as regards CAPABILITY
       
  3099 	}
       
  3100 
       
  3101 /**
       
  3102  * Processes RUN_PROGRAM command arguments and starts the program
       
  3103  */
       
  3104 void CProgramControl::RunProgramL()
       
  3105 	{
       
  3106 	TLex lex(iProgramArgs);
       
  3107 	//	Get program name.	
       
  3108 	lex.Mark();
       
  3109 	lex.NextToken();
       
  3110 #if   !defined TEF_LITE
       
  3111 	// Set up the program arguments
       
  3112 	TBuf<KMaxTestExecuteCommandLength> programArgs(lex.Remainder());
       
  3113 	programArgs.Trim();
       
  3114 	iProgramArgs.Set(programArgs);
       
  3115 
       
  3116 	if( !iWSProgRun )
       
  3117 		{
       
  3118 		// Create the Process
       
  3119 		User::LeaveIfError(iProgram.Create(lex.MarkedToken(),iProgramArgs));
       
  3120 		}
       
  3121 	else
       
  3122 		{
       
  3123  		if( !IsWindowServerAvailable() )
       
  3124  			{
       
  3125  			User::Leave(KErrNotSupported);
       
  3126  			}
       
  3127  
       
  3128  		// Launch the application using RApaLsSession
       
  3129 		// This will only work if there is a window server available.
       
  3130 		// It allows TechView apps to be launched
       
  3131 		CApaCommandLine *cmd=CApaCommandLine::NewLC();
       
  3132 		cmd->SetExecutableNameL(lex.MarkedToken());
       
  3133 		
       
  3134 		// Set the program arguments
       
  3135 		cmd->SetDocumentNameL( iProgramArgs );
       
  3136 		cmd->SetCommandL(EApaCommandRun);
       
  3137 
       
  3138 		User::LeaveIfError( iApaLsSess.Connect() );
       
  3139 		// startup
       
  3140 		TThreadId thread;
       
  3141 		User::LeaveIfError( iApaLsSess.StartApp(*cmd, thread) );
       
  3142 		TInt ret = iProgramWS.Open(thread);
       
  3143 		if( ret != KErrNone )
       
  3144 			{
       
  3145 			if( ret == KErrNotFound )
       
  3146 				{
       
  3147 				// If the thread can not be found then it has already completed
       
  3148 				// Leave with a relavent error
       
  3149 				User::Leave(KErrCompletion);
       
  3150 				}
       
  3151 			User::Leave(ret);
       
  3152 			}
       
  3153 
       
  3154 		//cleanup
       
  3155 		iApaLsSess.Close();
       
  3156 		CleanupStack::PopAndDestroy();
       
  3157 		}
       
  3158 #else
       
  3159 /**
       
  3160  * Kick off an exe in its own pocess
       
  3161  * completes asynchronously
       
  3162  */
       
  3163 	
       
  3164 	if (iWSProgRun)  //TEF lite doesn't support RUN_WS_PROGRAM.
       
  3165 		{
       
  3166 		iLogger.LogExtra((TText8*)__FILE__,__LINE__,ESevrErr,
       
  3167 				_L("Error Message :: TEF lite doesn't support RUN_WS_PROGRAM."));
       
  3168 		User::Leave(EFail);
       
  3169 		}
       
  3170 	
       
  3171 	// Set up the program arguments
       
  3172 	TPtrC commandLine(lex.Remainder());
       
  3173 	iProgramArgs.Set(commandLine);
       
  3174 	// Create the Process
       
  3175 	User::LeaveIfError(iProgram.Create(lex.MarkedToken(),iProgramArgs));
       
  3176 
       
  3177 #endif 
       
  3178 	if( !iWSProgRun )
       
  3179 		{
       
  3180 		iProgram.Rendezvous(iStatus);
       
  3181 		iProgram.Resume();
       
  3182 		}
       
  3183 	#if !defined TEF_LITE
       
  3184 	else
       
  3185 		{
       
  3186 		iProgramWS.Rendezvous(iStatus);
       
  3187 		}
       
  3188 	#endif
       
  3189 	}
       
  3190 
       
  3191 /**
       
  3192  * @param aServerName - Test server to connect to
       
  3193  * @param aSharedData - Flag for shared data mode session with test server
       
  3194  * Connect to the test server
       
  3195  * EKA2 version requires a just in time debug flag for the test server process
       
  3196  * This is read from the command line.
       
  3197  * Base class connect acts on this.
       
  3198  */
       
  3199 TInt RScriptTestServ::Connect(const TDesC& aServerName,TBool aSharedData)
       
  3200 	{
       
  3201 	iSharedData = aSharedData;
       
  3202 	// Parse the command line for -d
       
  3203 	TBuf<KMaxTestExecuteCommandLength> commandLine;
       
  3204 	if(User::CommandLineLength() > commandLine.MaxLength())
       
  3205 		User::Leave(KErrTooBig);
       
  3206 	User::CommandLine(commandLine);
       
  3207 	TLex flagLex(commandLine);
       
  3208 	// Default to false
       
  3209 	TBool aJustInTime(EFalse);
       
  3210 	while(!flagLex.Eos())
       
  3211 		{
       
  3212 		TPtrC token(flagLex.NextToken());
       
  3213 		if(token == KTestExecuteCommandLineFlagDebugMode)
       
  3214 			{
       
  3215 			aJustInTime = ETrue;
       
  3216 			break;
       
  3217 			}
       
  3218 		}
       
  3219 	return RTestServ::Connect(aServerName,aJustInTime);
       
  3220 	
       
  3221 	}
       
  3222 
       
  3223 /**
       
  3224  * Copies the integer value read from ini file to the reference integer passed to the function
       
  3225  * @param aConfigData - Pointer to CIniData object used for reading data from ini file
       
  3226  * @param aConfigSection - Descriptor value describing the section name within an ini file for reading
       
  3227  * @param aSharedData - KeyName within a section where the input data is available in ini file
       
  3228  * @param aSharedDataNum - Reference integer variable for collecting the value at the keyname specified
       
  3229  * @Leave system wide errors
       
  3230  */
       
  3231 void CScriptControl::FindValueL(CIniData* aConfigData, TPtrC aConfigSection, TPtrC aSharedData, TInt& aSharedDataNum)
       
  3232 	{
       
  3233 	aConfigData->FindVar(aConfigSection, aSharedData, aSharedDataNum);
       
  3234 	if (aSharedDataNum == 0)
       
  3235 		{
       
  3236 		User::Leave(KErrGeneral);
       
  3237 		}
       
  3238 	}
       
  3239 
       
  3240 /**
       
  3241  * Copies the descriptor value read from ini file to the reference descriptor passed to the function
       
  3242  * @param aConfigData - Pointer to CIniData object used for reading data from ini file
       
  3243  * @param aConfigSection - Descriptor value describing the section name within an ini file for reading
       
  3244  * @param aSharedData - KeyName within a section where the input data is available in ini file
       
  3245  * @param aSharedDataName - Reference descriptor variable for collecting the value at the keyname specified
       
  3246  * @Leave system wide errors
       
  3247  */
       
  3248 void CScriptControl::FindValueL(CIniData* aConfigData, TPtrC aConfigSection, TPtrC aSharedData, TPtrC& aSharedDataName)
       
  3249 	{
       
  3250 	User::LeaveIfError(aConfigData->FindVar(aConfigSection, aSharedData, aSharedDataName));
       
  3251 	TPtrC blankString(KNull);
       
  3252 	if (aSharedDataName.CompareF(blankString) == 0)
       
  3253 		{
       
  3254 		User::Leave(KErrGeneral);
       
  3255 		}
       
  3256 	}
       
  3257 
       
  3258 /**
       
  3259  * Creates one or more shared objects based on the inputs provided in ini file
       
  3260  * @Leave system wide errors
       
  3261  */
       
  3262 void CScriptControl::CreateSharedObjectsFromScriptLineL()
       
  3263 	{
       
  3264 	CIniData* configData = NULL;
       
  3265 	TInt err = 0;
       
  3266 	TInt sharedDataCount = 0;
       
  3267 	TPtrC sharedDataName;
       
  3268 
       
  3269 	// Sets the boolean to ETrue
       
  3270 	// Avoids SHARED_DATA command being called more than once
       
  3271 	iIsSharedData = ETrue;
       
  3272 	
       
  3273 	//It copies the current line from the script to TLex object
       
  3274 	TLex shareLex(iCurrentScriptLine);
       
  3275 
       
  3276 	//reads the next word
       
  3277 	shareLex.NextToken();
       
  3278 
       
  3279 	TPtrC configFile(shareLex.NextToken());
       
  3280 
       
  3281 	TPtrC configSection(shareLex.NextToken());
       
  3282 
       
  3283 	if(configFile.Length())
       
  3284 		{
       
  3285 		// Create instance of CIniData for reading ini input
       
  3286 		TRAP(err,configData = CIniData::NewL(configFile));
       
  3287 		}
       
  3288 	if(err != KErrNone)
       
  3289 		{
       
  3290 		ERR_PRINTF1(KTEFErrorReadingIni);
       
  3291 		User::Leave(err);
       
  3292 		}
       
  3293 	if(configData)
       
  3294 		{
       
  3295 		CleanupStack::PushL(configData);
       
  3296 		TPtrC sharedDataNumberKey(KTEFSharedDataNum);
       
  3297 		// Read the ini file for number of shared objects to be created
       
  3298 		// Store the value into variable sharedDataCount
       
  3299 		TRAP(err,FindValueL(configData,configSection,sharedDataNumberKey,sharedDataCount));
       
  3300 		if (err != KErrNone)
       
  3301 			{
       
  3302 			ERR_PRINTF1(KTEFErrNumberOfShareNotInIni);
       
  3303 			}
       
  3304 		else
       
  3305 			{
       
  3306 			// If ini input is available for number of shared data
       
  3307 			// Run a loop to read individual shared objects name
       
  3308 			for (TInt i=1; i<=sharedDataCount; i++)
       
  3309 				{
       
  3310 				TBuf<20> keyName(KTEFSharedName);
       
  3311 
       
  3312 				keyName.AppendNum(i);
       
  3313 
       
  3314 				keyName.ZeroTerminate();
       
  3315 
       
  3316 				TPtrC sharedDataNameKey(keyName);
       
  3317 
       
  3318 				sharedDataName.Set(KNull);
       
  3319 
       
  3320 				// Read ini file for i th object name
       
  3321 				TRAP(err,FindValueL(configData,configSection,sharedDataNameKey,sharedDataName));
       
  3322 				if (err != KErrNone)
       
  3323 					{
       
  3324 					ERR_PRINTF2(KTEFErrShareNameNotInIni,i);
       
  3325 					}
       
  3326 				else
       
  3327 					{
       
  3328 					// Number of shared data is limited to the value set in the constant KTEFMaxSharedArraySize
       
  3329 					// The constant is defined in ScriptEngine.h which can be extended from there
       
  3330 					if (iSharedDataNum < KTEFMaxSharedArraySize)
       
  3331 						{
       
  3332 						// If ini input is available for i th object name
       
  3333 						// Creating template class object for sharing the object
       
  3334 						CTestSharedData* sharedObject = NULL;
       
  3335 
       
  3336 						CTEFSharedData<CTestSharedData>* sharedData1 = NULL;
       
  3337 						TRAP(err,sharedData1 = CTEFSharedData<CTestSharedData>::NewL(sharedObject, KTEFSharedDataSize, sharedDataName));
       
  3338 						if (err != KErrNone)
       
  3339 							{
       
  3340 							User::Leave(err);
       
  3341 							}
       
  3342 						else
       
  3343 							{
       
  3344 							sharedData1->EnterCriticalSection();
       
  3345 							sharedObject->Construct();
       
  3346 							sharedData1->ExitCriticalSection();
       
  3347 							// Adding the template object to an array
       
  3348 							iSharedDataArray[iSharedDataNum] = sharedData1;
       
  3349 							// Counting the number of objects created
       
  3350 							// destructor can destroy the objects based on this count
       
  3351 							iSharedDataNum++;
       
  3352 							}
       
  3353 						}
       
  3354 					else
       
  3355 						{
       
  3356 						WARN_PRINTF1(KTEFMaxNumberOfSharedObjectsReached);
       
  3357 						}
       
  3358 					}
       
  3359 				}
       
  3360 			}
       
  3361 		// Cleanup CInidata object
       
  3362 		CleanupStack::PopAndDestroy(configData);
       
  3363 		}
       
  3364 	}
       
  3365 	
       
  3366 /**
       
  3367  * Parses the test block header
       
  3368  * @Return ETrue if pass ok else EFalse
       
  3369  */
       
  3370 // Fix defect 118337, check the configuration file exists or not, and set the flag.
       
  3371 TBool CScriptControl::ParseTestBlockHeader()
       
  3372 	{
       
  3373 	TLex lex(iCurrentScriptLine);
       
  3374 	TPtrC token = lex.NextToken();
       
  3375 	TInt paraCount = 1;
       
  3376 	const TInt KLeastBlockHeaderParaCount = 4;
       
  3377 	_LIT(KLegacySysDrive, "C:");
       
  3378 	_LIT(KDefaultIniFilePath, "\\System\\Data\\");
       
  3379 	
       
  3380 	while (!lex.Eos())
       
  3381 		{
       
  3382 		token.Set(lex.NextToken());
       
  3383 		lex.SkipSpace();
       
  3384 		++paraCount;
       
  3385 		}
       
  3386 	
       
  3387 	if (paraCount < KLeastBlockHeaderParaCount)
       
  3388 		{
       
  3389 		_LIT(KBadError, "Bad error syntax!");
       
  3390 		ERR_PRINTF1(KBadError);
       
  3391 		return EFalse;
       
  3392 		}
       
  3393 
       
  3394 	TFileName defaultIniFilePath(KLegacySysDrive);
       
  3395 	defaultIniFilePath.Append(KDefaultIniFilePath);
       
  3396 	
       
  3397 	iFS.Connect();
       
  3398 	TFindFile fileFind(iFS);
       
  3399 	TInt ret = fileFind.FindByDir(token, defaultIniFilePath);
       
  3400 	iFS.Close();
       
  3401 	if (KErrNotFound == ret)
       
  3402 		{
       
  3403 		_LIT(KFileNotFound, "Configuration File %S Not Found!");
       
  3404 		ERR_PRINTF2(KFileNotFound, &token);
       
  3405 		return EFalse;
       
  3406 		}
       
  3407 	return ETrue;
       
  3408 	}
       
  3409 // End defect 118337
       
  3410 
       
  3411 /**
       
  3412  * Parses the test block and populates the iBlockArray
       
  3413  * @Leave system wide errors
       
  3414  */
       
  3415 void CScriptControl::ParseTestBlockL( TTEFItemArray& aItemArray )
       
  3416 	{
       
  3417 	// Iterate through the commands contained within the test block
       
  3418 	//  and append them to the itemArray.
       
  3419 	TPtrC	startBlockScriptLine	= iCurrentScriptLine;
       
  3420 	TInt	startBlockLineNumber 	= iCurrentScriptLineNumber;
       
  3421 	
       
  3422 	TBool parseResult = ParseTestBlockHeader();
       
  3423 	
       
  3424 	FOREVER
       
  3425 		{
       
  3426 		TTEFBlockItem	blockItem;
       
  3427 		
       
  3428 		// Read in the next script line
       
  3429 		TBool	scriptLineRes = EFalse;
       
  3430 		if( !iStartLooping )
       
  3431 			{
       
  3432 			scriptLineRes = GetNextScriptLine(iCurrentScriptLine);
       
  3433 			}
       
  3434 		else
       
  3435 			{
       
  3436 			scriptLineRes = GetLoopScriptLine(iCurrentScriptLine);
       
  3437 			}
       
  3438 		
       
  3439 		if( !scriptLineRes )
       
  3440 			{
       
  3441 			_LIT( KTEFEoF, "Unexpectedly hit the end of the file" );
       
  3442 			ERR_PRINTF1( KTEFEoF );
       
  3443 			TExitCategoryName  blankPanicString;
       
  3444 			LogResult(EFail, blankPanicString, startBlockLineNumber, startBlockScriptLine);
       
  3445 			User::Leave( KErrEof );
       
  3446 			}
       
  3447 
       
  3448 		// Strip off any trailling comment
       
  3449 		TInt offset = iCurrentScriptLine.Find(KTEFComment);
       
  3450 		if( offset != KErrNotFound )
       
  3451 			{
       
  3452 			iCurrentScriptLine.Set( iCurrentScriptLine.Mid(0, offset) );
       
  3453 			}
       
  3454 
       
  3455 		TLex lex(iCurrentScriptLine);
       
  3456 		TPtrC token(lex.NextToken());
       
  3457 		
       
  3458 		// Populate the blockItem with the data required for each command
       
  3459 		
       
  3460 		// CREATE_OBJECT <object type> <object name section>
       
  3461 		if(	0 == token.CompareF(KTEFCreateObject) )
       
  3462 			{
       
  3463 			blockItem.iItemType		= ETEFCreateObject;
       
  3464 			blockItem.iObjectType	= lex.NextToken().Left(KTEFMaxNameLength);
       
  3465 			blockItem.iSection		= lex.NextToken().Left(KTEFMaxNameLength);
       
  3466 			}
       
  3467 		// RESTORE_OBJECT <object type> <object name section>
       
  3468 		else if( 0 == token.CompareF(KTEFRestoreObject) )
       
  3469 			{
       
  3470 			blockItem.iItemType		= ETEFRestoreObject;
       
  3471 			blockItem.iObjectType	= lex.NextToken().Left(KTEFMaxNameLength);
       
  3472 			blockItem.iSection		= lex.NextToken().Left(KTEFMaxNameLength);
       
  3473 			}
       
  3474 		// COMMAND [Error TEFParameter] <object name section> <function name> [section]
       
  3475 		else if( 0 == token.CompareF(KTEFCommand) )
       
  3476 			{
       
  3477 			blockItem.iItemType = ETEFCommand;
       
  3478 			TPtrC param = lex.NextToken().Left(KTEFMaxNameLength);
       
  3479 			
       
  3480 			if( param.Length() > 0 )
       
  3481 				{
       
  3482 				while( param[0] == KTEFAsciiExclamation )
       
  3483 					{
       
  3484 					// This is a TEF Error Parameter
       
  3485 					// Extract the type of TEF parameter being read in
       
  3486 					if( param.Length() >= KTEFError().Length() &&
       
  3487 						0 == param.Mid(0,KTEFError().Length()).CompareF(KTEFError) )
       
  3488 						{
       
  3489 						TInt	start = KTEFError().Length();
       
  3490 						TInt	length = param.Length()-start;
       
  3491 						TLex	errorCodeLex( param.Mid(start,
       
  3492 														length ));
       
  3493 						
       
  3494 						TInt errorCode = 0;
       
  3495 						if( errorCodeLex.Val(errorCode) == KErrNone )
       
  3496 							{
       
  3497 							blockItem.iExpectedError = errorCode;
       
  3498 							}
       
  3499 						else
       
  3500 							{
       
  3501 							_LIT(KBadError,"Bad error syntax.");
       
  3502 							ERR_PRINTF1(KBadError);	
       
  3503 							blockItem.iError = KErrNotSupported;
       
  3504 							}
       
  3505 						}
       
  3506 					else if( param.Length() >= KTEFAsyncError().Length() &&
       
  3507 							 0 == param.Mid(0,KTEFAsyncError().Length()).CompareF(KTEFAsyncError))
       
  3508 						{
       
  3509 						TInt	start = KTEFAsyncError().Length();
       
  3510 						TInt	length = param.Length()-start;
       
  3511 						TLex	errorCodeLex( param.Mid(start,
       
  3512 														length ));
       
  3513 						
       
  3514 						TInt errorCode = 0;
       
  3515 						if( errorCodeLex.Val(errorCode) == KErrNone )
       
  3516 							{
       
  3517 							blockItem.iExpectedAsyncError = errorCode;
       
  3518 							}
       
  3519 						else
       
  3520 							{
       
  3521 							_LIT(KBadError,"Bad error syntax.");
       
  3522 							ERR_PRINTF1(KBadError);
       
  3523 							blockItem.iAsyncError = KErrNotSupported;					
       
  3524 							}
       
  3525 						}
       
  3526 					else
       
  3527 						{
       
  3528 						// Unknown TEFParameter
       
  3529 						_LIT(KUnknownTEFParam,"Unknown Test Block TEFParameter.");
       
  3530 						ERR_PRINTF1(KUnknownTEFParam);
       
  3531 						TExitCategoryName  blankPanicString;
       
  3532 						LogResult(EFail, blankPanicString, startBlockLineNumber, startBlockScriptLine);
       
  3533 						User::Leave(KErrNotSupported);
       
  3534 						}
       
  3535 
       
  3536 					// Read the next token
       
  3537 					param.Set( lex.NextToken().Left(KTEFMaxNameLength) );
       
  3538 					}
       
  3539 				}
       
  3540 				
       
  3541 			// Read in the object section name, function name and optional data section
       
  3542 			blockItem.iCommand.iObject		= param;
       
  3543 			blockItem.iCommand.iFunction	= lex.NextToken().Left(KTEFMaxNameLength);
       
  3544 			blockItem.iSection				= lex.NextToken().Left(KTEFMaxNameLength);
       
  3545 			}
       
  3546 		// STORE <section>
       
  3547 		else if( 0 == token.CompareF(KTEFStore) )
       
  3548 			{
       
  3549 			blockItem.iItemType		= ETEFStore;
       
  3550 			blockItem.iSection		= lex.NextToken().Left(KTEFMaxNameLength);
       
  3551 			}
       
  3552 		// OUTSTANDING <poll interval in ms>
       
  3553 		else if( 0 == token.CompareF(KTEFOutstanding) )
       
  3554 			{
       
  3555 			blockItem.iItemType		= ETEFOutstanding;
       
  3556 			TLex	pollLex( lex.NextToken().Left(KTEFMaxNameLength) );
       
  3557 			TInt	poll = 0;
       
  3558 			blockItem.iTime			= (KErrNone==pollLex.Val(poll)?poll:0);
       
  3559 			blockItem.iSection		= lex.NextToken().Left(KTEFMaxNameLength);		
       
  3560 			}
       
  3561 		// DELAY <time in ms>
       
  3562 		else if( 0 == token.CompareF(KTEFDelay) )
       
  3563 			{
       
  3564 			blockItem.iItemType		= ETEFDelay;
       
  3565 			TLex	delayLex( lex.NextToken().Left(KTEFMaxNameLength) );
       
  3566 			TInt	delay = 0;
       
  3567 			blockItem.iTime = (KErrNone==delayLex.Val(delay)?delay:0);		
       
  3568 			}
       
  3569 		// ASYNC_DELAY <time in ms>
       
  3570 		else if( 0 == token.CompareF(KTEFAsyncDelay) )
       
  3571 			{
       
  3572 			blockItem.iItemType		= ETEFAsyncDelay;
       
  3573 			TLex	delayLex( lex.NextToken().Left(KTEFMaxNameLength) );
       
  3574 			TInt	delay = 0;
       
  3575 			blockItem.iTime = (KErrNone==delayLex.Val(delay)?delay:0);
       
  3576 			}
       
  3577 		// SHARED_ACTIVE_SCHEDULER
       
  3578 		else if( 0 == token.CompareF(KTEFSharedActiveScheduler) )
       
  3579 			{
       
  3580 			blockItem.iItemType		= ETEFSharedActiveScheduler;			
       
  3581 			}
       
  3582 		// STORE_ACTIVE_SCHEDULER
       
  3583 		else if( 0 == token.CompareF(KTEFStoreActiveScheduler) )
       
  3584 			{
       
  3585 			blockItem.iItemType		= ETEFStoreActiveScheduler;			
       
  3586 			}
       
  3587 		// END_TEST_BLOCK [Scheduler Cleanup]
       
  3588 		else if( 0 == token.CompareF(KTEFEndTestBlock) )
       
  3589 			{
       
  3590 			TExitCategoryName  blankPanicString;
       
  3591 			if( 0 == aItemArray.Count() )
       
  3592 				{
       
  3593 				_LIT( KTEFEmptyBlock, "The Test Block is empty." );
       
  3594 				ERR_PRINTF1( KTEFEmptyBlock );
       
  3595 				LogResult(EFail, blankPanicString, startBlockLineNumber, startBlockScriptLine);
       
  3596 				User::Leave(KErrNotFound);
       
  3597 				}
       
  3598 			else
       
  3599 				{
       
  3600 				// Hit the end of the test block and the package is ready
       
  3601 				// Fix defect 118337, check parse result, and print corresponding message.
       
  3602 				LogResult(parseResult?EPass:EFail, blankPanicString, startBlockLineNumber, startBlockScriptLine);
       
  3603 				//End defect 118337
       
  3604 				break;
       
  3605 				}
       
  3606 			}
       
  3607 		else if( 0 == token.CompareF(KTEFStartTestBlock) )
       
  3608 			{
       
  3609 			// Error - there was no end test block command
       
  3610 			_LIT(KMissingEnd,"Missing END_TEST_BLOCK command.");
       
  3611 			ERR_PRINTF1(KMissingEnd);
       
  3612 			TExitCategoryName  blankPanicString;
       
  3613 			LogResult(EFail, blankPanicString, startBlockLineNumber, startBlockScriptLine);
       
  3614 			User::Leave(KErrNotFound);
       
  3615 			}
       
  3616 		else
       
  3617 			{
       
  3618 			if( token.Length() > 0 )
       
  3619 				{
       
  3620 				if( 0 != token.Left(2).Compare(KTEFComment) )
       
  3621 					{
       
  3622 					// The SART_TEST_BLOCK command failed
       
  3623 					_LIT(KUnknownCmd,"Unknown Test Block command.");
       
  3624 					ERR_PRINTF1(KUnknownCmd);
       
  3625 					TExitCategoryName  blankPanicString;
       
  3626 					LogResult(EFail, blankPanicString, startBlockLineNumber, startBlockScriptLine);
       
  3627 		
       
  3628 					// Special case for END_TESTCASE commands
       
  3629 					//  If one has been hit here because an END_TEST_BLOCK command was missing
       
  3630 					//  the we must log its completion.
       
  3631 					if( token.CompareF(KTEFEndTestCaseCommand) == 0 || token.CompareF(KTEFEndSyncTestCaseCommand) == 0 )
       
  3632 						{
       
  3633 						LogTestCaseMarkerL();
       
  3634 						}
       
  3635 					User::Leave(KErrNotSupported);
       
  3636 					}
       
  3637 				}
       
  3638 			}
       
  3639 			
       
  3640 		// Append the blockItem to the package
       
  3641 		if( ETEFNull != blockItem.iItemType )
       
  3642 			{
       
  3643 			aItemArray.AppendL( blockItem );
       
  3644 			}
       
  3645 		}
       
  3646 	}
       
  3647 
       
  3648 
       
  3649 _LIT( KTEFSyncStatus, "TEFStatus" );
       
  3650 _LIT( KTEFSyncResult, "TEFResult" );
       
  3651 const TInt KDelay		= 3000000;
       
  3652 const TInt KRetryCount	= 10;
       
  3653 
       
  3654 enum TSyncStatus
       
  3655 	{
       
  3656 	ETEFSyncUnknown		= 0,
       
  3657 	ETEFSyncRunning		= 1,
       
  3658 	ETEFSyncComplete	= 2,
       
  3659 	ETEFSyncWaiting		= 3,
       
  3660 	ETEFSyncContinue	= 4,
       
  3661 	ETEFRetrieveResult	= 5
       
  3662 	};
       
  3663 
       
  3664 /**
       
  3665  * Constructor
       
  3666  */
       
  3667 CSyncControl::CSyncControl()
       
  3668 	: iSharedTEFStatus(NULL), iSharedTEFResult(NULL)
       
  3669 	{
       
  3670 	}
       
  3671 /**
       
  3672  * Destructor
       
  3673  */
       
  3674 CSyncControl::~CSyncControl()
       
  3675 	{
       
  3676 	if( iSharedTEFResult && iSharedTEFStatus )
       
  3677 		{
       
  3678 		// Don't cleanup until the status is correct
       
  3679 		// This will allow time for any retrieve result calls to get through before TEF exits
       
  3680 		// Will retry for 30 seconds
       
  3681 		CTestSharedData* tefStatus = iSharedTEFStatus->Ptr();
       
  3682 		if( tefStatus != NULL )
       
  3683 			{
       
  3684 			TInt64 status = ETEFRetrieveResult;
       
  3685 			TInt count = 0;
       
  3686 			while( status == ETEFRetrieveResult && count < KRetryCount )
       
  3687 				{
       
  3688 				iSharedTEFStatus->EnterCriticalSection();
       
  3689 				HBufC* statusBuffer = NULL;
       
  3690 				TRAPD( err, statusBuffer = HBufC::NewL(tefStatus->TextLength()) );
       
  3691 				if( err == KErrNone )
       
  3692 					{
       
  3693 					TPtr statusPtr( statusBuffer->Des() );
       
  3694 					tefStatus->GetText( statusPtr );
       
  3695 					TLex lex(statusPtr);
       
  3696 					lex.Val(status);
       
  3697 					delete statusBuffer;
       
  3698 					}
       
  3699 				iSharedTEFStatus->ExitCriticalSection();
       
  3700 
       
  3701 				// Don't deley for the first i
       
  3702 				if( count > 0 )
       
  3703 					{
       
  3704 					User::After( KDelay );
       
  3705 					}
       
  3706 				count++;
       
  3707 				}
       
  3708 			}
       
  3709 		delete iSharedTEFResult;
       
  3710 		delete iSharedTEFStatus;		
       
  3711 		}
       
  3712 	}
       
  3713 
       
  3714 /**
       
  3715  * Two phase construction
       
  3716  */	
       
  3717 CSyncControl* CSyncControl::NewL()
       
  3718 	{
       
  3719 	CSyncControl* self = CSyncControl::NewLC();
       
  3720 	CleanupStack::Pop();
       
  3721 	return self;
       
  3722 	}
       
  3723 
       
  3724 /**
       
  3725  * Two phase construction
       
  3726  */	
       
  3727 CSyncControl* CSyncControl::NewLC()
       
  3728 	{
       
  3729 	CSyncControl* self = new (ELeave) CSyncControl();
       
  3730 	CleanupStack::PushL(self);
       
  3731 	self->ConstructL();
       
  3732 	return self;
       
  3733 	}
       
  3734 
       
  3735 /**
       
  3736  * ConstructL
       
  3737  */	
       
  3738 void CSyncControl::ConstructL()
       
  3739 	{
       
  3740 	// Initialise the sync status shared data
       
  3741 	CTestSharedData* tefStatus = NULL;
       
  3742 	iSharedTEFStatus = CTEFSharedData<CTestSharedData>::NewL(	tefStatus,
       
  3743 																KMaxSharedDataLength,
       
  3744 																KTEFSyncStatus );
       
  3745 	iSharedTEFStatus->EnterCriticalSection();
       
  3746 	tefStatus->Construct();
       
  3747 	HBufC* statusBuffer = NULL;
       
  3748 	TRAPD( err, statusBuffer = HBufC::NewL(sizeof(TInt64)) );
       
  3749 	if( err != KErrNone )
       
  3750 		{
       
  3751 		iSharedTEFStatus->ExitCriticalSection();
       
  3752 		User::Leave( err );
       
  3753 		}
       
  3754 	TPtr statusPtr( statusBuffer->Des() );
       
  3755 	statusPtr.Num( ETEFSyncWaiting );
       
  3756 	tefStatus->SetText( statusPtr );
       
  3757 	delete statusBuffer;
       
  3758 	iSharedTEFStatus->ExitCriticalSection();
       
  3759 
       
  3760 	// Initialise the sync result shared data
       
  3761 	CTestSharedData* tefResult = NULL;
       
  3762 	iSharedTEFResult = CTEFSharedData<CTestSharedData>::NewL(	tefResult,
       
  3763 																KMaxSharedDataLength,
       
  3764 																KTEFSyncResult );
       
  3765 	iSharedTEFResult->EnterCriticalSection();
       
  3766 	tefResult->Construct();
       
  3767 	HBufC* resBuffer = NULL;
       
  3768 	TRAP( err, resBuffer = HBufC::NewL(sizeof(TInt64)) );
       
  3769 	if( err != KErrNone )
       
  3770 		{
       
  3771 		iSharedTEFResult->ExitCriticalSection();
       
  3772 		User::Leave( err );
       
  3773 		}
       
  3774 	TPtr resPtr( resBuffer->Des() );
       
  3775 	resPtr.Num( EInconclusive );
       
  3776 	tefResult->SetText( resPtr );
       
  3777 	delete resBuffer;
       
  3778 	iSharedTEFResult->ExitCriticalSection();
       
  3779 	}
       
  3780 
       
  3781 /**
       
  3782  * @param aError - Error value resulting from synchronised testcase for logging
       
  3783  * Sets the result obtained from synchronised testcase for logging
       
  3784  */
       
  3785 void CSyncControl::SetResultL( TVerdict aError )
       
  3786 	{
       
  3787 	// Retrieve the status and result shared data pointers
       
  3788 	CTestSharedData* tefResult = iSharedTEFResult->Ptr();
       
  3789 	CTestSharedData* tefStatus = iSharedTEFStatus->Ptr();
       
  3790 
       
  3791 	if( tefResult != NULL && tefStatus != NULL )
       
  3792 		{
       
  3793 		// Update the shared sync test case result code
       
  3794 		iSharedTEFResult->EnterCriticalSection();
       
  3795 		HBufC* resBuffer = NULL;
       
  3796 		TRAPD( err, resBuffer = HBufC::NewL(sizeof(TInt64)) );
       
  3797 		if( err != KErrNone )
       
  3798 			{
       
  3799 			iSharedTEFResult->ExitCriticalSection();
       
  3800 			User::Leave( err );
       
  3801 			}
       
  3802 		TPtr resPtr( resBuffer->Des() );
       
  3803 		resPtr.Num( (TInt64)aError );
       
  3804 		tefResult->SetText( resPtr );
       
  3805 		delete resBuffer;
       
  3806 		
       
  3807 		iSharedTEFResult->ExitCriticalSection();
       
  3808 		
       
  3809 		// So now the test has complete and the result has been updated
       
  3810 		//  we need to update the status to reflect this
       
  3811 		iSharedTEFStatus->EnterCriticalSection();
       
  3812 		HBufC* statusBuffer = NULL;
       
  3813 		TRAP( err, statusBuffer = HBufC::NewL(sizeof(TInt64)) );
       
  3814 		if( err != KErrNone )
       
  3815 			{
       
  3816 			iSharedTEFStatus->ExitCriticalSection();
       
  3817 			User::Leave( err );
       
  3818 			}
       
  3819 		TPtr statusPtr( statusBuffer->Des() );
       
  3820 		statusPtr.Num( ETEFRetrieveResult );
       
  3821 		tefStatus->SetText( statusPtr );
       
  3822 		delete statusBuffer;
       
  3823 		
       
  3824 		iSharedTEFStatus->ExitCriticalSection();
       
  3825 		}
       
  3826 	else
       
  3827 		{
       
  3828 		User::Leave( KErrNotFound );
       
  3829 		}
       
  3830 	}
       
  3831 
       
  3832 /**
       
  3833  * Identifies state of synchronised testcases and continues with the test or completes the tests
       
  3834  */
       
  3835 TBool CSyncControl::TestCaseContinueL()
       
  3836 	{
       
  3837 	TBool tefContinue = EFalse;
       
  3838 	
       
  3839 	// Retrieve the status and result shared data pointers
       
  3840 	CTestSharedData* tefStatus = iSharedTEFStatus->Ptr();
       
  3841 	CTestSharedData* tefResult = iSharedTEFResult->Ptr();
       
  3842 
       
  3843 	if( tefStatus != NULL && tefResult != NULL )
       
  3844 		{
       
  3845 		iSharedTEFStatus->EnterCriticalSection();
       
  3846 
       
  3847 		// Retrieve the current status
       
  3848 		HBufC* statusBuffer = NULL;
       
  3849 		TRAPD( err, statusBuffer = HBufC::NewL(tefStatus->TextLength()) );
       
  3850 		if( err != KErrNone )
       
  3851 			{
       
  3852 			iSharedTEFStatus->ExitCriticalSection();
       
  3853 			User::Leave( err );
       
  3854 			}
       
  3855 
       
  3856 		TPtr statusPtr( statusBuffer->Des() );
       
  3857 		tefStatus->GetText( statusPtr );
       
  3858 		TLex lex(statusPtr);
       
  3859 		TInt64	status = ETEFSyncUnknown;
       
  3860 		User::LeaveIfError( lex.Val(status) );
       
  3861 
       
  3862 		if( status == ETEFSyncContinue )
       
  3863 			{
       
  3864 			tefContinue = ETrue;
       
  3865 			// Update the status to running
       
  3866 			HBufC* buffer = NULL;
       
  3867 			TRAP( err, buffer = HBufC::NewL(sizeof(TInt64)) );
       
  3868 			if( err != KErrNone )
       
  3869 				{
       
  3870 				delete statusBuffer;
       
  3871 				iSharedTEFStatus->ExitCriticalSection();
       
  3872 				User::Leave( err );
       
  3873 				}
       
  3874 
       
  3875 			TPtr ptr( buffer->Des() );
       
  3876 			ptr.Num( ETEFSyncRunning );
       
  3877 			tefStatus->SetText( ptr );
       
  3878 			delete buffer;
       
  3879 			}
       
  3880 		else if( status == ETEFSyncComplete )
       
  3881 			{
       
  3882 			// Previous test has completed and a new sync block has been hit
       
  3883 			// Update the status to waiting
       
  3884 			HBufC* buffer = NULL;
       
  3885 			TRAP( err, buffer = HBufC::NewL(sizeof(TInt64)) );
       
  3886 			if( err != KErrNone )
       
  3887 				{
       
  3888 				delete statusBuffer;
       
  3889 				iSharedTEFStatus->ExitCriticalSection();
       
  3890 				User::Leave( err );
       
  3891 				}
       
  3892 
       
  3893 			TPtr ptr( buffer->Des() );
       
  3894 			ptr.Num( ETEFSyncWaiting );
       
  3895 			tefStatus->SetText( ptr );
       
  3896 			delete buffer;
       
  3897 			}
       
  3898 		delete statusBuffer;
       
  3899 		iSharedTEFStatus->ExitCriticalSection();
       
  3900 		}
       
  3901 	else
       
  3902 		{
       
  3903 		User::Leave( KErrNotFound );
       
  3904 		}
       
  3905 	return tefContinue;
       
  3906 	}
       
  3907 
       
  3908 /**
       
  3909  * Takes in a script line updates any relative file paths into corresponding absolute path based on the current script file path
       
  3910  * @param aScriptLineString - Pointer descriptor containing a particular script line for updation
       
  3911  */
       
  3912 void CScriptControl::MakeAbsoluteFilePathsL(TPtrC16& aScriptLineString)
       
  3913 	{
       
  3914 	TLex lex(aScriptLineString);
       
  3915 	iAlteredScriptLine.Zero(); // Initialise the altered script line to zero b4 we start processing
       
  3916 	TBuf<KMaxTestExecuteCommandLength> commandName; // To store the command name, basically first token of each script line
       
  3917 	TBuf<KMaxTestExecuteCommandLength> commandString; // To store individual tokens of script line for processing
       
  3918 	TBuf<KMaxTestExecuteCommandLength> prevCommandString;
       
  3919 	const TInt KTEFMinFileExtnSizeIni = 4;
       
  3920 	const TInt KTEFMinFileExtnSizeScript = 7;
       
  3921 
       
  3922 	while(!lex.Eos()) // start a loop for each token until end of the script line
       
  3923 		{
       
  3924 		lex.NextToken();
       
  3925 		lex.SkipSpace();
       
  3926 		if (lex.MarkedToken().Length() > KMaxTestExecuteCommandLength)
       
  3927 			{
       
  3928 			User::Leave(KErrTooBig);
       
  3929 			}
       
  3930 
       
  3931 		commandString.Copy(lex.MarkedToken());
       
  3932 		lex.Mark();
       
  3933 
       
  3934 		if (commandName.CompareF(KTEFRunScriptCommand) == 0 &&
       
  3935 			commandString.CompareF(KTEFNull) != 0)
       
  3936 			{
       
  3937 			// if the command name is RUN_SCRIPT, then check the parameter is not not null and has valid .script extn
       
  3938 			// We append .script extn if the length of the token is less than 7 (.script -> Length)
       
  3939 			// Or when the token does not end with .script enxtn
       
  3940 			if(commandString.Length() < KTEFMinFileExtnSizeScript ||
       
  3941 				commandString.Right(KTEFMinFileExtnSizeScript).CompareF(KTEFScriptExtension) != 0)
       
  3942 				{
       
  3943 				commandString.Append(KTEFScriptExtension);
       
  3944 				}
       
  3945 			}
       
  3946 
       
  3947 		// Expand recognised variables into their values
       
  3948 		// At the moment just ${SYSDRIVE} -> GetSystemDrive()
       
  3949 		ExpandVariables(commandString);
       
  3950 
       
  3951 		// we consider eligible path if the token is an argument for RUN_SCRIPT
       
  3952 		// or any INI file or an argument for RUN_UTILS command
       
  3953 		// Check to see if the token contains a ":" as second character represeting a drive letter
       
  3954 		if (commandString.Length() >= KTEFMinFileExtnSizeIni &&
       
  3955 			commandString.Mid(1,1).CompareF(KTEFColon) != 0)
       
  3956 			{
       
  3957 			// if the ":" is not found, we process converting relative -> absolute path
       
  3958 			// Provided the token ends with .script or .ini extns
       
  3959 		    if ((commandString.Length() >= KTEFMinFileExtnSizeScript && 
       
  3960 				commandString.Right(KTEFMinFileExtnSizeScript).CompareF(KTEFScriptExtension) == 0) ||
       
  3961 				(commandString.Length() >= KTEFMinFileExtnSizeIni && 
       
  3962 				commandString.Right(KTEFMinFileExtnSizeIni).CompareF(KTEFIniExtension) == 0))
       
  3963 				{
       
  3964 				// token does not does not have a ':' but is a eligible path,
       
  3965 				// so, convert relative path to absolute path
       
  3966 				TRAPD(err, ConvertRelativeToAbsoluteL(commandString));
       
  3967 				if(err != KErrNone)
       
  3968 					{
       
  3969 					// Leave here since we have got an invalid path
       
  3970 					User::Leave(err);
       
  3971 					}				
       
  3972 				}
       
  3973 			else if(commandName.CompareF(KTEFRunUtilsCommand) == 0 &&
       
  3974 					(prevCommandString.CompareF(KTEFRunUtilsCopyFile) == 0 ||
       
  3975 					prevCommandString.CompareF(KTEFRunUtilsMkDir) == 0 ||
       
  3976 					prevCommandString.CompareF(KTEFRunUtilsDeleteFile) == 0 ||
       
  3977 					prevCommandString.CompareF(KTEFRunUtilsDelete) == 0 ||
       
  3978 					prevCommandString.CompareF(KTEFRunUtilsMakeReadWrite) == 0 ||
       
  3979 					prevCommandString.CompareF(KTEFDeleteDirectory) == 0))
       
  3980 				{
       
  3981 				// token does not does not have a ':' but is a eligible path,
       
  3982 				// so, convert relative path to absolute path
       
  3983 				TRAPD(err, ConvertRelativeToAbsoluteL(commandString));
       
  3984 				if(err != KErrNone)
       
  3985 					{
       
  3986 					// Leave here since we have got an invalid path
       
  3987 					User::Leave(err);
       
  3988 					}
       
  3989 				}
       
  3990 			}
       
  3991 		//start defect 120600 
       
  3992 		//remove the code which append an extra space.
       
  3993 		// if (iAlteredScriptLine.Length())
       
  3994 		//end defect 120600
       
  3995 		if (iAlteredScriptLine.Length() == 0)
       
  3996 			{
       
  3997 			// While completng the processing for the first token in the script line,
       
  3998 			// we record the token as command name, so that we can use it to identify
       
  3999 			// eligible paths in the following loop cycles for the script line
       
  4000 			commandName.Copy(commandString);
       
  4001 			}
       
  4002 		prevCommandString.Copy(commandString);
       
  4003 		// Construct the altered script line with individual verified tokens of script line
       
  4004 		if(iAlteredScriptLine.Length() + commandString.Length() <= iAlteredScriptLine.MaxLength() )
       
  4005 			{
       
  4006 			iAlteredScriptLine.Append(commandString);			
       
  4007 			}
       
  4008 		else// this scipte too long buffer not long enought
       
  4009 			{			
       
  4010 			User::Leave(KErrTooBig);
       
  4011 			}
       
  4012 		}
       
  4013 	// At the end of the while loop, we are ready with new processed script line
       
  4014 	// which we shall update it with the original reference taken in
       
  4015 	aScriptLineString.Set(iAlteredScriptLine);
       
  4016 	}
       
  4017 
       
  4018 /**
       
  4019  * Takes in lex token and updates any relative file paths into corresponding absolute path based on the current script file path
       
  4020  * @param aCommandString - Pointer descriptor containing a particular token within a script line for updation
       
  4021  */
       
  4022 void CScriptControl::ConvertRelativeToAbsoluteL(TDes& aCommandString)
       
  4023 	{
       
  4024 	TInt offset = 0;
       
  4025 	TInt posOfLastSlash=iScriptFile.LocateReverse('\\') ;
       
  4026 	TBuf<KMaxTestExecuteCommandLength> tempStore(iScriptFile.Mid(0,posOfLastSlash)); // Initial script file path
       
  4027 
       
  4028 	if(aCommandString.FindC(KTEFOneUp) >= 0)
       
  4029 		{
       
  4030 		while(aCommandString.FindC(KTEFOneUp) >= 0)
       
  4031 			{
       
  4032 			offset = aCommandString.FindC(KTEFOneUp);
       
  4033 			posOfLastSlash=tempStore.LocateReverse('\\') ;
       
  4034 			if (posOfLastSlash <= 0)
       
  4035 				{
       
  4036 				User::Leave(KTEFErrInvalidRelPath);
       
  4037 				}
       
  4038 			tempStore.Copy(iScriptFile.Mid(0,posOfLastSlash));// script file path
       
  4039 			aCommandString.Copy(aCommandString.Mid(offset + 3)); // 3 for ..'\\'
       
  4040 			}
       
  4041 
       
  4042 		tempStore.Append('\\');
       
  4043 		}
       
  4044 	else if (aCommandString.FindC(KTEFDotSlash) >= 0)
       
  4045 		{
       
  4046 		offset = aCommandString.FindC(KTEFDotSlash);
       
  4047 		aCommandString.Copy(aCommandString.Mid(offset + 1));
       
  4048 		}
       
  4049 	else if(aCommandString.Locate('\\') == 0)
       
  4050 		{
       
  4051 		tempStore.Copy(iScriptFile.Mid(0,2)); // Example: c:
       
  4052 		}
       
  4053 	else
       
  4054 		{
       
  4055 		tempStore.Append('\\');
       
  4056 		}
       
  4057 
       
  4058 	tempStore.Append(aCommandString);
       
  4059 	aCommandString.Copy(tempStore);
       
  4060 	}
       
  4061 
       
  4062 /**
       
  4063  * Expand recognised variables in script file into their corresponding value
       
  4064  * Currently supported variable is ${SYSDRIVE} -> GetSystemDrive() / Drive letter set from testexecute.ini
       
  4065  * @param aCommandString - Descriptor containing a particular token within a script line for updation
       
  4066  */
       
  4067 void CScriptControl::ExpandVariables(TDes& aCommandString)
       
  4068 	{
       
  4069 	TInt offset = 0;
       
  4070 	if (aCommandString.FindC(KTEFSysDrive) >= 0)
       
  4071 		{
       
  4072 		// If we find ${SYSDRIVE} in the token, replace it with the drive letter to be substitued
       
  4073 		offset = aCommandString.FindC(KTEFSysDrive);
       
  4074 		aCommandString.Replace(offset, 11, iTestSysDrive);
       
  4075 		}
       
  4076 	}