6#include <QtCore/qglobal.h>
7#include <QtCore/qlibraryinfo.h>
9#include <QtTest/private/qtestlog_p.h>
10#include <QtTest/private/qxmltestlogger_p.h>
11#include <QtTest/private/qtestresult_p.h>
12#include <QtTest/private/qbenchmark_p.h>
13#include <QtTest/private/qbenchmarkmetric_p.h>
14#include <QtTest/qtestcase.h>
23 case QAbstractTestLogger::QDebug:
25 case QAbstractTestLogger::QInfo:
27 case QAbstractTestLogger::QWarning:
29 case QAbstractTestLogger::QCritical:
31 case QAbstractTestLogger::QFatal:
33 case QAbstractTestLogger::Info:
35 case QAbstractTestLogger::Warn:
44 case QAbstractTestLogger::Skip:
46 case QAbstractTestLogger::Pass:
48 case QAbstractTestLogger::XFail:
50 case QAbstractTestLogger::Fail:
52 case QAbstractTestLogger::XPass:
54 case QAbstractTestLogger::BlacklistedPass:
56 case QAbstractTestLogger::BlacklistedFail:
58 case QAbstractTestLogger::BlacklistedXPass:
60 case QAbstractTestLogger::BlacklistedXFail:
69
70
71
72
73
74
75
77
78
79
80
81
82
83
84
85
86
87
89QXmlTestLogger::QXmlTestLogger(XmlMode mode,
const char *filename)
90 : QAbstractTestLogger(filename), xmlmode(mode)
94QXmlTestLogger::~QXmlTestLogger() =
default;
96void QXmlTestLogger::startLogging()
98 QAbstractTestLogger::startLogging();
101 if (xmlmode == QXmlTestLogger::Complete) {
102 QTestCharBuffer quotedTc;
103 QTest::qt_asprintf(&buf,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
104 outputString(buf.constData());
105 if (xmlQuote("edTc, QTestResult::currentTestObjectName())) {
106 QTest::qt_asprintf(&buf,
"<TestCase name=\"%s\">\n", quotedTc.constData());
107 outputString(buf.constData());
110 Q_ASSERT_X(
false,
"QXmlTestLogger::startLogging",
111 "Insanely long test-case name or OOM issue");
115 QTestCharBuffer quotedBuild;
116 if (!QLibraryInfo::build() || xmlQuote("edBuild, QLibraryInfo::build())) {
117 QTest::qt_asprintf(&buf,
119 " <QtVersion>%s</QtVersion>\n"
120 " <QtBuild>%s</QtBuild>\n"
121 " <QTestVersion>" QTEST_VERSION_STR
"</QTestVersion>\n"
122 " </Environment>\n", qVersion(), quotedBuild.constData());
123 outputString(buf.constData());
127void QXmlTestLogger::stopLogging()
131 QTest::qt_asprintf(&buf,
" <Duration msecs=\"%s\"/>\n",
132 QString::number(QTestLog::msecsTotalTime()).toUtf8().constData());
133 outputString(buf.constData());
134 if (xmlmode == QXmlTestLogger::Complete)
135 outputString(
"</TestCase>\n");
137 QAbstractTestLogger::stopLogging();
140void QXmlTestLogger::enterTestFunction(
const char *function)
142 QTestCharBuffer quotedFunction;
143 if (xmlQuote("edFunction, function)) {
145 QTest::qt_asprintf(&buf,
" <TestFunction name=\"%s\">\n", quotedFunction.constData());
146 outputString(buf.constData());
149 Q_ASSERT_X(
false,
"QXmlTestLogger::enterTestFunction",
150 "Insanely long test-function name or OOM issue");
154void QXmlTestLogger::leaveTestFunction()
157 QTest::qt_asprintf(&buf,
158 " <Duration msecs=\"%s\"/>\n"
159 " </TestFunction>\n",
160 QString::number(QTestLog::msecsFunctionTime()).toUtf8().constData());
162 outputString(buf.constData());
170 return !str || !str[0];
177 ?
" <Incident type=\"%s\" file=\"%s\" line=\"%d\" />\n"
178 :
" <Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
179 " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
183 ?
" <Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
184 " <Description><![CDATA[%s%s%s%s]]></Description>\n"
186 :
" <Incident type=\"%s\" file=\"%s\" line=\"%d\">\n"
187 " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
188 " <Description><![CDATA[%s]]></Description>\n"
194 return " <BenchmarkResult metric=\"%s\" tag=\"%s\" value=\"%.6g\" variance=\"%.6g\" iterations=\"%d\" />\n";
201 return " <Message type=\"%s\" file=\"%s\" line=\"%d\" />\n";
203 return " <Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
204 " <DataTag><![CDATA[%s%s%s%s]]></DataTag>\n"
208 return " <Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
209 " <Description><![CDATA[%s%s%s%s]]></Description>\n"
212 return " <Message type=\"%s\" file=\"%s\" line=\"%d\">\n"
213 " <DataTag><![CDATA[%s%s%s]]></DataTag>\n"
214 " <Description><![CDATA[%s]]></Description>\n"
221void QXmlTestLogger::addIncident(IncidentTypes type,
const char *description,
222 const char *file,
int line)
225 const char *tag = QTestResult::currentDataTag();
226 const char *gtag = QTestResult::currentGlobalDataTag();
227 const char *filler = (tag && gtag) ?
":" :
"";
228 const bool notag = QTest::isEmpty(tag) && QTest::isEmpty(gtag);
230 QTestCharBuffer quotedFile;
231 QTestCharBuffer cdataGtag;
232 QTestCharBuffer cdataTag;
233 QTestCharBuffer cdataDescription;
235 if (xmlQuote("edFile, file)
236 && xmlCdata(&cdataGtag, gtag)
237 && xmlCdata(&cdataTag, tag)
238 && xmlCdata(&cdataDescription, description)) {
240 QTest::qt_asprintf(&buf,
241 QTest::incidentFormatString(QTest::isEmpty(description), notag),
242 QTest::xmlIncidentType2String(type),
243 quotedFile.constData(), line,
244 cdataGtag.constData(),
246 cdataTag.constData(),
247 cdataDescription.constData());
249 outputString(buf.constData());
253void QXmlTestLogger::addBenchmarkResult(
const QBenchmarkResult &result)
255 QTestCharBuffer quotedMetric;
256 QTestCharBuffer quotedTag;
258 if (xmlQuote("edMetric, benchmarkMetricName(result.measurement.metric))
259 && xmlQuote("edTag, result.context.tag.toUtf8().constData())) {
261 QTest::qt_asprintf(&buf,
262 QTest::benchmarkResultFormatString(),
263 quotedMetric.constData(),
264 quotedTag.constData(),
265 result.measurement.value /
double(result.iterations),
266 result.measurement.variance,
268 outputString(buf.constData());
272void QXmlTestLogger::addMessage(MessageTypes type,
const QString &message,
273 const char *file,
int line)
276 QTestCharBuffer quotedFile;
277 QTestCharBuffer cdataGtag;
278 QTestCharBuffer cdataTag;
279 QTestCharBuffer cdataDescription;
286 const QTestResult::IdentifierLocker locker;
287 const char *tag = locker.dataTag();
288 const char *gtag = locker.globalDataTag();
289 filler = (tag && gtag) ?
":" :
"";
290 notag = QTest::isEmpty(tag) && QTest::isEmpty(gtag);
291 quoted = xmlQuote("edFile, file) && xmlCdata(&cdataGtag, gtag)
292 && xmlCdata(&cdataTag, tag);
294 quoted = quoted && xmlCdata(&cdataDescription, message.toUtf8().constData());
297 QTest::qt_asprintf(&buf,
298 QTest::messageFormatString(message.isEmpty(), notag),
299 QTest::xmlMessageType2String(type),
300 quotedFile.constData(), line,
301 cdataGtag.constData(),
303 cdataTag.constData(),
304 cdataDescription.constData());
306 outputString(buf.constData());
310int QXmlTestLogger::xmlQuote(QTestCharBuffer *destBuf,
char const *src, qsizetype n)
314 Q_ASSERT(n >= 512 && destBuf->size() == n);
315 char *dest = destBuf->data();
323 char *end = dest + n;
328#define MAP_ENTITY(chr, ent)
330 if (dest + sizeof(ent) < end) {
332 dest += sizeof(ent) - 1
;
335 return dest + sizeof(ent) - begin;
365 Q_ASSERT(dest == end && end > begin);
370int QXmlTestLogger::xmlCdata(QTestCharBuffer *destBuf,
char const *src, qsizetype n)
372 Q_ASSERT(n >= 512 && destBuf->size() == n);
373 char *dest = destBuf->data();
380 static char const CDATA_END[] =
"]]>";
381 static char const CDATA_END_ESCAPED[] =
"]]]><![CDATA[]>";
382 const size_t CDATA_END_LEN =
sizeof(CDATA_END) - 1;
385 char *end = dest + n;
392 if (!strncmp(src, CDATA_END, CDATA_END_LEN)) {
393 if (dest +
sizeof(CDATA_END_ESCAPED) < end) {
394 strcpy(dest, CDATA_END_ESCAPED);
395 src += CDATA_END_LEN;
396 dest +=
sizeof(CDATA_END_ESCAPED) - 1;
399 return dest +
sizeof(CDATA_END_ESCAPED) - begin;
410 Q_ASSERT(dest == end && end > begin);
418
419
420
423 constexpr int MAXSIZE = 1024 * 1024 * 2;
424 int size = str->size();
425 Q_ASSERT(size >= 512 && !str->data()[0]);
428 const int res = func(str, src, size);
430 Q_ASSERT(res > 0 || (!res && (!src || !src[0])));
436 }
while (size <= MAXSIZE && str->reset(size));
442
443
444
445
446
447
448
449
450bool QXmlTestLogger::xmlQuote(QTestCharBuffer *str,
char const *src)
452 return allocateStringFn(str, src, QXmlTestLogger::xmlQuote);
456
457
458
459
460
461
462
463bool QXmlTestLogger::xmlCdata(QTestCharBuffer *str,
char const *src)
465 return allocateStringFn(str, src, QXmlTestLogger::xmlCdata);
static const char * xmlIncidentType2String(QAbstractTestLogger::IncidentTypes type)
static const char * incidentFormatString(bool noDescription, bool noTag)
static const char * benchmarkResultFormatString()
static bool isEmpty(const char *str)
static const char * xmlMessageType2String(QAbstractTestLogger::MessageTypes type)
static const char * messageFormatString(bool noDescription, bool noTag)
#define MAP_ENTITY(chr, ent)
static bool allocateStringFn(QTestCharBuffer *str, char const *src, StringFormatFunction func)
int(* StringFormatFunction)(QTestCharBuffer *, char const *, qsizetype)