source: trunk/src/testlib/qtestlogger.cpp@ 792

Last change on this file since 792 was 769, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 12.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtTest module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qtestlogger_p.h"
43#include "qtestelement.h"
44#include "qtestxunitstreamer.h"
45#include "qtestxmlstreamer.h"
46#include "qtestlightxmlstreamer.h"
47#include "qtestfilelogger.h"
48
49#include "QtTest/qtestcase.h"
50#include "QtTest/private/qtestresult_p.h"
51#include "QtTest/private/qbenchmark_p.h"
52
53#include <string.h>
54
55QT_BEGIN_NAMESPACE
56
57QTestLogger::QTestLogger(int fm)
58 :listOfTestcases(0), currentLogElement(0), errorLogElement(0),
59 logFormatter(0), format( (TestLoggerFormat)fm ), filelogger(new QTestFileLogger),
60 testCounter(0), passCounter(0),
61 failureCounter(0), errorCounter(0),
62 warningCounter(0), skipCounter(0),
63 systemCounter(0), qdebugCounter(0),
64 qwarnCounter(0), qfatalCounter(0),
65 infoCounter(0)
66{
67}
68
69QTestLogger::~QTestLogger()
70{
71 if(format == TLF_XunitXml)
72 delete currentLogElement;
73 else
74 delete listOfTestcases;
75
76 delete logFormatter;
77 delete filelogger;
78}
79
80void QTestLogger::startLogging()
81{
82 switch(format){
83 case TLF_LightXml:{
84 logFormatter = new QTestLightXmlStreamer;
85 filelogger->init();
86 break;
87 }case TLF_XML:{
88 logFormatter = new QTestXmlStreamer;
89 filelogger->init();
90 break;
91 }case TLF_XunitXml:{
92 logFormatter = new QTestXunitStreamer;
93 delete errorLogElement;
94 errorLogElement = new QTestElement(QTest::LET_SystemError);
95 filelogger->init();
96 break;
97 }
98 }
99
100 logFormatter->setLogger(this);
101 logFormatter->startStreaming();
102}
103
104void QTestLogger::stopLogging()
105{
106 QTestElement *iterator = listOfTestcases;
107
108 if(format == TLF_XunitXml ){
109 char buf[10];
110
111 currentLogElement = new QTestElement(QTest::LET_TestSuite);
112 currentLogElement->addAttribute(QTest::AI_Name, QTestResult::currentTestObjectName());
113
114 QTest::qt_snprintf(buf, sizeof(buf), "%i", testCounter);
115 currentLogElement->addAttribute(QTest::AI_Tests, buf);
116
117 QTest::qt_snprintf(buf, sizeof(buf), "%i", failureCounter);
118 currentLogElement->addAttribute(QTest::AI_Failures, buf);
119
120 QTest::qt_snprintf(buf, sizeof(buf), "%i", errorCounter);
121 currentLogElement->addAttribute(QTest::AI_Errors, buf);
122
123 QTestElement *property;
124 QTestElement *properties = new QTestElement(QTest::LET_Properties);
125
126 property = new QTestElement(QTest::LET_Property);
127 property->addAttribute(QTest::AI_Name, "QTestVersion");
128 property->addAttribute(QTest::AI_PropertyValue, QTEST_VERSION_STR);
129 properties->addLogElement(property);
130
131 property = new QTestElement(QTest::LET_Property);
132 property->addAttribute(QTest::AI_Name, "QtVersion");
133 property->addAttribute(QTest::AI_PropertyValue, qVersion());
134 properties->addLogElement(property);
135
136 currentLogElement->addLogElement(properties);
137
138 currentLogElement->addLogElement(iterator);
139
140 /* For correct indenting, make sure every testcase knows its parent */
141 QTestElement* testcase = iterator;
142 while (testcase) {
143 testcase->setParent(currentLogElement);
144 testcase = testcase->nextElement();
145 }
146
147 currentLogElement->addLogElement(errorLogElement);
148
149 QTestElement *it = currentLogElement;
150 logFormatter->output(it);
151 }else{
152 logFormatter->output(iterator);
153 }
154
155 logFormatter->stopStreaming();
156}
157
158void QTestLogger::enterTestFunction(const char *function)
159{
160 char buf[1024];
161 QTest::qt_snprintf(buf, sizeof(buf), "Entered test-function: %s\n", function);
162 filelogger->flush(buf);
163
164 currentLogElement = new QTestElement(QTest::LET_TestCase);
165 currentLogElement->addAttribute(QTest::AI_Name, function);
166 currentLogElement->addToList(&listOfTestcases);
167
168 ++testCounter;
169}
170
171void QTestLogger::leaveTestFunction()
172{
173}
174
175void QTestLogger::addIncident(IncidentTypes type, const char *description,
176 const char *file, int line)
177{
178 const char *typeBuf = 0;
179 char buf[100];
180
181 switch (type) {
182 case QAbstractTestLogger::XPass:
183 ++failureCounter;
184 typeBuf = "xpass";
185 break;
186 case QAbstractTestLogger::Pass:
187 ++passCounter;
188 typeBuf = "pass";
189 break;
190 case QAbstractTestLogger::XFail:
191 ++passCounter;
192 typeBuf = "xfail";
193 break;
194 case QAbstractTestLogger::Fail:
195 ++failureCounter;
196 typeBuf = "fail";
197 break;
198 default:
199 typeBuf = "??????";
200 break;
201 }
202
203 if (type == QAbstractTestLogger::Fail || type == QAbstractTestLogger::XPass
204 || ((format != TLF_XunitXml) && (type == QAbstractTestLogger::XFail))) {
205 QTestElement *failureElement = new QTestElement(QTest::LET_Failure);
206 failureElement->addAttribute(QTest::AI_Result, typeBuf);
207 if(file)
208 failureElement->addAttribute(QTest::AI_File, file);
209 else
210 failureElement->addAttribute(QTest::AI_File, "");
211 QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
212 failureElement->addAttribute(QTest::AI_Line, buf);
213 failureElement->addAttribute(QTest::AI_Description, description);
214 addTag(failureElement);
215 currentLogElement->addLogElement(failureElement);
216 }
217
218 /*
219 Only one result can be shown for the whole testfunction.
220 Check if we currently have a result, and if so, overwrite it
221 iff the new result is worse.
222 */
223 QTestElementAttribute* resultAttr =
224 const_cast<QTestElementAttribute*>(currentLogElement->attribute(QTest::AI_Result));
225 if (resultAttr) {
226 const char* oldResult = resultAttr->value();
227 bool overwrite = false;
228 if (!strcmp(oldResult, "pass")) {
229 overwrite = true;
230 }
231 else if (!strcmp(oldResult, "xfail")) {
232 overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail);
233 }
234 else if (!strcmp(oldResult, "xpass")) {
235 overwrite = (type == QAbstractTestLogger::Fail);
236 }
237 if (overwrite) {
238 resultAttr->setPair(QTest::AI_Result, typeBuf);
239 }
240 }
241 else {
242 currentLogElement->addAttribute(QTest::AI_Result, typeBuf);
243 }
244
245 if(file)
246 currentLogElement->addAttribute(QTest::AI_File, file);
247 else
248 currentLogElement->addAttribute(QTest::AI_File, "");
249
250 QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
251 currentLogElement->addAttribute(QTest::AI_Line, buf);
252
253 /*
254 Since XFAIL does not add a failure to the testlog in xunitxml, add a message, so we still
255 have some information about the expected failure.
256 */
257 if (format == TLF_XunitXml && type == QAbstractTestLogger::XFail) {
258 QTestLogger::addMessage(QAbstractTestLogger::Info, description, file, line);
259 }
260}
261
262void QTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
263{
264 QTestElement *benchmarkElement = new QTestElement(QTest::LET_Benchmark);
265// printf("element %i", benchmarkElement->elementType());
266
267 benchmarkElement->addAttribute(QTest::AI_Metric, QBenchmarkGlobalData::current->measurer->metricText().toAscii().data());
268 benchmarkElement->addAttribute(QTest::AI_Tag, result.context.tag.toAscii().data());
269 benchmarkElement->addAttribute(QTest::AI_Value, QByteArray::number(result.value).constData());
270
271 char buf[100];
272 QTest::qt_snprintf(buf, sizeof(buf), "%i", result.iterations);
273 benchmarkElement->addAttribute(QTest::AI_Iterations, buf);
274 currentLogElement->addLogElement(benchmarkElement);
275}
276
277void QTestLogger::addTag(QTestElement* element)
278{
279 const char *tag = QTestResult::currentDataTag();
280 const char *gtag = QTestResult::currentGlobalDataTag();
281 const char *filler = (tag && gtag) ? ":" : "";
282 if ((!tag || !tag[0]) && (!gtag || !gtag[0])) {
283 return;
284 }
285
286 if (!tag) {
287 tag = "";
288 }
289 if (!gtag) {
290 gtag = "";
291 }
292
293 QTestCharBuffer buf;
294 QTest::qt_asprintf(&buf, "%s%s%s", gtag, filler, tag);
295 element->addAttribute(QTest::AI_Tag, buf.constData());
296}
297
298void QTestLogger::addMessage(MessageTypes type, const char *message, const char *file, int line)
299{
300 QTestElement *errorElement = new QTestElement(QTest::LET_Error);
301 const char *typeBuf = 0;
302
303 switch (type) {
304 case QAbstractTestLogger::Warn:
305 ++warningCounter;
306 typeBuf = "warn";
307 break;
308 case QAbstractTestLogger::QSystem:
309 ++systemCounter;
310 typeBuf = "system";
311 break;
312 case QAbstractTestLogger::QDebug:
313 ++qdebugCounter;
314 typeBuf = "qdebug";
315 break;
316 case QAbstractTestLogger::QWarning:
317 ++qwarnCounter;
318 typeBuf = "qwarn";
319 break;
320 case QAbstractTestLogger::QFatal:
321 ++qfatalCounter;
322 typeBuf = "qfatal";
323 break;
324 case QAbstractTestLogger::Skip:
325 ++skipCounter;
326 typeBuf = "skip";
327 break;
328 case QAbstractTestLogger::Info:
329 ++infoCounter;
330 typeBuf = "info";
331 break;
332 default:
333 typeBuf = "??????";
334 break;
335 }
336
337 errorElement->addAttribute(QTest::AI_Type, typeBuf);
338 errorElement->addAttribute(QTest::AI_Description, message);
339 addTag(errorElement);
340
341 if(file)
342 errorElement->addAttribute(QTest::AI_File, file);
343 else
344 errorElement->addAttribute(QTest::AI_File, "");
345
346 char buf[100];
347 QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
348 errorElement->addAttribute(QTest::AI_Line, buf);
349
350 currentLogElement->addLogElement(errorElement);
351 ++errorCounter;
352
353 // Also add the message to the system error log (i.e. stderr), if one exists
354 if (errorLogElement) {
355 QTestElement *systemErrorElement = new QTestElement(QTest::LET_Error);
356 systemErrorElement->addAttribute(QTest::AI_Description, message);
357 errorLogElement->addLogElement(systemErrorElement);
358 }
359}
360
361void QTestLogger::setLogFormat(TestLoggerFormat fm)
362{
363 format = fm;
364}
365
366QTestLogger::TestLoggerFormat QTestLogger::logFormat()
367{
368 return format;
369}
370
371int QTestLogger::passCount() const
372{
373 return passCounter;
374}
375
376int QTestLogger::failureCount() const
377{
378 return failureCounter;
379}
380
381int QTestLogger::errorCount() const
382{
383 return errorCounter;
384}
385
386int QTestLogger::warningCount() const
387{
388 return warningCounter;
389}
390
391int QTestLogger::skipCount() const
392{
393 return skipCounter;
394}
395
396int QTestLogger::systemCount() const
397{
398 return systemCounter;
399}
400
401int QTestLogger::qdebugCount() const
402{
403 return qdebugCounter;
404}
405
406int QTestLogger::qwarnCount() const
407{
408 return qwarnCounter;
409}
410
411int QTestLogger::qfatalCount() const
412{
413 return qfatalCounter;
414}
415
416int QTestLogger::infoCount() const
417{
418 return infoCounter;
419}
420
421QT_END_NAMESPACE
422
Note: See TracBrowser for help on using the repository browser.