|
1 /* |
|
2 * Copyright (c) 1998-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 the License "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 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "t_testsetup.h" |
|
20 #include "t_testactionspec.h" |
|
21 #include "t_input.h" |
|
22 #include "t_certstoreactionmemfail.h" |
|
23 #include "tcancel.h" |
|
24 #include "t_message.h" |
|
25 #include "tScriptSetup.h" |
|
26 #include "Thardcodedsetup.h" |
|
27 #include "t_testhandler.h" |
|
28 #include "t_output.h" |
|
29 #include "tTestSpec.h" |
|
30 #include "ttesthandlersettings.h" |
|
31 #include "testexecuteinterface.h" |
|
32 #include "t_logger.h" |
|
33 #include "t_testrunner.h" |
|
34 #include "t_dummyconsole.h" |
|
35 |
|
36 EXPORT_C HBufC* CTestSetup::GetArgument(TInt nPos) |
|
37 { |
|
38 // Get command line |
|
39 HBufC *argv = HBufC::NewLC(User::CommandLineLength()); |
|
40 TPtr cmd(argv->Des()); |
|
41 User::CommandLine(cmd); |
|
42 |
|
43 TLex arguments(cmd); |
|
44 TPtrC token; |
|
45 token.Set(KNullDesC); |
|
46 |
|
47 // finds nth parameter that doesnt have a - |
|
48 while(nPos >= 0 && !arguments.Eos()) |
|
49 { |
|
50 token.Set(arguments.NextToken()); |
|
51 if(token.Length() > 0 && token[0] != '-') |
|
52 nPos--; |
|
53 } |
|
54 |
|
55 HBufC* result = token.AllocL(); |
|
56 |
|
57 CleanupStack::PopAndDestroy(argv); |
|
58 |
|
59 return result; |
|
60 } |
|
61 |
|
62 void CTestSetup::InitFileserverSessionLC(RFs& aFs) |
|
63 { |
|
64 User::LeaveIfError(aFs.Connect()); |
|
65 CleanupClosePushL(aFs); |
|
66 |
|
67 // enable tests to pass file handles between processes |
|
68 aFs.ShareProtected(); |
|
69 |
|
70 // Create the private directory, to fix failures in tests that write to |
|
71 // relative paths that were broken when the default path was changed to the |
|
72 // private path in build 03429 |
|
73 TFileName privatePath; |
|
74 User::LeaveIfError(aFs.PrivatePath(privatePath)); |
|
75 TInt err = aFs.MkDir(privatePath); |
|
76 if (err != KErrNone && err != KErrAlreadyExists) |
|
77 { |
|
78 User::Leave(err); |
|
79 } |
|
80 } |
|
81 |
|
82 EXPORT_C void CTestSetup::CreateAndRunTestsL(TScriptTests theTestTypes[], |
|
83 const TDesC& aScript, const TDesC& aLogFile, TBool aUseCommandLine, |
|
84 CConsoleBase* aConsole, TBool* aResult) |
|
85 { |
|
86 LOG(_L("-- Test handler starting")); |
|
87 |
|
88 RFs fs; |
|
89 |
|
90 InitFileserverSessionLC(fs); |
|
91 |
|
92 CScriptSetup* testSetup = CScriptSetup::NewLC(aConsole); |
|
93 CTestHandlerSettings* commandLineArgs = CTestHandlerSettings::NewLC(); |
|
94 CTestSpec* testSpec = CTestSpec::NewL(); |
|
95 CleanupStack::PushL(testSpec); |
|
96 |
|
97 TTestSummary summary; |
|
98 if(testSetup->InitialiseL(fs, aScript, aLogFile, aUseCommandLine)) |
|
99 { |
|
100 |
|
101 // Store the state of the heap and RFs resource count before the tests |
|
102 |
|
103 TInt initAllocCount = User::CountAllocCells(); |
|
104 TInt initRFsCount = fs.ResourceCount(); |
|
105 |
|
106 // Store the initial count of process and thread handles |
|
107 TInt initThreadHandleCount; |
|
108 TInt initProcessHandleCount; |
|
109 RThread().HandleCount(initProcessHandleCount, initThreadHandleCount); |
|
110 |
|
111 |
|
112 testSetup->LogFile().write(_L("State of the system before the tests:\n")); |
|
113 testSetup->LogFile().write(_L("\tRFs resource count: %d\n"), initRFsCount); |
|
114 testSetup->LogFile().write(_L("\tProcess handle count: %d\n"), initProcessHandleCount); |
|
115 testSetup->LogFile().write(_L("\tThread handle count: %d\n"), initThreadHandleCount); |
|
116 |
|
117 TRAPD(error, testSetup->SetupTestsL(fs, *testSpec, theTestTypes, *commandLineArgs)) |
|
118 |
|
119 if(error==KErrNone) |
|
120 { |
|
121 CTestHandler* handler = CTestHandler::NewLC(fs, *testSpec, *commandLineArgs, |
|
122 &testSetup->Console(), |
|
123 &testSetup->LogFile()); |
|
124 handler->RunTestsL(); |
|
125 summary = handler->Summary(); |
|
126 testSpec->FreeAllTests(); |
|
127 CleanupStack::PopAndDestroy(handler); |
|
128 |
|
129 // Do heap, RFs resource, process and thread handle balance checks |
|
130 |
|
131 TInt finalRFsCount = fs.ResourceCount(); |
|
132 |
|
133 testSetup->LogFile().write(_L("State of the system after the tests:\n")); |
|
134 testSetup->LogFile().write(_L("\tRFs resource count: %d\n"), finalRFsCount); |
|
135 |
|
136 if (initRFsCount == finalRFsCount) |
|
137 { |
|
138 testSetup->LogFile().write(_L("\nRFs resource count ok: %d final\n\n"), |
|
139 finalRFsCount); |
|
140 } |
|
141 else |
|
142 { |
|
143 testSetup->LogFile().write(_L("\nRFs resource count inbalance: %d final\n\n"), |
|
144 finalRFsCount); |
|
145 ++summary.iTestsFailed; |
|
146 } |
|
147 |
|
148 |
|
149 TInt finalAllocCount = User::CountAllocCells(); |
|
150 if (initAllocCount == finalAllocCount) |
|
151 { |
|
152 testSetup->LogFile().write(_L("\nHeap alloc count ok: %d final vs %d initial\n\n"), |
|
153 finalAllocCount, initAllocCount); |
|
154 } |
|
155 else |
|
156 { |
|
157 testSetup->LogFile().write(_L("\nHeap alloc count inbalance: %d final vs %d initial\n\n"), |
|
158 finalAllocCount, initAllocCount); |
|
159 ++summary.iTestsFailed; |
|
160 } |
|
161 |
|
162 TInt finalThreadHandleCount; |
|
163 TInt finalProcessHandleCount; |
|
164 RThread().HandleCount(finalProcessHandleCount, finalThreadHandleCount); |
|
165 |
|
166 if (initProcessHandleCount == finalProcessHandleCount) |
|
167 { |
|
168 testSetup->LogFile().write(_L("\nProcess handle count ok: %d final vs %d initial\n\n"), |
|
169 finalProcessHandleCount, initProcessHandleCount); |
|
170 } |
|
171 else |
|
172 { |
|
173 testSetup->LogFile().write(_L("\nProcess handle count imbalance: %d final vs %d initial\n\n"), |
|
174 finalProcessHandleCount, initProcessHandleCount); |
|
175 ++summary.iTestsFailed; |
|
176 } |
|
177 |
|
178 if (initThreadHandleCount == finalThreadHandleCount) |
|
179 { |
|
180 testSetup->LogFile().write(_L("\nThread handle count ok: %d final vs %d initial\n\n"), |
|
181 finalThreadHandleCount, initThreadHandleCount); |
|
182 } |
|
183 else |
|
184 { |
|
185 testSetup->LogFile().write(_L("\nThread handle count imbalance: %d final vs %d initial\n\n"), |
|
186 finalThreadHandleCount, initThreadHandleCount); |
|
187 ++summary.iTestsFailed; |
|
188 } |
|
189 ++summary.iTestsRun; |
|
190 } |
|
191 |
|
192 // Set the result if required by caller |
|
193 if (aResult) |
|
194 { |
|
195 *aResult = summary.AllTestsPassed(); |
|
196 } |
|
197 |
|
198 summary.PrintL(testSetup->LogFile()); |
|
199 |
|
200 // pauses runtime if command line requests it i.e. -w |
|
201 if(commandLineArgs->iWaitForKeyPressAtEnd) |
|
202 { |
|
203 testSetup->Console().Printf(_L("\nPress a key to quit")); |
|
204 testSetup->Console().Getch(); |
|
205 } |
|
206 |
|
207 } |
|
208 |
|
209 CleanupStack::PopAndDestroy(4, &fs); // fs, testsetup, commandLineArgs and testspec |
|
210 // this MUST be the last thing to do incase objects being destructed on cleanup |
|
211 // have debug info |
|
212 //if (bTestSuccess) |
|
213 // RDebug::RawPrint(_L("RTEST: SUCCESS : testhandler\n")); |
|
214 } |
|
215 |
|
216 EXPORT_C void CTestSetup::CreateAndRunTestsL(THardcodedTests theTestTypes[], const TDesC& aDefaultLog) |
|
217 { |
|
218 LOG(_L("-- Test handler starting")); |
|
219 |
|
220 RFs fs; |
|
221 |
|
222 InitFileserverSessionLC(fs); |
|
223 |
|
224 InitFileserverSessionLC(fs); |
|
225 |
|
226 CHardcodedSetup* testSetup = CHardcodedSetup::NewLC(); |
|
227 CTestHandlerSettings* commandLineArgs = CTestHandlerSettings::NewLC(); |
|
228 CTestSpec* testSpec = CTestSpec::NewL(); |
|
229 CleanupStack::PushL(testSpec); |
|
230 |
|
231 TTestSummary summary; |
|
232 if(testSetup->InitialiseL(fs, aDefaultLog)) |
|
233 { |
|
234 |
|
235 // Store the state of the heap and RFs resource count before the tests |
|
236 |
|
237 TInt initAllocCount = User::CountAllocCells(); |
|
238 TInt initRFsCount = fs.ResourceCount(); |
|
239 |
|
240 TRAPD(error, testSetup->SetupTestsL(fs, *testSpec, theTestTypes, *commandLineArgs)); |
|
241 |
|
242 if(error==KErrNone) |
|
243 { |
|
244 CTestHandler* handler = CTestHandler::NewLC(fs, *testSpec, *commandLineArgs, |
|
245 &testSetup->Console(), |
|
246 &testSetup->LogFile()); |
|
247 handler->RunTestsL(); |
|
248 summary = handler->Summary(); |
|
249 testSpec->FreeAllTests(); |
|
250 CleanupStack::PopAndDestroy(handler); |
|
251 |
|
252 // Do heap and RFs resource balance checks |
|
253 |
|
254 TInt finalRFsCount = fs.ResourceCount(); |
|
255 |
|
256 testSetup->LogFile().write(_L("State of the system after the tests:\n")); |
|
257 testSetup->LogFile().write(_L("\tRFs resource count: %d\n"), finalRFsCount); |
|
258 |
|
259 if (initRFsCount == finalRFsCount) |
|
260 { |
|
261 testSetup->LogFile().write(_L("\nRFs resource count ok: %d final\n\n"), |
|
262 finalRFsCount); |
|
263 } |
|
264 else |
|
265 { |
|
266 testSetup->LogFile().write(_L("\nRFs resource count inbalance: %d final\n\n"), |
|
267 finalRFsCount); |
|
268 ++summary.iTestsFailed; |
|
269 } |
|
270 |
|
271 TInt finalAllocCount = User::CountAllocCells(); |
|
272 if (initAllocCount == finalAllocCount) |
|
273 { |
|
274 testSetup->LogFile().write(_L("\nHeap alloc count ok: %d final vs %d initial\n\n"), |
|
275 finalAllocCount, initAllocCount); |
|
276 } |
|
277 else |
|
278 { |
|
279 testSetup->LogFile().write(_L("\nHeap alloc count inbalance: %d final vs %d initial\n\n"), |
|
280 finalAllocCount, initAllocCount); |
|
281 ++summary.iTestsFailed; |
|
282 } |
|
283 ++summary.iTestsRun; |
|
284 } |
|
285 |
|
286 summary.PrintL(testSetup->LogFile()); |
|
287 |
|
288 // pauses runtime if command line requests it i.e. -w |
|
289 if(commandLineArgs->iWaitForKeyPressAtEnd) |
|
290 { |
|
291 testSetup->Console().Printf(_L("\nPress a key to quit")); |
|
292 testSetup->Console().Getch(); |
|
293 } |
|
294 } |
|
295 |
|
296 CleanupStack::PopAndDestroy(4, &fs); // fs, testsetup, commandLineArgs and testspec |
|
297 |
|
298 //if (bTestSuccess) |
|
299 // RDebug::RawPrint(_L("RTEST: SUCCESS : testhandler\n")); |
|
300 } |
|
301 |
|
302 //Check all flags is provided for understanability - Each grouping function called calls the next function |
|
303 // if it has succeeded |
|
304 TBool CTestSetup::CheckAllFlags(const CTestHandlerSettings& aCommandLineSettings, TInt& aScriptGroupings) |
|
305 { |
|
306 return CheckExhaustiveandSmoke(aCommandLineSettings,aScriptGroupings); |
|
307 } |
|
308 |
|
309 TBool CTestSetup::CheckExhaustiveandSmoke(const CTestHandlerSettings& aCommandLineSettings, TInt& aScriptGroupings) |
|
310 { |
|
311 |
|
312 if (aCommandLineSettings.iExhaust || (aScriptGroupings & SMOKE)) |
|
313 { |
|
314 //Do other flags |
|
315 return CheckSkipped(aCommandLineSettings, aScriptGroupings); |
|
316 } |
|
317 else |
|
318 |
|
319 return EFalse; |
|
320 } |
|
321 |
|
322 |
|
323 TBool CTestSetup::CheckSkipped(const CTestHandlerSettings& aCommandLineSettings, |
|
324 TInt& aScriptGroupings) |
|
325 { |
|
326 if (aCommandLineSettings.iSkip || !(aScriptGroupings & SKIP)) |
|
327 { |
|
328 //Do other flags |
|
329 return CheckInteractive(aCommandLineSettings, aScriptGroupings); |
|
330 } |
|
331 else |
|
332 return EFalse; |
|
333 } |
|
334 |
|
335 TBool CTestSetup::CheckInteractive(const CTestHandlerSettings& aCommandLineSettings, |
|
336 TInt& aScriptGroupings) |
|
337 { |
|
338 if (aCommandLineSettings.iInt || !(aScriptGroupings & INTER)) |
|
339 { |
|
340 //Do other flags |
|
341 return CheckOOMandCancel(aCommandLineSettings, aScriptGroupings); |
|
342 } |
|
343 else |
|
344 return EFalse; |
|
345 } |
|
346 |
|
347 TBool CTestSetup::CheckOOMandCancel(const CTestHandlerSettings& aCommandLineSettings, |
|
348 TInt& aScriptGroupings) |
|
349 { |
|
350 |
|
351 if ((aScriptGroupings & (EXOOM | INOOM)) == (EXOOM | INOOM)) |
|
352 User::Panic(_L("Test is both Included and Excluded from OOM"), 1); |
|
353 |
|
354 if ((aScriptGroupings & (EXCANCEL | INCANCEL)) == (EXCANCEL | INCANCEL)) |
|
355 User::Panic(_L("Test is both Included and Excluded from Cancel"), 1); |
|
356 |
|
357 if ((aScriptGroupings & (INOOM | INCANCEL)) == (INOOM | INCANCEL)) |
|
358 User::Panic(_L("Test is in both OOM and Cancel groups"), 1); |
|
359 |
|
360 // Check to see whether -o set |
|
361 if (aCommandLineSettings.iOOM) |
|
362 { |
|
363 //Is the test in OOM group? |
|
364 if (aScriptGroupings & INOOM) |
|
365 return ETrue; |
|
366 else |
|
367 //Is the test excluded from OOM? |
|
368 if (aScriptGroupings & EXOOM) |
|
369 return EFalse; |
|
370 } |
|
371 else |
|
372 if (aScriptGroupings & INOOM) |
|
373 return EFalse; |
|
374 |
|
375 // Check to see whether -c set |
|
376 if (aCommandLineSettings.iCancel) |
|
377 { |
|
378 //Is the test in CANCEL group? |
|
379 if (aScriptGroupings & INCANCEL) |
|
380 return ETrue; |
|
381 else |
|
382 //Is the test excluded from CANCEL? |
|
383 if (aScriptGroupings & EXCANCEL) |
|
384 return EFalse; |
|
385 } |
|
386 else |
|
387 if (aScriptGroupings & INCANCEL) |
|
388 return EFalse; |
|
389 |
|
390 |
|
391 return ETrue; |
|
392 } |
|
393 |
|
394 |
|
395 CTestSetup::~CTestSetup() |
|
396 { |
|
397 delete iLogFile; |
|
398 delete iTestConsole; |
|
399 if (iConsoleOwned) |
|
400 { |
|
401 // Note that the heap count when this is deleted must be the same as |
|
402 // when the console was allocated, otherwise a panic will occur. This |
|
403 // is due to the techview implementation of the console doing a heap |
|
404 // mark in its destructor. |
|
405 delete iConsole; |
|
406 } |
|
407 } |
|
408 |
|
409 CTestSetup::CTestSetup(CConsoleBase* aConsole) |
|
410 : iConsole(aConsole), iConsoleOwned(aConsole == NULL) |
|
411 { |
|
412 } |
|
413 |
|
414 void CTestSetup::ConstructL() |
|
415 { |
|
416 if (iConsoleOwned) |
|
417 { |
|
418 iConsole = Console::NewL(_L("Test code"), TSize(KDefaultConsWidth, KDefaultConsHeight)); |
|
419 } |
|
420 |
|
421 // Currently the console passed to the test actions discards all output - |
|
422 // this is an attempt to make hardware tests run faster. All information |
|
423 // should be written to the log file anyway, and I'd like to remove use of a |
|
424 // console as well as the log file. -- jc |
|
425 iTestConsole = new (ELeave) CDummyConsole(); |
|
426 } |
|
427 |
|
428 void CTestSetup::OpenLogFileL(RFs &aFs, TInt nPos, const TDesC &aLogFile, TBool aUseCommandline) |
|
429 { |
|
430 HBufC* logFileName = NULL; |
|
431 |
|
432 if (aUseCommandline) |
|
433 { |
|
434 logFileName = GetArgument(nPos); |
|
435 CleanupStack::PushL(logFileName); |
|
436 |
|
437 // check if logfile was specified on command line |
|
438 if(logFileName->Length()==0) |
|
439 { |
|
440 // empty so remove it |
|
441 CleanupStack::PopAndDestroy(logFileName); |
|
442 logFileName = NULL; |
|
443 } |
|
444 } |
|
445 |
|
446 if(logFileName == NULL) |
|
447 { |
|
448 if(aLogFile.Length()==0) |
|
449 { |
|
450 PRINTANDLOG(_L("No log file specified on command line and no default given")); |
|
451 User::Leave(KErrArgument); |
|
452 } |
|
453 else |
|
454 { |
|
455 // there is a default copy that |
|
456 logFileName = aLogFile.AllocL(); |
|
457 CleanupStack::PushL(logFileName); |
|
458 } |
|
459 } |
|
460 |
|
461 PRINTANDLOG1(_L("Log file: %S"), logFileName); |
|
462 |
|
463 RFile logFile; |
|
464 |
|
465 // attempts to create directories incase they dont exist |
|
466 aFs.MkDirAll(*logFileName); // ignore errors |
|
467 |
|
468 // write over any existing log |
|
469 User::LeaveIfError(logFile.Replace(aFs, *logFileName, EFileWrite)); |
|
470 |
|
471 // output goes only to the log file |
|
472 iLogFile = new(ELeave) FileOutput(logFile); |
|
473 CleanupStack::PopAndDestroy(logFileName); |
|
474 }; |