|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file cdbtest.cpp |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include <bacline.h> |
|
22 #include "testlog.h" |
|
23 #include "testscriptparser.h" |
|
24 #include "testexecutestepbase.h" |
|
25 #include "Te_commsdatSuiteServer.h" |
|
26 #include "Te_cedSuiteServer.h" |
|
27 #include "posix.h" |
|
28 |
|
29 |
|
30 |
|
31 // max length of path/filename |
|
32 #define MAX_BUFFER_LEN 256 |
|
33 |
|
34 // max length of arg list to program |
|
35 #define MAX_ARG_LEN (MAX_BUFFER_LEN * 3) |
|
36 |
|
37 // Application name |
|
38 #define APPLICATIONNAME _L("cdbtest") |
|
39 |
|
40 _LIT(SCRIPT_TARGET, ""); |
|
41 _LIT(LOG_TARGET, "cdbtest.log"); |
|
42 |
|
43 |
|
44 // PROTOTYPES |
|
45 TInt ParseCommandLine(TInt &aDebugOn, TDes &aIn, TDes &aOut, CConsoleBase* aConsole); |
|
46 void ProcessScriptFile(CTestScriptParser* afileParser, CTestLog* aMsg); |
|
47 void HelpDump(CConsoleBase* aConsole); |
|
48 |
|
49 |
|
50 void MainL(CConsoleBase* aConsole) |
|
51 /** Central processing unit of cdbtest |
|
52 |
|
53 @return void |
|
54 @leave refer only called functions and dependant components |
|
55 */ |
|
56 { |
|
57 TInt bDebugOn = EFalse; |
|
58 |
|
59 TBuf<MAX_BUFFER_LEN> fIn; |
|
60 TBuf<MAX_BUFFER_LEN> fOut; |
|
61 RFs fsSession; // file system session |
|
62 |
|
63 // connect to file system |
|
64 User::LeaveIfError(fsSession.Connect()); |
|
65 CleanupClosePushL(fsSession); |
|
66 |
|
67 // Get arguments from the command line |
|
68 TInt valid = ParseCommandLine(bDebugOn, fIn, fOut, aConsole); |
|
69 |
|
70 if (valid) |
|
71 { |
|
72 // initialise output log file |
|
73 CTestLog* outMsg = CTestLog::NewLC(fsSession, fOut, bDebugOn, aConsole); |
|
74 |
|
75 outMsg->Msg(_L(" ")); |
|
76 outMsg->Msg(_L("====================================================")); |
|
77 outMsg->Msg(APPLICATIONNAME); |
|
78 outMsg->Msg(_L("====================================================")); |
|
79 outMsg->Msg(_L(" ")); |
|
80 outMsg->Msg(_L("Processing test script from [%S]"), &fIn); |
|
81 outMsg->Msg(_L("Writing logfile to [%S]"), &fOut); |
|
82 outMsg->Msg(_L(" ")); |
|
83 |
|
84 CTestScriptParser* fileParser = CTestScriptParser::FactoryLC( fIn, outMsg ); |
|
85 |
|
86 TRAPD(err, fileParser->OpenScriptFileL()); |
|
87 if (err == KErrNone) |
|
88 { |
|
89 ProcessScriptFile(fileParser, outMsg); |
|
90 } |
|
91 else |
|
92 { |
|
93 outMsg->Msg(_L("Failed to open test script from [%S]"), &fIn); |
|
94 } |
|
95 CleanupStack::PopAndDestroy(fileParser); |
|
96 CleanupStack::PopAndDestroy(outMsg); |
|
97 } |
|
98 CleanupStack::PopAndDestroy(&fsSession); |
|
99 } |
|
100 |
|
101 LOCAL_C void doMainL() |
|
102 { |
|
103 // allocate a Console |
|
104 CConsoleBase* aConsole; |
|
105 aConsole = Console::NewL(APPLICATIONNAME, TSize(KConsFullScreen, KConsFullScreen)); |
|
106 CleanupStack::PushL(aConsole); |
|
107 |
|
108 // call main routine |
|
109 MainL(aConsole); |
|
110 |
|
111 CleanupStack::PopAndDestroy(aConsole); |
|
112 } |
|
113 |
|
114 TInt E32Main() |
|
115 { |
|
116 __UHEAP_MARK; |
|
117 |
|
118 // set up trap cleanup framework |
|
119 CTrapCleanup* theCleanup = CTrapCleanup::New(); |
|
120 |
|
121 // call main routine and trap any exceptions |
|
122 TRAPD(ret, doMainL()); |
|
123 |
|
124 TBool bSuccessful = ETrue; |
|
125 if (ret != KErrNone) |
|
126 { |
|
127 bSuccessful = EFalse; |
|
128 } |
|
129 |
|
130 // clean up when finished |
|
131 delete theCleanup; |
|
132 |
|
133 __UHEAP_MARKEND; |
|
134 |
|
135 // Convert the boolean idea of "success" into the customary process idea of errorlevel, where zero |
|
136 // is success and anything else designates particular kinds of failure. Specific failure reasons aren't |
|
137 // provided, so the caller should only look for process exit != 0 to mean failure, and then examine the |
|
138 // log to see what failed. |
|
139 return !bSuccessful; |
|
140 } |
|
141 |
|
142 TInt ParseCommandLine(TBool &aDebugOn, TDes &aIn, TDes &aOut, CConsoleBase* aConsole) |
|
143 /** Parse the command line for any overriding settings from exe command line |
|
144 |
|
145 @param bDebugOn Wether to output debug messages to the log file using CTestLog::Dbg(TPtrC text, ...) |
|
146 @param fIn Path and filename of the configuration database file |
|
147 @param fOut Filename of the file to send logging too |
|
148 @return ETrue if Successful else EFalse |
|
149 */ |
|
150 { |
|
151 TInt valid = EFalse; |
|
152 CCommandLineArguments *pCmd; |
|
153 pCmd = CCommandLineArguments::NewL(); |
|
154 |
|
155 // set defaults |
|
156 aIn = SCRIPT_TARGET; |
|
157 aOut = LOG_TARGET; |
|
158 |
|
159 // Flags for encountering the specification |
|
160 // of an input and an output file |
|
161 TBool bInFound = EFalse; |
|
162 TBool bOutFound = EFalse; |
|
163 |
|
164 if (pCmd) |
|
165 { |
|
166 TBuf<MAX_ARG_LEN> arg; |
|
167 |
|
168 // check all arguments for switches |
|
169 TInt i = 0; |
|
170 while ( ++i < pCmd->Count() ) |
|
171 { |
|
172 arg = pCmd->Arg(i); |
|
173 arg.UpperCase(); |
|
174 |
|
175 //Display help |
|
176 if (arg.FindF(_L("-H")) != KErrNotFound) |
|
177 { |
|
178 HelpDump(aConsole); |
|
179 delete pCmd; |
|
180 return valid; |
|
181 } |
|
182 |
|
183 // Debug switch |
|
184 if (arg.FindF(_L("-D")) != KErrNotFound) |
|
185 { |
|
186 aDebugOn = ETrue; |
|
187 continue; |
|
188 } |
|
189 |
|
190 // Specification of an input script file |
|
191 if (arg.FindF(_L("-I")) != KErrNotFound) |
|
192 { |
|
193 if (i != pCmd->Count()-1) |
|
194 { |
|
195 aIn = pCmd->Arg(++i); |
|
196 bInFound = ETrue; |
|
197 continue; |
|
198 } |
|
199 else |
|
200 { |
|
201 delete pCmd; |
|
202 aConsole->Printf(_L("Argument missing after '-i' switch\n")); |
|
203 #ifndef __TOOLS2__ |
|
204 aConsole->Printf(_L("\nPress any key to finish")); |
|
205 aConsole->Getch(); |
|
206 #endif |
|
207 return valid; |
|
208 } |
|
209 } |
|
210 // Specification of an output log file |
|
211 if (arg.FindF(_L("-O")) != KErrNotFound) |
|
212 { |
|
213 if (i != pCmd->Count()-1) |
|
214 { |
|
215 aOut = pCmd->Arg(++i); |
|
216 bOutFound = ETrue; |
|
217 continue; |
|
218 } |
|
219 else |
|
220 { |
|
221 delete pCmd; |
|
222 aConsole->Printf(_L("Argument missing after '-o' switch\n")); |
|
223 #ifndef __TOOLS2__ |
|
224 aConsole->Printf(_L("\nPress any key to finish")); |
|
225 aConsole->Getch(); |
|
226 #endif |
|
227 return valid; |
|
228 } |
|
229 } |
|
230 |
|
231 // No flag is supplied: first file encountered is the input |
|
232 // file and the following one is the output file |
|
233 |
|
234 if ( !bInFound) |
|
235 { |
|
236 aIn = pCmd->Arg(i); |
|
237 bInFound = ETrue; |
|
238 continue; |
|
239 } |
|
240 if ( !bOutFound) |
|
241 { |
|
242 aOut = pCmd->Arg(i); |
|
243 bOutFound = ETrue; |
|
244 continue; |
|
245 } |
|
246 } |
|
247 |
|
248 if (aIn.Length() > 0) |
|
249 valid = ETrue; |
|
250 |
|
251 if ( !bInFound) |
|
252 { |
|
253 aConsole->Printf(_L("No test script file found please specify using -i\n")); |
|
254 #ifndef __TOOLS2__ |
|
255 aConsole->Printf(_L("\nPress any key to finish")); |
|
256 aConsole->Getch(); |
|
257 #endif |
|
258 |
|
259 valid=EFalse; |
|
260 } |
|
261 |
|
262 delete pCmd; |
|
263 } |
|
264 |
|
265 return valid; |
|
266 } |
|
267 |
|
268 void ProcessScriptFile(CTestScriptParser* afileParser, CTestLog* aMsg) |
|
269 { |
|
270 |
|
271 // Initialise the test counters |
|
272 TUint totalTests = 0; |
|
273 TUint testPass = 0; |
|
274 TUint testInconclusive = 0; |
|
275 TUint testFail = 0; |
|
276 TUint testNotExecuted = 0; |
|
277 TUint testAbort = 0; |
|
278 |
|
279 TBool end(EFalse); |
|
280 CTestScriptParser::TScriptAction runAction; |
|
281 |
|
282 CTestServer* simServer = NULL; |
|
283 |
|
284 do |
|
285 { |
|
286 TBuf<MAX_BUFFER_LEN> stepParameters; |
|
287 |
|
288 end = afileParser->CTestScriptParser::GetNextTestStepL(runAction, stepParameters); |
|
289 if (runAction == CTestScriptParser::ELoadTestSuite) |
|
290 { |
|
291 if (simServer) |
|
292 { |
|
293 CleanupStack::PopAndDestroy(simServer); |
|
294 simServer = NULL; |
|
295 } |
|
296 |
|
297 if (stepParameters.Compare(_L("Te_commsdat")) == 0) |
|
298 { |
|
299 // Create the simulator for the TestExecute Suite |
|
300 simServer = CTe_commsdatSuite::NewL(); |
|
301 CleanupStack::PushL(simServer); |
|
302 } |
|
303 if (stepParameters.Compare(_L("te_cedSuite")) == 0) |
|
304 { |
|
305 // Create the simulator for the TestExecute Suite |
|
306 simServer = CTe_cedSuite::NewL(); |
|
307 CleanupStack::PushL(simServer); |
|
308 } |
|
309 |
|
310 } |
|
311 else if(runAction == CTestScriptParser::ERunTestStep) |
|
312 { |
|
313 |
|
314 // Create the next test |
|
315 CTestStep* testStep = NULL; |
|
316 if (simServer) |
|
317 { |
|
318 testStep = simServer->CreateTestStep(stepParameters); |
|
319 } |
|
320 else |
|
321 { |
|
322 aMsg->Msg(_L("Error: Test step found but no test suite loaded.")); |
|
323 } |
|
324 |
|
325 if (testStep) |
|
326 { |
|
327 CleanupStack::PushL(testStep); |
|
328 |
|
329 // Now run the test |
|
330 totalTests++; |
|
331 |
|
332 testStep->SetLogger(aMsg); |
|
333 |
|
334 // Do the Test Preamble |
|
335 TRAPD(err, testStep->doTestStepPreambleL()) |
|
336 if (err == KErrNone) |
|
337 { |
|
338 // Preamble was OK so do the actual Test step |
|
339 TRAP(err, testStep->doTestStepL()); |
|
340 |
|
341 // Always run the Test Postamble step even if the test failed |
|
342 TRAP(err, testStep->doTestStepPostambleL()); |
|
343 } |
|
344 else |
|
345 { |
|
346 // Do not run the test |
|
347 // Tell the user about the error |
|
348 aMsg->Dbg(_L("%S->doTestStepPreambleL failed - test not run"), &stepParameters); |
|
349 } |
|
350 |
|
351 // Now print out the result |
|
352 switch(testStep->TestStepResult()) |
|
353 { |
|
354 case EPass: |
|
355 { |
|
356 aMsg->Msg(_L("%S passed"), &stepParameters); |
|
357 testPass++; |
|
358 break; |
|
359 } |
|
360 case EInconclusive: |
|
361 { |
|
362 aMsg->Msg(_L("%S was inconclusive"), &stepParameters); |
|
363 testInconclusive++; |
|
364 break; |
|
365 } |
|
366 case EAbort: |
|
367 { |
|
368 aMsg->Msg(_L("%S was aborted"), &stepParameters); |
|
369 testAbort++; |
|
370 break; |
|
371 } |
|
372 case EIgnore: |
|
373 { |
|
374 aMsg->Msg(_L("%S was ignored"), &stepParameters); |
|
375 testNotExecuted++; |
|
376 break; |
|
377 } |
|
378 case ETestSuiteError: |
|
379 { |
|
380 aMsg->Msg(_L("%S had a testsuite error"), &stepParameters); |
|
381 testFail++; |
|
382 break; |
|
383 } |
|
384 default: |
|
385 case EFail: |
|
386 { |
|
387 aMsg->Msg(_L("%S failed"), &stepParameters); |
|
388 testFail++; |
|
389 break; |
|
390 } |
|
391 } |
|
392 CleanupStack::PopAndDestroy(testStep); |
|
393 testStep = NULL; |
|
394 } |
|
395 else |
|
396 { |
|
397 aMsg->Msg(_L("%S not executed"), &stepParameters); |
|
398 testNotExecuted++; |
|
399 } |
|
400 } |
|
401 else if(runAction == CTestScriptParser::ERunProgram) |
|
402 { |
|
403 aMsg->Msg(_L("Running %S"), &stepParameters); |
|
404 |
|
405 // stepParameters contains the entire command line. |
|
406 // Make a POSIX call to launch the command |
|
407 char commandLine[MAX_BUFFER_LEN]; |
|
408 |
|
409 TInt i; |
|
410 for(i = 0; i < stepParameters.Length(); i++) |
|
411 { |
|
412 commandLine[i] = (char)stepParameters[i]; |
|
413 } |
|
414 commandLine[i] = '\0'; |
|
415 TInt exitValue = RunProgram(commandLine); |
|
416 if (exitValue) |
|
417 { |
|
418 aMsg->Msg(_L("%S failed with exit value %d"),&stepParameters, exitValue); |
|
419 } |
|
420 } |
|
421 else if(runAction == CTestScriptParser::EPrint) |
|
422 { |
|
423 aMsg->Msg(_L("%S"),&stepParameters); |
|
424 } |
|
425 |
|
426 }while(!end); |
|
427 |
|
428 if (simServer) |
|
429 { |
|
430 CleanupStack::PopAndDestroy(simServer); |
|
431 } |
|
432 |
|
433 aMsg->Msg(_L(" ")); |
|
434 aMsg->Msg(_L("Test Summary")); |
|
435 aMsg->Msg(_L("-----------------------")); |
|
436 aMsg->Msg(_L("total tests run = %d"), totalTests ); |
|
437 aMsg->Msg(_L("tests passed = %d "), testPass ); |
|
438 aMsg->Msg(_L("tests failed = %d"), testFail ); |
|
439 aMsg->Msg(_L("tests aborted = %d"), testAbort ); |
|
440 aMsg->Msg(_L("tests inconclusive = %d"), testInconclusive ); |
|
441 aMsg->Msg(_L("tests not executed = %d"), testNotExecuted ); |
|
442 } |
|
443 |
|
444 |
|
445 void HelpDump(CConsoleBase* aConsole) |
|
446 // Prints basic help information to the console window including command switches |
|
447 { |
|
448 aConsole->Printf(_L("Tests commsdat by simulatimg the TestExecute framework.")); |
|
449 aConsole->Printf(_L("\n\ncdbtest [-d] [-i [path]filename] [-o [path]filename]")); |
|
450 aConsole->Printf(_L("\n-i\tSpecifies an input test script file. Failure to provide this parameter \r\n")); |
|
451 aConsole->Printf(_L("\twill lead to the application exiting with no tests being run. \r\n")); |
|
452 aConsole->Printf(_L("\n-o\tSpecifies an output file for logging the test output messages. \r\n")); |
|
453 aConsole->Printf(_L("\tIf this parameter is not specified, the application defaults to the \r\n")); |
|
454 aConsole->Printf(_L("\tfile cdbtest.log in the local directory. \r\n")); |
|
455 aConsole->Printf(_L("\n-d\tEnables debug mode which outputs more data to the log file.\n")); |
|
456 #ifndef __TOOLS2__ |
|
457 aConsole->Printf(_L("\nPress any key to finish")); |
|
458 aConsole->Getch(); |
|
459 #endif |
|
460 } |
|
461 |
|
462 |
|
463 |