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