|
1 // Copyright (c) 2002-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 // This contains CTestSuite which is the base class for all the TestSuite DLLs |
|
15 // |
|
16 // |
|
17 |
|
18 // EPOC includes |
|
19 #include <e32base.h> |
|
20 |
|
21 // Test system includes |
|
22 #include <testframework.h> |
|
23 |
|
24 // do not export if Unit Testing |
|
25 #if defined (__TSU_TESTFRAMEWORK__) |
|
26 #undef EXPORT_C |
|
27 #define EXPORT_C |
|
28 #endif |
|
29 |
|
30 /** |
|
31 * |
|
32 * Default test suite version string |
|
33 * |
|
34 * @xxxx |
|
35 * |
|
36 */ |
|
37 _LIT(KTxtVersion,"?.?"); |
|
38 |
|
39 /** |
|
40 * |
|
41 * Test suite destructor |
|
42 * This destroys all the test steps contained in this class and |
|
43 * in classes derived from it |
|
44 * |
|
45 * @xxxx |
|
46 * |
|
47 */ |
|
48 EXPORT_C CTestSuite::~CTestSuite() |
|
49 { |
|
50 // free all test steps |
|
51 if (iArrayTestSteps) |
|
52 iArrayTestSteps->ResetAndDestroy(); |
|
53 |
|
54 // free the dynamic array used for test steps |
|
55 delete iArrayTestSteps; |
|
56 |
|
57 } |
|
58 |
|
59 /** |
|
60 * |
|
61 * Test suite constructor (second phase) |
|
62 * |
|
63 * @xxxx |
|
64 * |
|
65 */ |
|
66 EXPORT_C void CTestSuite::ConstructL() |
|
67 { |
|
68 // create a new Array to store the test steps in |
|
69 iArrayTestSteps = new(ELeave) CArrayPtrFlat<RTestStep>(1); |
|
70 |
|
71 // default severity |
|
72 SetSeverity(ESevrAll); |
|
73 iLogger = NULL; |
|
74 |
|
75 // initialise the derived test suites |
|
76 InitialiseL(); |
|
77 } |
|
78 |
|
79 /** |
|
80 * |
|
81 * Get test suite version. |
|
82 * |
|
83 * NOTE : this function is not pure virtual i.e. a test suite |
|
84 * does not have to provide a version string - however this |
|
85 * may change. It is strongly recommended that a test suite DLL |
|
86 * overrides this method. |
|
87 * |
|
88 * @return "TPtrC" |
|
89 * The version string. |
|
90 * |
|
91 * @xxxx |
|
92 * |
|
93 */ |
|
94 EXPORT_C TPtrC CTestSuite::GetVersion() const |
|
95 { |
|
96 return KTxtVersion(); |
|
97 } |
|
98 |
|
99 /** |
|
100 * |
|
101 * Add a test step into the suite |
|
102 * |
|
103 * @param "RTestStep* aTestStep" |
|
104 * The test step to add. |
|
105 * |
|
106 * @xxxx |
|
107 * |
|
108 */ |
|
109 EXPORT_C void CTestSuite::AddTestStepL(RTestStep* aTestStep) |
|
110 { |
|
111 __ASSERT_ALWAYS(aTestStep, User::Panic(_L("CTestSuite::AddTestStepL"), KErrArgument)); |
|
112 // test steps contain a pointer back to the suite which owns them |
|
113 aTestStep->SetSuite(this); |
|
114 // add the step; order is not important, so add it at position 1 |
|
115 iArrayTestSteps->AppendL(aTestStep, 1); |
|
116 } |
|
117 |
|
118 |
|
119 /** |
|
120 * |
|
121 * Perform a test step. |
|
122 * |
|
123 * @param "const TDesC& aStep" |
|
124 * The test step to run. |
|
125 * |
|
126 * @param "const TDesC& aConfig" |
|
127 * The configuration file name. |
|
128 * |
|
129 * @return "TVerdict" |
|
130 * Result of the test. |
|
131 * |
|
132 * @xxxx |
|
133 * |
|
134 */ |
|
135 EXPORT_C TVerdict CTestSuite::DoTestStep(const TDesC& aStep, const TDesC& aConfig, const TDesC& aParamSet) |
|
136 { |
|
137 // This function traps leaves in the test steps, so should never leave |
|
138 |
|
139 // get the number of tests available in this suite |
|
140 TInt noOfTests = iArrayTestSteps->Count(); |
|
141 |
|
142 // search the available test steps for the required one |
|
143 for (TInt i = 0; i < noOfTests; i++) |
|
144 { |
|
145 RTestStep* theStep = iArrayTestSteps->At(i); |
|
146 if (theStep->StepName().MatchF(aStep) != KErrNotFound) |
|
147 { |
|
148 |
|
149 // found required test so initialise to PASS |
|
150 theStep->SetResult(EPass); |
|
151 |
|
152 // set the param set to use |
|
153 theStep->SetDefaultParamSet(aParamSet); |
|
154 |
|
155 // pass the config file info into the test step |
|
156 theStep->LoadConfig(aConfig); |
|
157 |
|
158 // assume it's going to work |
|
159 TVerdict result = EPass; |
|
160 |
|
161 // set step status |
|
162 iStepStatus = EStepStatusStart; |
|
163 |
|
164 // execute pre-preamble (cleanup stack growth) |
|
165 TRAPD(rPreOpen, theStep->PreOpenL()); |
|
166 |
|
167 if (rPreOpen != KErrNone) |
|
168 { |
|
169 WARN_PRINTF4(_L("Warning: Test step:%S PreOpenL in suite:%S left, error %d"), &aStep, &iSuiteName, rPreOpen); |
|
170 result = EInconclusive; |
|
171 } |
|
172 else |
|
173 { |
|
174 // execute test step preamble (if any) inside a trap |
|
175 TRAPD(rPreAmble, result = theStep->OpenL()); |
|
176 |
|
177 if (result != EPass) |
|
178 { |
|
179 WARN_PRINTF3(_L("Warning: Test step:%S preamble in suite:%S failed"), &aStep, &iSuiteName); |
|
180 // here : call to virtual cleanup function in test step, if it exists... |
|
181 theStep->CleanupAfterOpenFail(); |
|
182 result = EInconclusive; |
|
183 } |
|
184 else if (rPreAmble != KErrNone) |
|
185 { |
|
186 WARN_PRINTF4(_L("Warning: Test step:%S preamble in suite:%S left, error %d"), &aStep, &iSuiteName, rPreAmble); |
|
187 // here : call to virtual cleanup function in test step, if it exists... |
|
188 theStep->CleanupAfterOpenFail(); |
|
189 result = EInconclusive; |
|
190 } |
|
191 } |
|
192 |
|
193 // only continue if the preamble passed |
|
194 if (result == EPass) |
|
195 { |
|
196 |
|
197 // set step status |
|
198 iStepStatus = EStepStatusPreamble; |
|
199 |
|
200 // now execute test step inside a trap |
|
201 TRAPD(r, result = theStep->DoTestStepL()); |
|
202 |
|
203 if (r!= KErrNone) |
|
204 { |
|
205 WARN_PRINTF4(_L("Warning: Test step:%S in suite:%S left, error %d"), &aStep, &iSuiteName, r); |
|
206 result = EFail; |
|
207 } |
|
208 |
|
209 // set step status |
|
210 iStepStatus = EStepStatusTest; |
|
211 |
|
212 // execute test step postamble |
|
213 // NB - postamble does not leave, but may panic |
|
214 theStep->Close(); |
|
215 |
|
216 // set step status |
|
217 iStepStatus = EStepStatusFinished; |
|
218 } |
|
219 |
|
220 // *** TO DO - check if there are problems when the preamble leaves. |
|
221 // In this case the postamble is not called - there may be memory leaks. |
|
222 // (Preambles may allocate memory, call __UHEAP_MARK, etc.) |
|
223 // If so, move Close() to this point, and check again. |
|
224 |
|
225 // clean up Config data object |
|
226 theStep->UnloadConfig(); |
|
227 |
|
228 return result; |
|
229 |
|
230 } |
|
231 } |
|
232 |
|
233 // suite has been searched but test step not found, so error. |
|
234 ERR_PRINTF3(_L("Failed to find test step:%S in suite:%S"), &aStep, &iSuiteName); |
|
235 |
|
236 return ETestSuiteError; |
|
237 |
|
238 } |
|
239 |
|
240 /** |
|
241 * |
|
242 * Gets a step's heap and stack size. |
|
243 * |
|
244 * @param "const TDesC& aStep" |
|
245 * The step name |
|
246 * @param "TInt* aHeapSize" |
|
247 * Returns the step's heap size |
|
248 * @param "TInt* aStackSize" |
|
249 * Returns the step's stack size |
|
250 * |
|
251 * @xxxx |
|
252 * |
|
253 */ |
|
254 EXPORT_C void CTestSuite::GetHeapAndStackSize(const TDesC& aStep, TInt* aHeapSize, TInt* aStackSize) |
|
255 { |
|
256 //get the number of tests available in this suite |
|
257 TInt noOfTests = iArrayTestSteps->Count(); |
|
258 |
|
259 // search the available test steps for the required one |
|
260 for (TInt i = 0; i < noOfTests; i++) |
|
261 { |
|
262 RTestStep* theStep = iArrayTestSteps->At(i); |
|
263 if (theStep->StepName().MatchF(aStep) != KErrNotFound) |
|
264 { |
|
265 |
|
266 // found required test, so get the stack and heap size |
|
267 *aHeapSize = theStep->HeapSize(); |
|
268 *aStackSize = theStep->StackSize(); |
|
269 } |
|
270 } |
|
271 } |
|
272 |
|
273 /** |
|
274 * |
|
275 * General logging function for test suites. |
|
276 * |
|
277 * @param "TRefByValue<const TDesC16> aFmt" |
|
278 * Printf-style format. |
|
279 * |
|
280 * @param "..." |
|
281 * Variable print parameters |
|
282 * |
|
283 * @xxxx |
|
284 * |
|
285 */ |
|
286 EXPORT_C void CTestSuite::Log(TRefByValue<const TDesC16> aFmt, ...) |
|
287 { |
|
288 |
|
289 VA_LIST aList; |
|
290 VA_START(aList, aFmt); |
|
291 |
|
292 if(iLogger) |
|
293 iLogger->Log(aFmt, aList); |
|
294 |
|
295 VA_END(aList); |
|
296 } |
|
297 |
|
298 /** |
|
299 * |
|
300 * General logging function for test suites, with severity. |
|
301 * |
|
302 * @param "TInt aSeverity" |
|
303 * Severity level required to log |
|
304 * |
|
305 * @param "TRefByValue<const TDesC16> aFmt" |
|
306 * Printf-style format. |
|
307 * |
|
308 * @param "..." |
|
309 * Variable print parameters |
|
310 * |
|
311 * @xxxx |
|
312 * |
|
313 */ |
|
314 EXPORT_C void CTestSuite::Log(TInt aSeverity, TRefByValue<const TDesC16> aFmt, ...) |
|
315 { |
|
316 VA_LIST aList; |
|
317 VA_START(aList, aFmt); |
|
318 |
|
319 if(LogSeverity::IsActive(aSeverity, Severity())) |
|
320 { |
|
321 if(iLogger) |
|
322 iLogger->Log(aFmt, aList); |
|
323 } |
|
324 |
|
325 VA_END(aList); |
|
326 } |
|
327 |
|
328 /** |
|
329 * |
|
330 * Traceable logging function for test suites. |
|
331 * |
|
332 * @param "const TText8* aFile" |
|
333 * Source code file name |
|
334 * |
|
335 * @param "TInt aLine" |
|
336 * Source code line |
|
337 * |
|
338 * @param "TInt aSeverity" |
|
339 * Severity level required to log |
|
340 * |
|
341 * @param "TRefByValue<const TDesC16> aFmt" |
|
342 * Printf-style format. |
|
343 * |
|
344 * @param "..." |
|
345 * Variable print parameters |
|
346 * |
|
347 * @xxxx |
|
348 * |
|
349 */ |
|
350 EXPORT_C void CTestSuite::LogExtra(const TText8* aFile, TInt aLine, TInt aSeverity, |
|
351 TRefByValue<const TDesC16> aFmt,...) |
|
352 { |
|
353 VA_LIST aList; |
|
354 VA_START(aList, aFmt); |
|
355 |
|
356 if(LogSeverity::IsActive(aSeverity, Severity())) |
|
357 { |
|
358 if(iLogger) |
|
359 { |
|
360 iLogger->LogExtra(aFile, aLine, aSeverity, aFmt, aList); |
|
361 } |
|
362 } |
|
363 |
|
364 VA_END(aList); |
|
365 } |
|
366 |
|
367 |
|
368 /** |
|
369 * |
|
370 * Traceable Boolean condition tester. |
|
371 * |
|
372 * @param "TBool aCondition" |
|
373 * Condition to be checked |
|
374 * |
|
375 * @param "const TText8* aFile" |
|
376 * Source code file name |
|
377 * |
|
378 * @param "TInt aLine" |
|
379 * Source code line |
|
380 * |
|
381 * @xxxx |
|
382 * |
|
383 */ |
|
384 EXPORT_C void CTestSuite::TestBooleanTrueL(TBool aCondition, const TText8* aFile, TInt aLine) |
|
385 { |
|
386 |
|
387 // check condition |
|
388 if (aCondition) |
|
389 return; |
|
390 |
|
391 // convert filename for log |
|
392 TBuf<KMaxLogFilenameLength> fileName; |
|
393 TPtrC8 fileName8(aFile); |
|
394 fileName.Copy(fileName8); // TText8->TBuf16 |
|
395 |
|
396 // display a log message |
|
397 ERR_PRINTF3(_L("Test Failed in file:%S line:%d"), &fileName, aLine); |
|
398 |
|
399 // leave with error code |
|
400 User::Leave(KTestErrorCode); |
|
401 |
|
402 } |
|
403 |
|
404 /** |
|
405 * |
|
406 * Set log severity. |
|
407 * |
|
408 * @param "TInt aSeverity" |
|
409 * The required severity |
|
410 * |
|
411 * @xxxx |
|
412 * |
|
413 */ |
|
414 EXPORT_C void CTestSuite::SetSeverity(TInt aSeverity) |
|
415 { |
|
416 iSeverity = aSeverity; |
|
417 } |
|
418 |
|
419 /** |
|
420 * |
|
421 * Get log severity. |
|
422 * |
|
423 * @return "TInt" |
|
424 * The current severity |
|
425 * |
|
426 * @xxxx |
|
427 * |
|
428 */ |
|
429 EXPORT_C TInt CTestSuite::Severity() const |
|
430 { |
|
431 return iSeverity; |
|
432 } |
|
433 |
|
434 /** |
|
435 * |
|
436 * Set logging system. |
|
437 * |
|
438 * @param "CLog *aLogger" |
|
439 * The log to use. |
|
440 * |
|
441 * @xxxx |
|
442 * |
|
443 */ |
|
444 EXPORT_C void CTestSuite::SetLogSystem(CLog* aLogger) |
|
445 { |
|
446 iLogger = aLogger; |
|
447 } |
|
448 |
|
449 /** |
|
450 * |
|
451 * Get logging system. |
|
452 * |
|
453 * @return "CLog*" |
|
454 * The log the test suite is currently using. |
|
455 * |
|
456 * @xxxx |
|
457 * |
|
458 */ |
|
459 EXPORT_C CLog* CTestSuite::LogSystem() const |
|
460 { |
|
461 return iLogger; |
|
462 } |
|
463 |
|
464 /** |
|
465 * |
|
466 * Set step status. |
|
467 * |
|
468 * @param "TTestStepStatus aStatus" |
|
469 * The status to set. |
|
470 * |
|
471 * @xxxx |
|
472 * |
|
473 */ |
|
474 EXPORT_C void CTestSuite::SetStepStatus(TTestStepStatus aStatus) |
|
475 { |
|
476 iStepStatus = aStatus; |
|
477 } |
|
478 |
|
479 /** |
|
480 * |
|
481 * Get step status. |
|
482 * |
|
483 * @return "TTestStepStatus" |
|
484 * The step status. |
|
485 * |
|
486 * @xxxx |
|
487 * |
|
488 */ |
|
489 EXPORT_C TTestStepStatus CTestSuite::StepStatus() const |
|
490 { |
|
491 return iStepStatus; |
|
492 } |