summaryrefslogtreecommitdiff
path: root/tests/auto/selftests/tst_selftests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/selftests/tst_selftests.cpp')
-rw-r--r--tests/auto/selftests/tst_selftests.cpp403
1 files changed, 220 insertions, 183 deletions
diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp
index 0b9cee0347..f34e2fbdc7 100644
--- a/tests/auto/selftests/tst_selftests.cpp
+++ b/tests/auto/selftests/tst_selftests.cpp
@@ -49,18 +49,12 @@ class tst_Selftests: public QObject
{
Q_OBJECT
private slots:
- void initTestCase();
void runSubTest_data();
void runSubTest();
- void checkXML() const;
- void checkXML_data();
- void checkXunitxml() const;
- void checkXunitxml_data();
+ void cleanupTestCase();
private:
- QStringList m_checkXMLBlacklist;
- QStringList m_checkXunitBlacklist;
- void doRunSubTest(QString &subdir, QStringList &arguments );
+ void doRunSubTest(QString const& subdir, QString const& logger, QStringList const& arguments );
};
struct BenchmarkResult
@@ -121,89 +115,221 @@ QT_END_NAMESPACE
static QList<QByteArray> splitLines(QByteArray ba)
{
ba.replace('\r', "");
- return ba.split('\n');
+ QList<QByteArray> out = ba.split('\n');
+
+ // Replace any ` file="..."' in XML with a generic location.
+ static const char marker[] = " file=\"";
+ for (int i = 0; i < out.size(); ++i) {
+ QByteArray& line = out[i];
+ int index = line.indexOf(marker);
+ if (index == -1) {
+ continue;
+ }
+ int end = line.indexOf('"', index + sizeof(marker));
+ if (end == -1) {
+ continue;
+ }
+ line.replace(index, end-index, " file=\"__FILE__\"");
+ }
+
+ return out;
}
-static QList<QByteArray> expectedResult(const QString &subdir)
+static QList<QByteArray> expectedResult(const QString &subdir, const QString &logger)
{
- QFile file(":/expected_" + subdir + ".txt");
+ QString suffix = logger;
+ if (suffix.isEmpty()) {
+ suffix = "txt";
+ }
+ QFile file(":/expected_" + subdir + "." + suffix);
if (!file.open(QIODevice::ReadOnly))
return QList<QByteArray>();
return splitLines(file.readAll());
}
+struct Logger
+{
+ Logger(QString const&, QString const&, QStringList const&);
+
+ QString name;
+ QString testdata_suffix;
+ QStringList arguments;
+};
+
+Logger::Logger(QString const& _name, QString const& _testdata_suffix, QStringList const& _arguments)
+ : name(_name)
+ , testdata_suffix(_testdata_suffix)
+ , arguments(_arguments)
+{
+}
+
+static QList<Logger> allLoggers()
+{
+ return QList<Logger>()
+ << Logger("plain", "txt", QStringList())
+ << Logger("xml", "xml", QStringList() << "-xml")
+ << Logger("xml flush", "xml", QStringList() << "-xml" << "-flush")
+ << Logger("xunitxml", "xunitxml", QStringList() << "-xunitxml")
+ << Logger("lightxml", "lightxml", QStringList() << "-lightxml")
+ ;
+}
+
void tst_Selftests::runSubTest_data()
{
QTest::addColumn<QString>("subdir");
+ QTest::addColumn<QString>("logger");
QTest::addColumn<QStringList>("arguments");
- QTest::newRow("subtest") << "subtest" << QStringList();
- QTest::newRow("warnings") << "warnings" << QStringList();
- QTest::newRow("maxwarnings") << "maxwarnings" << QStringList();
- QTest::newRow("cmptest") << "cmptest" << QStringList();
-// QTest::newRow("alive") << "alive" << QStringList(); // timer dependent
- QTest::newRow("globaldata") << "globaldata" << QStringList();
- QTest::newRow("skipglobal") << "skipglobal" << QStringList();
- QTest::newRow("skip") << "skip" << QStringList();
- QTest::newRow("strcmp") << "strcmp" << QStringList();
- QTest::newRow("expectfail") << "expectfail" << QStringList();
- QTest::newRow("sleep") << "sleep" << QStringList();
- QTest::newRow("fetchbogus") << "fetchbogus" << QStringList();
- QTest::newRow("crashes") << "crashes" << QStringList();
- QTest::newRow("multiexec") << "multiexec" << QStringList();
- QTest::newRow("failinit") << "failinit" << QStringList();
- QTest::newRow("failinitdata") << "failinitdata" << QStringList();
- QTest::newRow("skipinit") << "skipinit" << QStringList();
- QTest::newRow("skipinitdata") << "skipinitdata" << QStringList();
- QTest::newRow("datetime") << "datetime" << QStringList();
- QTest::newRow("singleskip") << "singleskip" << QStringList();
-
- //on windows assert does nothing in release mode and blocks execution with a popup window in debug mode
+ QStringList tests = QStringList()
+ << "subtest"
+ << "warnings"
+ << "maxwarnings"
+ << "cmptest"
+// << "alive" // timer dependent
+ << "globaldata"
+ << "skipglobal"
+ << "skip"
+ << "strcmp"
+ << "expectfail"
+ << "sleep"
+ << "fetchbogus"
+ << "crashes"
+ << "multiexec"
+ << "failinit"
+ << "failinitdata"
+ << "skipinit"
+ << "skipinitdata"
+ << "datetime"
+ << "singleskip"
+
+ //on windows assert does nothing in release mode and blocks execution with a popup window in debug mode
#if !defined(Q_OS_WIN)
- QTest::newRow("assert") << "assert" << QStringList();
+ << "assert"
#endif
- QTest::newRow("waitwithoutgui") << "waitwithoutgui" << QStringList();
- QTest::newRow("differentexec") << "differentexec" << QStringList();
+ << "waitwithoutgui"
+ << "differentexec"
#ifndef QT_NO_EXCEPTIONS
- // The machine that run the intel autotests will popup a dialog
- // with a warning that an uncaught exception was thrown.
- // This will time out and falsely fail, therefore we disable the test for that platform.
+ // The machine that run the intel autotests will popup a dialog
+ // with a warning that an uncaught exception was thrown.
+ // This will time out and falsely fail, therefore we disable the test for that platform.
# if !defined(Q_CC_INTEL) || !defined(Q_OS_WIN)
- QTest::newRow("exceptionthrow") << "exceptionthrow" << QStringList();
+ << "exceptionthrow"
# endif
#endif
- QTest::newRow("qexecstringlist") << "qexecstringlist" << QStringList();
- QTest::newRow("datatable") << "datatable" << QStringList();
- QTest::newRow("commandlinedata") << "commandlinedata" << QString("fiveTablePasses fiveTablePasses:fiveTablePasses_data1 -v2").split(' ');
+ << "qexecstringlist"
+ << "datatable"
+ << "commandlinedata"
#if defined(__GNUC__) && defined(__i386) && defined(Q_OS_LINUX)
- QTest::newRow("benchlibcallgrind") << "benchlibcallgrind" << QStringList("-callgrind");
+ << "benchlibcallgrind"
#endif
- QTest::newRow("benchlibeventcounter") << "benchlibeventcounter" << QStringList("-eventcounter");
- QTest::newRow("benchliboptions") << "benchliboptions" << QStringList("-eventcounter");
+ << "benchlibeventcounter"
+ << "benchliboptions"
- //### These tests are affected by timing and whether the CPU tick counter is
- //### monotonically increasing. They won't work on some machines so leave them off by default.
- //### Feel free to uncomment for your own testing.
+ //### These tests are affected by timing and whether the CPU tick counter is
+ //### monotonically increasing. They won't work on some machines so leave them off by default.
+ //### Feel free to uncomment for your own testing.
#if 0
- QTest::newRow("benchlibwalltime") << "benchlibwalltime" << QStringList();
- QTest::newRow("benchlibtickcounter") << "benchlibtickcounter" << QStringList("-tickcounter");
+ << "benchlibwalltime"
+ << "benchlibtickcounter"
#endif
- QTest::newRow("xunit") << "xunit" << QStringList("-xunitxml");
- QTest::newRow("longstring") << "longstring" << QStringList();
+ << "xunit"
+ << "longstring"
+ << "badxml"
+ ;
+
+ foreach (Logger const& logger, allLoggers()) {
+ QString rowSuffix;
+ if (logger.name != "plain") {
+ rowSuffix = QString(" %1").arg(logger.name);
+ }
+
+ foreach (QString const& subtest, tests) {
+ QStringList arguments = logger.arguments;
+ if (subtest == "commandlinedata") {
+ arguments << QString("fiveTablePasses fiveTablePasses:fiveTablePasses_data1 -v2").split(' ');
+ }
+ else if (subtest == "benchlibcallgrind") {
+ arguments << "-callgrind";
+ }
+ else if (subtest == "benchlibeventcounter") {
+ arguments << "-eventcounter";
+ }
+ else if (subtest == "benchliboptions") {
+ arguments << "-eventcounter";
+ }
+ else if (subtest == "benchlibtickcounter") {
+ arguments << "-tickcounter";
+ }
+ else if (subtest == "badxml") {
+ arguments << "-eventcounter";
+ }
+
+ // These tests don't work right with loggers other than plain, usually because
+ // they internally supply arguments to themselves.
+ if (logger.name != "plain") {
+ if (subtest == "differentexec") {
+ continue;
+ }
+ if (subtest == "qexecstringlist") {
+ continue;
+ }
+ if (subtest == "benchliboptions") {
+ continue;
+ }
+ if (subtest == "waitwithoutgui") {
+ continue;
+ }
+ // `crashes' will not output valid XML on platforms without a crash handler
+ if (subtest == "crashes") {
+ continue;
+ }
+ // this test prints out some floats in the testlog and the formatting is
+ // platform-specific and hard to predict.
+ if (subtest == "subtest") {
+ continue;
+ }
+ }
+ QTest::newRow(qPrintable(QString("%1%2").arg(subtest).arg(rowSuffix)))
+ << subtest
+ << logger.testdata_suffix
+ << arguments
+ ;
+ }
+ }
}
-void tst_Selftests::doRunSubTest(QString &subdir, QStringList &arguments )
+void tst_Selftests::doRunSubTest(QString const& subdir, QString const& logger, QStringList const& arguments )
{
+ // For the plain text logger, we'll read straight from standard output.
+ // For all other loggers (XML), we'll tell testlib to redirect to a file.
+ // The reason is that tests are allowed to print to standard output, and
+ // that means the test log is no longer guaranteed to be valid XML.
+ QStringList extraArguments;
+ QString logfile;
+ if (logger != "txt") {
+ logfile = "test_output";
+ extraArguments << "-o" << logfile;
+ }
+
QProcess proc;
proc.setEnvironment(QStringList(""));
- proc.start(subdir + "/" + subdir, arguments);
+ proc.start(subdir + "/" + subdir, QStringList() << arguments << extraArguments);
QVERIFY2(proc.waitForFinished(), qPrintable(proc.errorString()));
- const QByteArray out(proc.readAllStandardOutput());
+ QByteArray out;
+ if (logfile.isEmpty()) {
+ out = proc.readAllStandardOutput();
+ }
+ else {
+ QFile file(logfile);
+ if (file.open(QIODevice::ReadOnly))
+ out = file.readAll();
+ }
+
const QByteArray err(proc.readAllStandardError());
/* Some platforms decides to output a message for uncaught exceptions. For instance,
@@ -215,13 +341,13 @@ void tst_Selftests::doRunSubTest(QString &subdir, QStringList &arguments )
QVERIFY2(err.isEmpty(), err.constData());
QList<QByteArray> res = splitLines(out);
- QList<QByteArray> exp = expectedResult(subdir);
+ QList<QByteArray> exp = expectedResult(subdir, logger);
if (exp.count() == 0) {
QList<QList<QByteArray> > expArr;
int i = 1;
do {
- exp = expectedResult(subdir + QString("_%1").arg(i++));
+ exp = expectedResult(subdir + QString("_%1").arg(i++), logger);
if (exp.count())
expArr += exp;
} while(exp.count());
@@ -236,6 +362,28 @@ void tst_Selftests::doRunSubTest(QString &subdir, QStringList &arguments )
QCOMPARE(res.count(), exp.count());
}
+ if (logger == "xunitxml" || logger == "xml" || logger == "lightxml") {
+ QByteArray xml(out);
+ // lightxml intentionally skips the root element, which technically makes it
+ // not valid XML.
+ // We'll add that ourselves for the purpose of validation.
+ if (logger == "lightxml") {
+ xml.prepend("<root>");
+ xml.append("</root>");
+ }
+
+ QXmlStreamReader reader(xml);
+
+ while(!reader.atEnd())
+ reader.readNext();
+
+ QVERIFY2(!reader.error(), qPrintable(QString("line %1, col %2: %3")
+ .arg(reader.lineNumber())
+ .arg(reader.columnNumber())
+ .arg(reader.errorString())
+ ));
+ }
+
bool benchmark = false;
for (int i = 0; i < res.count(); ++i) {
QByteArray line = res.at(i);
@@ -250,8 +398,13 @@ void tst_Selftests::doRunSubTest(QString &subdir, QStringList &arguments )
const QString output(QString::fromLatin1(line));
const QString expected(QString::fromLatin1(exp.at(i)).replace("<INSERT_QT_VERSION_HERE>", QT_VERSION_STR));
- if (line.contains("ASSERT") && output != expected)
- QEXPECT_FAIL("assert", "QTestLib prints out the absolute path.", Continue);
+ if (line.contains("ASSERT") && output != expected) {
+ QEXPECT_FAIL("assert", "QTestLib prints out the absolute path.", Continue);
+ QEXPECT_FAIL("assert xml", "QTestLib prints out the absolute path.", Continue);
+ QEXPECT_FAIL("assert xml flush","QTestLib prints out the absolute path.", Continue);
+ QEXPECT_FAIL("assert lightxml", "QTestLib prints out the absolute path.", Continue);
+ QEXPECT_FAIL("assert xunitxml", "QTestLib prints out the absolute path.", Continue);
+ }
/* On some platforms we compile without RTTI, and as a result we never throw an exception. */
if(expected.startsWith(QLatin1String("FAIL! : tst_Exception::throwException() Caught unhandled exce")) && expected != output)
@@ -292,131 +445,10 @@ void tst_Selftests::doRunSubTest(QString &subdir, QStringList &arguments )
void tst_Selftests::runSubTest()
{
QFETCH(QString, subdir);
+ QFETCH(QString, logger);
QFETCH(QStringList, arguments);
- doRunSubTest(subdir, arguments);
-}
-
-void tst_Selftests::initTestCase()
-{
-#if !defined(Q_OS_UNIX) || defined(Q_WS_MAC)
- m_checkXMLBlacklist.append("crashes"); // This test crashes (XML valid on Unix only)
-#endif
- m_checkXMLBlacklist.append("waitwithoutgui"); // This test is not a QTestLib test.
-
- /* Output from several tests is broken with the XML output method,
- * and it's quite heavy in the design. See task 155001. */
- m_checkXMLBlacklist.append("multiexec");
- m_checkXMLBlacklist.append("differentexec");
- m_checkXMLBlacklist.append("qexecstringlist");
- m_checkXMLBlacklist.append("benchliboptions");
-
- /* These tests use printf and therefore corrupt the testlog */
- m_checkXMLBlacklist.append("subtest");
- m_checkXMLBlacklist.append("globaldata");
- m_checkXMLBlacklist.append("warnings");
-
- m_checkXunitBlacklist = m_checkXMLBlacklist;
-}
-
-void tst_Selftests::checkXML() const
-{
- QFETCH(QString, subdir);
- QFETCH(QStringList, arguments);
-
- if(m_checkXMLBlacklist.contains(subdir))
- return;
-
- QStringList args;
- /* Test both old (-flush) and new XML logger implementation */
- for (int i = 0; i < 2; ++i) {
- bool flush = i;
- args = arguments;
- args.prepend("-xml");
- if (flush) args.prepend("-flush");
-
- QProcess proc;
- proc.setEnvironment(QStringList(""));
- proc.start(subdir + "/" + subdir, args);
- QVERIFY(proc.waitForFinished());
-
- QByteArray out(proc.readAllStandardOutput());
- QByteArray err(proc.readAllStandardError());
-
- /* Some platforms decides to output a message for uncaught exceptions. For instance,
- * this is what windows platforms says:
- * "This application has requested the Runtime to terminate it in an unusual way.
- * Please contact the application's support team for more information." */
- if(subdir != QLatin1String("exceptionthrow") && subdir != QLatin1String("fetchbogus"))
- QVERIFY2(err.isEmpty(), err.constData());
-
- QXmlStreamReader reader(out);
-
- while(!reader.atEnd())
- reader.readNext();
-
- QVERIFY2(!reader.error(), qPrintable(QString("(flush %0) line %1, col %2: %3")
- .arg(flush)
- .arg(reader.lineNumber())
- .arg(reader.columnNumber())
- .arg(reader.errorString())
- ));
- }
-}
-
-void tst_Selftests::checkXunitxml() const
-{
- QFETCH(QString, subdir);
- QFETCH(QStringList, arguments);
-
- if(m_checkXunitBlacklist.contains(subdir))
- return;
-
- arguments.prepend("-xunitxml");
- arguments.prepend("-flush");
-
- QProcess proc;
- proc.setEnvironment(QStringList(""));
- proc.start(subdir + "/" + subdir, arguments);
- QVERIFY(proc.waitForFinished());
-
- QByteArray out(proc.readAllStandardOutput());
- QByteArray err(proc.readAllStandardError());
-
-// qDebug()<<out;
-
- /* Some platforms decides to output a message for uncaught exceptions. For instance,
- * this is what windows platforms says:
- * "This application has requested the Runtime to terminate it in an unusual way.
- * Please contact the application's support team for more information." */
- if(subdir != QLatin1String("exceptionthrow") && subdir != QLatin1String("fetchbogus"))
- QVERIFY2(err.isEmpty(), err.constData());
-
- QXmlStreamReader reader(out);
-
- while(!reader.atEnd())
- reader.readNext();
-
- QVERIFY2(!reader.error(), qPrintable(QString("line %1, col %2: %3")
- .arg(reader.lineNumber())
- .arg(reader.columnNumber())
- .arg(reader.errorString())
- ));
-}
-
-void tst_Selftests::checkXunitxml_data()
-{
- checkXML_data();
-}
-
-void tst_Selftests::checkXML_data()
-{
- runSubTest_data();
- QTest::newRow("badxml 1") << "badxml" << QStringList();
- QTest::newRow("badxml 2") << "badxml" << (QStringList() << "-badstring" << "0");
- QTest::newRow("badxml 3") << "badxml" << (QStringList() << "-badstring" << "1");
- QTest::newRow("badxml 4") << "badxml" << (QStringList() << "-badstring" << "2");
- QTest::newRow("badxml 5") << "badxml" << (QStringList() << "-badstring" << "3");
+ doRunSubTest(subdir, logger, arguments);
}
/* Parse line into the BenchmarkResult it represents. */
@@ -516,6 +548,11 @@ BenchmarkResult BenchmarkResult::parse(QString const& line, QString* error)
return out;
}
+void tst_Selftests::cleanupTestCase()
+{
+ QFile::remove("test_output");
+}
+
QTEST_MAIN(tst_Selftests)
#include "tst_selftests.moc"