Don't try to mmap past EOF
[qt-netbsd.git] / src / testlib / qtestlogger.cpp
blob3e89ff7fb5515ead0d83aab99e71172bcd9cf964
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtTest module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
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"
49 #include "QtTest/qtestcase.h"
50 #include "QtTest/private/qtestresult_p.h"
51 #include "QtTest/private/qbenchmark_p.h"
53 #include <string.h>
55 QT_BEGIN_NAMESPACE
57 QTestLogger::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)
69 QTestLogger::~QTestLogger()
71 if(format == TLF_XunitXml)
72 delete currentLogElement;
73 else
74 delete listOfTestcases;
76 delete logFormatter;
77 delete filelogger;
80 void QTestLogger::startLogging()
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;
100 logFormatter->setLogger(this);
101 logFormatter->startStreaming();
104 void QTestLogger::stopLogging()
106 QTestElement *iterator = listOfTestcases;
108 if(format == TLF_XunitXml ){
109 char buf[10];
111 currentLogElement = new QTestElement(QTest::LET_TestSuite);
112 currentLogElement->addAttribute(QTest::AI_Name, QTestResult::currentTestObjectName());
114 QTest::qt_snprintf(buf, sizeof(buf), "%i", testCounter);
115 currentLogElement->addAttribute(QTest::AI_Tests, buf);
117 QTest::qt_snprintf(buf, sizeof(buf), "%i", failureCounter);
118 currentLogElement->addAttribute(QTest::AI_Failures, buf);
120 QTest::qt_snprintf(buf, sizeof(buf), "%i", errorCounter);
121 currentLogElement->addAttribute(QTest::AI_Errors, buf);
123 QTestElement *property;
124 QTestElement *properties = new QTestElement(QTest::LET_Properties);
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);
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);
136 currentLogElement->addLogElement(properties);
138 currentLogElement->addLogElement(iterator);
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();
147 currentLogElement->addLogElement(errorLogElement);
149 QTestElement *it = currentLogElement;
150 logFormatter->output(it);
151 }else{
152 logFormatter->output(iterator);
155 logFormatter->stopStreaming();
158 void QTestLogger::enterTestFunction(const char *function)
160 char buf[1024];
161 QTest::qt_snprintf(buf, sizeof(buf), "Entered test-function: %s\n", function);
162 filelogger->flush(buf);
164 currentLogElement = new QTestElement(QTest::LET_TestCase);
165 currentLogElement->addAttribute(QTest::AI_Name, function);
166 currentLogElement->addToList(&listOfTestcases);
168 ++testCounter;
171 void QTestLogger::leaveTestFunction()
175 void QTestLogger::addIncident(IncidentTypes type, const char *description,
176 const char *file, int line)
178 const char *typeBuf = 0;
179 char buf[100];
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;
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);
218 currentLogElement->addLogElement(failureElement);
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.
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;
234 else if (!strcmp(oldResult, "xfail")) {
235 overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail);
237 else if (!strcmp(oldResult, "xpass")) {
238 overwrite = (type == QAbstractTestLogger::Fail);
240 if (overwrite) {
241 resultAttr->setPair(QTest::AI_Result, typeBuf);
244 else {
245 currentLogElement->addAttribute(QTest::AI_Result, typeBuf);
248 if(file)
249 currentLogElement->addAttribute(QTest::AI_File, file);
250 else
251 currentLogElement->addAttribute(QTest::AI_File, "");
253 QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
254 currentLogElement->addAttribute(QTest::AI_Line, buf);
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.
260 if (format == TLF_XunitXml && type == QAbstractTestLogger::XFail) {
261 QTestLogger::addMessage(QAbstractTestLogger::Info, description, file, line);
265 void QTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
267 QTestElement *benchmarkElement = new QTestElement(QTest::LET_Benchmark);
268 // printf("element %i", benchmarkElement->elementType());
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());
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);
280 void QTestLogger::addMessage(MessageTypes type, const char *message, const char *file, int line)
282 QTestElement *errorElement = new QTestElement(QTest::LET_Error);
283 const char *typeBuf = 0;
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;
319 errorElement->addAttribute(QTest::AI_Type, typeBuf);
320 errorElement->addAttribute(QTest::AI_Description, message);
322 if(file)
323 errorElement->addAttribute(QTest::AI_File, file);
324 else
325 errorElement->addAttribute(QTest::AI_File, "");
327 char buf[100];
328 QTest::qt_snprintf(buf, sizeof(buf), "%i", line);
329 errorElement->addAttribute(QTest::AI_Line, buf);
331 currentLogElement->addLogElement(errorElement);
332 ++errorCounter;
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);
342 void QTestLogger::setLogFormat(TestLoggerFormat fm)
344 format = fm;
347 QTestLogger::TestLoggerFormat QTestLogger::logFormat()
349 return format;
352 int QTestLogger::passCount() const
354 return passCounter;
357 int QTestLogger::failureCount() const
359 return failureCounter;
362 int QTestLogger::errorCount() const
364 return errorCounter;
367 int QTestLogger::warningCount() const
369 return warningCounter;
372 int QTestLogger::skipCount() const
374 return skipCounter;
377 int QTestLogger::systemCount() const
379 return systemCounter;
382 int QTestLogger::qdebugCount() const
384 return qdebugCounter;
387 int QTestLogger::qwarnCount() const
389 return qwarnCounter;
392 int QTestLogger::qfatalCount() const
394 return qfatalCounter;
397 int QTestLogger::infoCount() const
399 return infoCounter;
402 QT_END_NAMESPACE