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

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

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 12.0 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 const char* tag = QTestResult::currentDataTag();
215 if (tag) {
216 failureElement->addAttribute(QTest::AI_Tag, tag);
217 }
218 currentLogElement->addLogElement(failureElement);
219 }
220
221 /*
222 Only one result can be shown for the whole testfunction.
223 Check if we currently have a result, and if so, overwrite it
224 iff the new result is worse.
225 */
226 QTestElementAttribute* resultAttr =
227 const_cast<QTestElementAttribute*>(currentLogElement->attribute(QTest::AI_Result));
228 if (resultAttr) {
229 const char* oldResult = resultAttr->value();
230 bool overwrite = false;
231 if (!strcmp(oldResult, "pass")) {
232 overwrite = true;
233 }
234 else if (!strcmp(oldResult, "xfail")) {
235 overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail);
236 }
237 else if (!strcmp(oldResult, "xpass")) {
238 overwrite = (type == QAbstractTestLogger::Fail);
239 }
240 if (overwrite) {
241 resultAttr->setPair(QTest::AI_Result, typeBuf);
242 }
243 }
244 else {
245 currentLogElement->addAttribute(QTest::AI_Result, typeBuf);
246 }
247
248 if(file)
249 currentLogElement->addAttribute(QTest::AI_File, file);
250 else
251 currentLogElement->addAttribute(QTest::AI_File, "");
252
253 QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
254 currentLogElement->addAttribute(QTest::AI_Line, buf);
255
256 /*
257 Since XFAIL does not add a failure to the testlog in xunitxml, add a message, so we still
258 have some information about the expected failure.
259 */
260 if (format == TLF_XunitXml && type == QAbstractTestLogger::XFail) {
261 QTestLogger::addMessage(QAbstractTestLogger::Info, description, file, line);
262 }
263}
264
265void QTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
266{
267 QTestElement *benchmarkElement = new QTestElement(QTest::LET_Benchmark);
268// printf("element %i", benchmarkElement->elementType());
269
270 benchmarkElement->addAttribute(QTest::AI_Metric, QBenchmarkGlobalData::current->measurer->metricText().toAscii().data());
271 benchmarkElement->addAttribute(QTest::AI_Tag, result.context.tag.toAscii().data());
272 benchmarkElement->addAttribute(QTest::AI_Value, QByteArray::number(result.value).constData());
273
274 char buf[100];
275 QTest::qt_snprintf(buf, sizeof(buf), "%i", result.iterations);
276 benchmarkElement->addAttribute(QTest::AI_Iterations, buf);
277 currentLogElement->addLogElement(benchmarkElement);
278}
279
280void QTestLogger::addMessage(MessageTypes type, const char *message, const char *file, int line)
281{
282 QTestElement *errorElement = new QTestElement(QTest::LET_Error);
283 const char *typeBuf = 0;
284
285 switch (type) {
286 case QAbstractTestLogger::Warn:
287 ++warningCounter;
288 typeBuf = "warn";
289 break;
290 case QAbstractTestLogger::QSystem:
291 ++systemCounter;
292 typeBuf = "system";
293 break;
294 case QAbstractTestLogger::QDebug:
295 ++qdebugCounter;
296 typeBuf = "qdebug";
297 break;
298 case QAbstractTestLogger::QWarning:
299 ++qwarnCounter;
300 typeBuf = "qwarning";
301 break;
302 case QAbstractTestLogger::QFatal:
303 ++qfatalCounter;
304 typeBuf = "qfatal";
305 break;
306 case QAbstractTestLogger::Skip:
307 ++skipCounter;
308 typeBuf = "skip";
309 break;
310 case QAbstractTestLogger::Info:
311 ++infoCounter;
312 typeBuf = "info";
313 break;
314 default:
315 typeBuf = "??????";
316 break;
317 }
318
319 errorElement->addAttribute(QTest::AI_Type, typeBuf);
320 errorElement->addAttribute(QTest::AI_Description, message);
321
322 if(file)
323 errorElement->addAttribute(QTest::AI_File, file);
324 else
325 errorElement->addAttribute(QTest::AI_File, "");
326
327 char buf[100];
328 QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
329 errorElement->addAttribute(QTest::AI_Line, buf);
330
331 currentLogElement->addLogElement(errorElement);
332 ++errorCounter;
333
334 // Also add the message to the system error log (i.e. stderr), if one exists
335 if (errorLogElement) {
336 QTestElement *systemErrorElement = new QTestElement(QTest::LET_Error);
337 systemErrorElement->addAttribute(QTest::AI_Description, message);
338 errorLogElement->addLogElement(systemErrorElement);
339 }
340}
341
342void QTestLogger::setLogFormat(TestLoggerFormat fm)
343{
344 format = fm;
345}
346
347QTestLogger::TestLoggerFormat QTestLogger::logFormat()
348{
349 return format;
350}
351
352int QTestLogger::passCount() const
353{
354 return passCounter;
355}
356
357int QTestLogger::failureCount() const
358{
359 return failureCounter;
360}
361
362int QTestLogger::errorCount() const
363{
364 return errorCounter;
365}
366
367int QTestLogger::warningCount() const
368{
369 return warningCounter;
370}
371
372int QTestLogger::skipCount() const
373{
374 return skipCounter;
375}
376
377int QTestLogger::systemCount() const
378{
379 return systemCounter;
380}
381
382int QTestLogger::qdebugCount() const
383{
384 return qdebugCounter;
385}
386
387int QTestLogger::qwarnCount() const
388{
389 return qwarnCounter;
390}
391
392int QTestLogger::qfatalCount() const
393{
394 return qfatalCounter;
395}
396
397int QTestLogger::infoCount() const
398{
399 return infoCounter;
400}
401
402QT_END_NAMESPACE
403
Note: See TracBrowser for help on using the repository browser.