qplaintestlogger.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/testlib/qplaintestlogger.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtTest module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include <QtTest/private/qtestresult_p.h>-
41#include <QtTest/qtestassert.h>-
42#include <QtTest/private/qtestlog_p.h>-
43#include <QtTest/private/qplaintestlogger_p.h>-
44#include <QtTest/private/qbenchmark_p.h>-
45#include <QtTest/private/qbenchmarkmetric_p.h>-
46-
47#include <stdarg.h>-
48#include <stdio.h>-
49#include <stdlib.h>-
50#include <string.h>-
51-
52#ifdef Q_OS_WINCE-
53#include <QtCore/QString>-
54#endif-
55-
56#ifdef min // windows.h without NOMINMAX is included by the benchmark headers.-
57# undef min-
58#endif-
59#ifdef max-
60# undef max-
61#endif-
62-
63#include <QtCore/QByteArray>-
64#include <QtCore/qmath.h>-
65#include <QtCore/QLibraryInfo>-
66-
67#ifdef Q_OS_ANDROID-
68# include <android/log.h>-
69#endif-
70-
71#ifdef Q_OS_WIN-
72# include <qt_windows.h>-
73#endif-
74-
75QT_BEGIN_NAMESPACE-
76-
77namespace QTest {-
78-
79 static const char *incidentType2String(QAbstractTestLogger::IncidentTypes type)-
80 {-
81 switch (type) {-
82 case QAbstractTestLogger::Pass:-
83 return "PASS ";-
84 case QAbstractTestLogger::XFail:-
85 return "XFAIL ";-
86 case QAbstractTestLogger::Fail:-
87 return "FAIL! ";-
88 case QAbstractTestLogger::XPass:-
89 return "XPASS ";-
90 case QAbstractTestLogger::BlacklistedPass:-
91 return "BPASS ";-
92 case QAbstractTestLogger::BlacklistedFail:-
93 return "BFAIL ";-
94 }-
95 return "??????";-
96 }-
97-
98 static const char *benchmarkResult2String()-
99 {-
100 return "RESULT ";-
101 }-
102-
103 static const char *messageType2String(QAbstractTestLogger::MessageTypes type)-
104 {-
105 switch (type) {-
106 case QAbstractTestLogger::Skip:-
107 return "SKIP ";-
108 case QAbstractTestLogger::Warn:-
109 return "WARNING";-
110 case QAbstractTestLogger::QWarning:-
111 return "QWARN ";-
112 case QAbstractTestLogger::QDebug:-
113 return "QDEBUG ";-
114 case QAbstractTestLogger::QInfo:-
115 return "QINFO ";-
116 case QAbstractTestLogger::QSystem:-
117 return "QSYSTEM";-
118 case QAbstractTestLogger::QFatal:-
119 return "QFATAL ";-
120 case QAbstractTestLogger::Info:-
121 return "INFO ";-
122 }-
123 return "??????";-
124 }-
125-
126 template <typename T>-
127 static int countSignificantDigits(T num)-
128 {-
129 if (num <= 0)-
130 return 0;-
131-
132 int digits = 0;-
133 qreal divisor = 1;-
134-
135 while (num / divisor >= 1) {-
136 divisor *= 10;-
137 ++digits;-
138 }-
139-
140 return digits;-
141 }-
142-
143 // Pretty-prints a benchmark result using the given number of digits.-
144 template <typename T> QString formatResult(T number, int significantDigits)-
145 {-
146 if (number < T(0))-
147 return QLatin1String("NAN");-
148 if (number == T(0))-
149 return QLatin1String("0");-
150-
151 QString beforeDecimalPoint = QString::number(qint64(number), 'f', 0);-
152 QString afterDecimalPoint = QString::number(number, 'f', 20);-
153 afterDecimalPoint.remove(0, beforeDecimalPoint.count() + 1);-
154-
155 int beforeUse = qMin(beforeDecimalPoint.count(), significantDigits);-
156 int beforeRemove = beforeDecimalPoint.count() - beforeUse;-
157-
158 // Replace insignificant digits before the decimal point with zeros.-
159 beforeDecimalPoint.chop(beforeRemove);-
160 for (int i = 0; i < beforeRemove; ++i) {-
161 beforeDecimalPoint.append(QLatin1Char('0'));-
162 }-
163-
164 int afterUse = significantDigits - beforeUse;-
165-
166 // leading zeroes after the decimal point does not count towards the digit use.-
167 if (beforeDecimalPoint == QLatin1String("0") && afterDecimalPoint.isEmpty() == false) {-
168 ++afterUse;-
169-
170 int i = 0;-
171 while (i < afterDecimalPoint.count() && afterDecimalPoint.at(i) == QLatin1Char('0')) {-
172 ++i;-
173 }-
174-
175 afterUse += i;-
176 }-
177-
178 int afterRemove = afterDecimalPoint.count() - afterUse;-
179 afterDecimalPoint.chop(afterRemove);-
180-
181 QChar separator = QLatin1Char(',');-
182 QChar decimalPoint = QLatin1Char('.');-
183-
184 // insert thousands separators-
185 int length = beforeDecimalPoint.length();-
186 for (int i = beforeDecimalPoint.length() -1; i >= 1; --i) {-
187 if ((length - i) % 3 == 0)-
188 beforeDecimalPoint.insert(i, separator);-
189 }-
190-
191 QString print;-
192 print = beforeDecimalPoint;-
193 if (afterUse > 0)-
194 print.append(decimalPoint);-
195-
196 print += afterDecimalPoint;-
197-
198-
199 return print;-
200 }-
201-
202 template <typename T>-
203 int formatResult(char * buffer, int bufferSize, T number, int significantDigits)-
204 {-
205 QString result = formatResult(number, significantDigits);-
206 qstrncpy(buffer, result.toLatin1().constData(), bufferSize);-
207 int size = result.count();-
208 return size;-
209 }-
210}-
211-
212#if defined(Q_OS_WIN)-
213Q_CORE_EXPORT bool qt_logging_to_console(); // defined in qlogging.cpp-
214#endif-
215-
216void QPlainTestLogger::outputMessage(const char *str)-
217{-
218#if defined(Q_OS_WINCE)-
219 QString strUtf16 = QString::fromLocal8Bit(str);-
220 const int maxOutputLength = 255;-
221 do {-
222 QString tmp = strUtf16.left(maxOutputLength);-
223 OutputDebugString((wchar_t*)tmp.utf16());-
224 strUtf16.remove(0, maxOutputLength);-
225 } while (!strUtf16.isEmpty());-
226 if (stream != stdout)-
227#elif defined(Q_OS_WIN)-
228 // log to system log only if output is not redirected, and no console is attached-
229 if (!qt_logging_to_console() && stream == stdout) {-
230 OutputDebugStringA(str);-
231 return;-
232 }-
233#elif defined(Q_OS_ANDROID)-
234 __android_log_write(ANDROID_LOG_INFO, "QTestLib", str);-
235#endif-
236 outputString(str);-
237}-
238-
239void QPlainTestLogger::printMessage(const char *type, const char *msg, const char *file, int line)-
240{-
241 QTEST_ASSERT(type);-
242 QTEST_ASSERT(msg);-
243-
244 QTestCharBuffer buf;-
245-
246 const char *fn = QTestResult::currentTestFunction() ? QTestResult::currentTestFunction()-
247 : "UnknownTestFunc";-
248 const char *tag = QTestResult::currentDataTag() ? QTestResult::currentDataTag() : "";-
249 const char *gtag = QTestResult::currentGlobalDataTag()-
250 ? QTestResult::currentGlobalDataTag()-
251 : "";-
252 const char *filler = (tag[0] && gtag[0]) ? ":" : "";-
253 if (file) {-
254 QTest::qt_asprintf(&buf, "%s: %s::%s(%s%s%s)%s%s\n"-
255#ifdef Q_OS_WIN-
256 "%s(%d) : failure location\n"-
257#else-
258 " Loc: [%s(%d)]\n"-
259#endif-
260 , type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag,-
261 msg[0] ? " " : "", msg, file, line);-
262 } else {-
263 QTest::qt_asprintf(&buf, "%s: %s::%s(%s%s%s)%s%s\n",-
264 type, QTestResult::currentTestObjectName(), fn, gtag, filler, tag,-
265 msg[0] ? " " : "", msg);-
266 }-
267 // In colored mode, printf above stripped our nonprintable control characters.-
268 // Put them back.-
269 memcpy(buf.data(), type, strlen(type));-
270 outputMessage(buf.data());-
271}-
272-
273void QPlainTestLogger::printBenchmarkResult(const QBenchmarkResult &result)-
274{-
275 const char *bmtag = QTest::benchmarkResult2String();-
276-
277 char buf1[1024];-
278 qsnprintf(-
279 buf1, sizeof(buf1), "%s: %s::%s",-
280 bmtag,-
281 QTestResult::currentTestObjectName(),-
282 result.context.slotName.toLatin1().data());-
283-
284 char bufTag[1024];-
285 bufTag[0] = 0;-
286 QByteArray tag = result.context.tag.toLocal8Bit();-
287 if (tag.isEmpty() == false) {-
288 qsnprintf(bufTag, sizeof(bufTag), ":\"%s\"", tag.data());-
289 }-
290-
291-
292 char fillFormat[8];-
293 int fillLength = 5;-
294 qsnprintf(fillFormat, sizeof(fillFormat), ":\n%%%ds", fillLength);-
295 char fill[1024];-
296 qsnprintf(fill, sizeof(fill), fillFormat, "");-
297-
298 const char * unitText = QTest::benchmarkMetricUnit(result.metric);-
299-
300 qreal valuePerIteration = qreal(result.value) / qreal(result.iterations);-
301 char resultBuffer[100] = "";-
302 QTest::formatResult(resultBuffer, 100, valuePerIteration, QTest::countSignificantDigits(result.value));-
303-
304 char buf2[1024];-
305 qsnprintf(buf2, sizeof(buf2), "%s %s", resultBuffer, unitText);-
306-
307 char buf2_[1024];-
308 QByteArray iterationText = " per iteration";-
309 Q_ASSERT(result.iterations > 0);-
310 qsnprintf(buf2_, sizeof(buf2_), "%s", iterationText.data());-
311-
312 char buf3[1024];-
313 Q_ASSERT(result.iterations > 0);-
314 QTest::formatResult(resultBuffer, 100, result.value, QTest::countSignificantDigits(result.value));-
315 qsnprintf(buf3, sizeof(buf3), " (total: %s, iterations: %d)", resultBuffer, result.iterations);-
316-
317 char buf[1024];-
318-
319 if (result.setByMacro) {-
320 qsnprintf(buf, sizeof(buf), "%s%s%s%s%s%s\n", buf1, bufTag, fill, buf2, buf2_, buf3);-
321 } else {-
322 qsnprintf(buf, sizeof(buf), "%s%s%s%s\n", buf1, bufTag, fill, buf2);-
323 }-
324-
325 memcpy(buf, bmtag, strlen(bmtag));-
326 outputMessage(buf);-
327}-
328-
329QPlainTestLogger::QPlainTestLogger(const char *filename)-
330 : QAbstractTestLogger(filename)-
331{-
332}-
333-
334QPlainTestLogger::~QPlainTestLogger()-
335{-
336}-
337-
338void QPlainTestLogger::startLogging()-
339{-
340 QAbstractTestLogger::startLogging();-
341-
342 char buf[1024];-
343 if (QTestLog::verboseLevel() < 0) {-
344 qsnprintf(buf, sizeof(buf), "Testing %s\n", QTestResult::currentTestObjectName());-
345 } else {-
346 qsnprintf(buf, sizeof(buf),-
347 "********* Start testing of %s *********\n"-
348 "Config: Using QtTest library " QTEST_VERSION_STR-
349 ", %s\n", QTestResult::currentTestObjectName(), QLibraryInfo::build());-
350 }-
351 outputMessage(buf);-
352}-
353-
354void QPlainTestLogger::stopLogging()-
355{-
356 char buf[1024];-
357 const int timeMs = qRound(QTestLog::msecsTotalTime());-
358 if (QTestLog::verboseLevel() < 0) {
QTestLog::verboseLevel() < 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_selftests - unknown status
FALSEevaluated 849 times by 506 tests
Evaluated by:
  • tst_Collections
  • tst_Compiler
  • tst_Gestures
  • tst_Lancelot
  • tst_LargeFile
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_PlatformSocketEngine
  • tst_QAbstractAnimation
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSocket
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • ...
2-849
359 qsnprintf(buf, sizeof(buf), "Totals: %d passed, %d failed, %d skipped, %d blacklisted\n"blacklisted, %dms\n",-
360 QTestLog::passCount(), QTestLog::failCount(),-
361 QTestLog::skipCount(), QTestLog::blacklistCount());(), timeMs);-
362 } else {
executed 2 times by 1 test: end of block
Executed by:
  • tst_selftests - unknown status
2
363 qsnprintf(buf, sizeof(buf),-
364 "Totals: %d passed, %d failed, %d skipped, %d blacklisted\n"blacklisted, %dms\n"-
365 "********* Finished testing of %s *********\n",-
366 QTestLog::passCount(), QTestLog::failCount(),-
367 QTestLog::skipCount(), QTestLog::blacklistCount(), timeMs,-
368 QTestResult::currentTestObjectName());-
369 }
executed 849 times by 506 tests: end of block
Executed by:
  • tst_Collections
  • tst_Compiler
  • tst_Gestures
  • tst_Lancelot
  • tst_LargeFile
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_PlatformSocketEngine
  • tst_QAbstractAnimation
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSocket
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • ...
849
370 outputMessage(buf);-
371-
372 QAbstractTestLogger::stopLogging();-
373}
executed 851 times by 506 tests: end of block
Executed by:
  • tst_Collections
  • tst_Compiler
  • tst_Gestures
  • tst_Lancelot
  • tst_LargeFile
  • tst_ModelTest
  • tst_NetworkSelfTest
  • tst_PlatformSocketEngine
  • tst_QAbstractAnimation
  • tst_QAbstractButton
  • tst_QAbstractFileEngine
  • tst_QAbstractItemModel
  • tst_QAbstractItemView
  • tst_QAbstractNetworkCache
  • tst_QAbstractPrintDialog
  • tst_QAbstractProxyModel
  • tst_QAbstractScrollArea
  • tst_QAbstractSlider
  • tst_QAbstractSocket
  • tst_QAbstractSpinBox
  • tst_QAbstractTextDocumentLayout
  • tst_QAccessibility
  • tst_QAction
  • tst_QActionGroup
  • tst_QAlgorithms
  • ...
851
374-
375-
376void QPlainTestLogger::enterTestFunction(const char * /*function*/)-
377{-
378 if (QTestLog::verboseLevel() >= 1)-
379 printMessage(QTest::messageType2String(Info), "entering");-
380}-
381-
382void QPlainTestLogger::leaveTestFunction()-
383{-
384}-
385-
386void QPlainTestLogger::addIncident(IncidentTypes type, const char *description,-
387 const char *file, int line)-
388{-
389 // suppress PASS and XFAIL in silent mode-
390 if ((type == QAbstractTestLogger::Pass || type == QAbstractTestLogger::XFail)-
391 && QTestLog::verboseLevel() < 0)-
392 return;-
393-
394 printMessage(QTest::incidentType2String(type), description, file, line);-
395}-
396-
397void QPlainTestLogger::addBenchmarkResult(const QBenchmarkResult &result)-
398{-
399 // suppress benchmark results in silent mode-
400 if (QTestLog::verboseLevel() < 0)-
401 return;-
402-
403 printBenchmarkResult(result);-
404}-
405-
406void QPlainTestLogger::addMessage(MessageTypes type, const QString &message,-
407 const char *file, int line)-
408{-
409 // suppress non-fatal messages in silent mode-
410 if (type != QAbstractTestLogger::QFatal && QTestLog::verboseLevel() < 0)-
411 return;-
412-
413 printMessage(QTest::messageType2String(type), qPrintable(message), file, line);-
414}-
415-
416QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9