|
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_testhandler.h" |
|
20 #include "ttesthandlersettings.h" |
|
21 #include "t_output.h" |
|
22 #include "t_testaction.h" |
|
23 #include "t_testsetup.h" |
|
24 #include "tTestSpec.h" |
|
25 #include "t_testrunner.h" |
|
26 |
|
27 |
|
28 TTestSummary::TTestSummary() : |
|
29 iTestsRun(0), iTestsFailed(0) |
|
30 { |
|
31 } |
|
32 |
|
33 void TTestSummary::PrintL(Output& aOut) |
|
34 { |
|
35 aOut.write(_L("%d tests failed out of %d\n"), iTestsFailed, iTestsRun); |
|
36 } |
|
37 |
|
38 TBool TTestSummary::AllTestsPassed() |
|
39 { |
|
40 return iTestsRun > 0 && iTestsFailed == 0; |
|
41 } |
|
42 |
|
43 EXPORT_C CTestHandler* CTestHandler::NewLC(RFs& aFs, |
|
44 MTestSpec& aTestSpec, |
|
45 CTestHandlerSettings& aSettings, |
|
46 CConsoleBase* aConsole, |
|
47 Output* aOut) |
|
48 { |
|
49 CTestHandler* self = new(ELeave) CTestHandler(aFs, aTestSpec, aConsole, aOut); |
|
50 CleanupStack::PushL(self); |
|
51 self->ConstructL(aSettings); |
|
52 return self; |
|
53 } |
|
54 |
|
55 CTestHandler::~CTestHandler() |
|
56 { |
|
57 delete iSettings; |
|
58 delete iScheduler; |
|
59 delete iSharedData; |
|
60 delete iTestRunner; |
|
61 delete iNextTestRunner; |
|
62 |
|
63 iFailedTests.Reset(); |
|
64 iFailedTestNames.ResetAndDestroy(); |
|
65 iKnownDefects.ResetAndDestroy(); |
|
66 } |
|
67 |
|
68 CTestHandler::CTestHandler(RFs& aFs, |
|
69 MTestSpec& aTestSpec, |
|
70 CConsoleBase* aConsole, |
|
71 Output* aOut) : |
|
72 iFs(aFs), iConsole(aConsole), iOut(aOut), iTestSpec(aTestSpec) |
|
73 { |
|
74 } |
|
75 |
|
76 void CTestHandler::ConstructL(CTestHandlerSettings& aSettings) |
|
77 { |
|
78 iSettings = CTestHandlerSettings::NewL(aSettings); |
|
79 iScheduler = new(ELeave) CActiveScheduler; |
|
80 CActiveScheduler::Install(iScheduler); |
|
81 |
|
82 // Set up test handler based on command line argument |
|
83 if (aSettings.iOOM) |
|
84 { |
|
85 SetTestRunnerL(new (ELeave) COOMTestRunner(*iOut)); |
|
86 } |
|
87 else if (aSettings.iCancel) |
|
88 { |
|
89 SetTestRunnerL(new (ELeave) CCancelTestRunner(*iOut)); |
|
90 } |
|
91 else |
|
92 { |
|
93 SetTestRunnerL(NULL); |
|
94 } |
|
95 } |
|
96 |
|
97 TTestSummary CTestHandler::Summary() |
|
98 { |
|
99 TTestSummary result; |
|
100 result.iTestsRun = iActionCount; |
|
101 result.iTestsFailed = iFailedTests.Count(); |
|
102 return result; |
|
103 } |
|
104 |
|
105 EXPORT_C void CTestHandler::RunTestsL() |
|
106 { |
|
107 iActionNumber = 0; |
|
108 CTestAction* action; |
|
109 while(iTestSpec.GetNextTest(action)) |
|
110 { |
|
111 iActionCount++; |
|
112 iActionNumber++; |
|
113 |
|
114 TRAPD(err, RunTestL(action)); |
|
115 if (err != KErrNone) |
|
116 { |
|
117 FailTestL(action, EFailInTestHandler, err); |
|
118 } |
|
119 } |
|
120 DisplaySummary(); |
|
121 } |
|
122 |
|
123 void CTestHandler::RunTestL(CTestAction* aAction) |
|
124 { |
|
125 // If the last test set a new test runner, install it here |
|
126 if (iNextTestRunner) |
|
127 { |
|
128 delete iTestRunner; |
|
129 iTestRunner = iNextTestRunner; |
|
130 iNextTestRunner = NULL; |
|
131 } |
|
132 |
|
133 iOut->writeString(_L("Test ")); |
|
134 iOut->writeNum(iActionNumber); |
|
135 iOut->writeNewLine(); |
|
136 |
|
137 if (iActionNumber > 1) |
|
138 { |
|
139 iConsole->Printf(_L(", ")); |
|
140 } |
|
141 iConsole->Printf(_L("%d: "), iActionNumber); |
|
142 |
|
143 aAction->ReportAction(); |
|
144 aAction->SetTestHandler(*this); |
|
145 |
|
146 TInt preErr = iTestRunner->PerformPrerequisiteL(aAction); |
|
147 if ((preErr != KErrNone) && !aAction->iResult) |
|
148 { |
|
149 FailTestL(aAction, EFailInPrerequisite, preErr); |
|
150 return; |
|
151 } |
|
152 TInt actionErr = 0; |
|
153 if (preErr == KErrNone) |
|
154 { |
|
155 actionErr = iTestRunner->PerformActionL(aAction); |
|
156 } |
|
157 TInt postErr = iTestRunner->PerformPostrequisiteL(aAction, actionErr); |
|
158 // investiage if passing actionErr would make more sense here |
|
159 aAction->CheckResult(postErr); |
|
160 if (!aAction->iResult) |
|
161 { |
|
162 FailTestL(aAction, EFailInAction, actionErr); |
|
163 return; |
|
164 } |
|
165 |
|
166 iConsole->Printf(_L("passed")); |
|
167 } |
|
168 |
|
169 const TDesC& CTestHandler::GetFailLocationName(TTestFailLocation aLoc) |
|
170 { |
|
171 _LIT(KTestHandler, "test handler"); |
|
172 _LIT(KPrerequisite, "prerequisite"); |
|
173 _LIT(KTestAction, "test action"); |
|
174 |
|
175 const TDesC* result = NULL; |
|
176 |
|
177 switch (aLoc) |
|
178 { |
|
179 case EFailInTestHandler: |
|
180 result = &KTestHandler; |
|
181 break; |
|
182 case EFailInPrerequisite: |
|
183 result = &KPrerequisite; |
|
184 break; |
|
185 case EFailInAction: |
|
186 result = &KTestAction; |
|
187 break; |
|
188 } |
|
189 |
|
190 ASSERT(result); |
|
191 return *result; |
|
192 } |
|
193 |
|
194 void CTestHandler::FailTestL(CTestAction* aAction, TTestFailLocation aLoc, TInt aErr) |
|
195 { |
|
196 iOut->writeString(_L("Test failed in ")); |
|
197 iOut->writeString(GetFailLocationName(aLoc)); |
|
198 iOut->writeString(_L(": ")); |
|
199 iOut->writeNum(aErr); |
|
200 iOut->writeNewLine(); |
|
201 |
|
202 iConsole->Printf(_L("failed")); |
|
203 |
|
204 AppendFailedTestL(iActionNumber, *aAction->iNameInfo); |
|
205 if(aAction->ScriptError() == CTestAction::EFileNotFound) |
|
206 { |
|
207 TBuf<KMaxErrorSize> scriptError; |
|
208 aAction->ScriptError(scriptError); |
|
209 iOut->writeString(_L("File Not Found \"")); |
|
210 iOut->writeString(scriptError); |
|
211 iOut->writeString(_L("\" in test ")); |
|
212 iOut->writeNum(iActionNumber); |
|
213 iOut->writeNewLine(); |
|
214 } |
|
215 |
|
216 if (aAction->iKnownFailure) |
|
217 {// Expecting a failure because of known defect - record details |
|
218 HBufC* name=HBufC::NewLC(aAction->iNameInfo->Length()); |
|
219 name->Des().Copy(*(aAction->iNameInfo)); |
|
220 User::LeaveIfError(iKnownDefects.Append(name)); |
|
221 CleanupStack::Pop(name); |
|
222 } |
|
223 } |
|
224 |
|
225 void CTestHandler::AppendFailedTestL(TInt aIndex, const TDesC8& aName) |
|
226 { |
|
227 iFailedTests.Append(aIndex); |
|
228 HBufC* name=HBufC::NewLC(aName.Length()); |
|
229 name->Des().Copy(aName); |
|
230 User::LeaveIfError(iFailedTestNames.Append(name)); |
|
231 CleanupStack::Pop(name); |
|
232 } |
|
233 |
|
234 void CTestHandler::DisplaySummary() |
|
235 { |
|
236 //Display the RTest information |
|
237 iConsole->Printf(_L("\n")); |
|
238 |
|
239 // Log the details of tests that failed because of known (deferred) defects |
|
240 TInt theFailCount = iKnownDefects.Count(); |
|
241 if (theFailCount > 0) |
|
242 { |
|
243 iOut->writeNewLine(); |
|
244 iOut->writeString(_L("----------------------------------------------------------------------------------")); |
|
245 iOut->writeNewLine(); |
|
246 iOut->writeString(_L("These tests may not pass because of known defects details of which are given below:")); |
|
247 iOut->writeNewLine(); |
|
248 iOut->writeNewLine(); |
|
249 |
|
250 TInt index = 0; |
|
251 for (; index<theFailCount; index++) |
|
252 { |
|
253 iOut->writeString(*iKnownDefects[index]); |
|
254 iOut->writeNewLine(); |
|
255 } |
|
256 iOut->writeString(_L("----------------------------------------------------------------------------------")); |
|
257 iOut->writeNewLine(); |
|
258 iOut->writeNewLine(); |
|
259 } |
|
260 |
|
261 // Display the failed tests |
|
262 TInt iEnd = iFailedTests.Count(); |
|
263 if (iEnd!=0) |
|
264 { |
|
265 iOut->writeString(_L(" Failed tests:-")); |
|
266 iOut->writeNewLine(); |
|
267 for (TInt i = 0; i < iEnd; i++) |
|
268 { |
|
269 iOut->writeNum(iFailedTests[i]); |
|
270 iOut->writeSpaces(2); |
|
271 iOut->writeString(*iFailedTestNames[i]); |
|
272 iOut->writeNewLine(); |
|
273 } |
|
274 iOut->writeNewLine(); |
|
275 } |
|
276 |
|
277 // Summary line is now printed in CTestSetup |
|
278 } |
|
279 |
|
280 CBase* CTestHandler::SharedData() const |
|
281 { |
|
282 return iSharedData; |
|
283 } |
|
284 |
|
285 void CTestHandler::SetSharedData(CBase* aData) |
|
286 { |
|
287 iSharedData = aData; |
|
288 } |
|
289 |
|
290 EXPORT_C void CTestHandler::SetTestRunnerL(CTestRunner *aTestRunner) |
|
291 { |
|
292 /* We can't set iTestRunner directly, as we may be called while we're inside |
|
293 * one of its methods. */ |
|
294 |
|
295 // This method can be called twice in a row, eg if the -o option is used |
|
296 if (iNextTestRunner) |
|
297 { |
|
298 delete iNextTestRunner; |
|
299 iNextTestRunner = NULL; |
|
300 } |
|
301 |
|
302 iNextTestRunner = aTestRunner ? aTestRunner : new (ELeave) CTestRunner(*iOut); |
|
303 } |
|
304 |
|
305 void CTestHandler::SetHeapMark(TInt aAllocCount) |
|
306 { |
|
307 iHeapMark = aAllocCount; |
|
308 } |
|
309 |
|
310 TInt CTestHandler::HeapMark() |
|
311 { |
|
312 return iHeapMark; |
|
313 } |