diff options
author | Tim Jenssen <tim.jenssen@theqtcompany.com> | 2015-01-16 13:44:24 +0100 |
---|---|---|
committer | Tim Jenssen <tim.jenssen@theqtcompany.com> | 2015-01-21 09:25:51 +0200 |
commit | 295ad02f7e62b66dfcba73ac56b6c2f2c8ba6036 (patch) | |
tree | b0ef9a8e77ee8283e44d1f07240b99227c576c4a | |
parent | 2a78ffea8d9514b147167408269f0076c094fb70 (diff) | |
download | qt-creator-295ad02f7e62b66dfcba73ac56b6c2f2c8ba6036.tar.gz |
introduce testxmloutputreader
Change-Id: I5a77e8fd629343bc059a03e6c27f45103b96101a
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
-rw-r--r-- | plugins/autotest/autotest.pro | 6 | ||||
-rw-r--r-- | plugins/autotest/testrunner.cpp | 310 | ||||
-rw-r--r-- | plugins/autotest/testxmloutputreader.cpp | 263 | ||||
-rw-r--r-- | plugins/autotest/testxmloutputreader.h | 56 |
4 files changed, 366 insertions, 269 deletions
diff --git a/plugins/autotest/autotest.pro b/plugins/autotest/autotest.pro index 0366ffae46..ecc8934575 100644 --- a/plugins/autotest/autotest.pro +++ b/plugins/autotest/autotest.pro @@ -25,7 +25,8 @@ SOURCES += \ testtreeitemdelegate.cpp \ testsettings.cpp \ testsettingspage.cpp \ - testnavigationwidget.cpp + testnavigationwidget.cpp \ + testxmloutputreader.cpp HEADERS += \ testtreeview.h \ @@ -46,7 +47,8 @@ HEADERS += \ testtreeitemdelegate.h \ testsettings.h \ testsettingspage.h \ - testnavigationwidget.h + testnavigationwidget.h \ + testxmloutputreader.h RESOURCES += \ autotest.qrc diff --git a/plugins/autotest/testrunner.cpp b/plugins/autotest/testrunner.cpp index ec142c9ec0..df9ad92b73 100644 --- a/plugins/autotest/testrunner.cpp +++ b/plugins/autotest/testrunner.cpp @@ -15,12 +15,13 @@ ** contact form at http://qt.digia.com ** ****************************************************************************/ +#include "testrunner.h" #include "autotestconstants.h" #include "autotestplugin.h" #include "testresultspane.h" -#include "testrunner.h" #include "testsettings.h" +#include "testxmloutputreader.h" #include <QDebug> // REMOVE @@ -42,266 +43,12 @@ namespace Autotest { namespace Internal { static TestRunner *m_instance = 0; -static QFutureInterface<void> *m_currentFuture = 0; - -TestRunner *TestRunner::instance() -{ - if (!m_instance) - m_instance = new TestRunner; - return m_instance; -} - -TestRunner::TestRunner(QObject *parent) : - QObject(parent), - m_building(false), - m_executingTests(false) -{ -} - -TestRunner::~TestRunner() -{ - qDeleteAll(m_selectedTests); - m_selectedTests.clear(); - m_instance = 0; -} - -void TestRunner::setSelectedTests(const QList<TestConfiguration *> &selected) -{ - qDeleteAll(m_selectedTests); - m_selectedTests.clear(); - m_selectedTests = selected; -} - -/******************** XML line parser helper ********************/ - -static bool xmlStartsWith(const QString &code, const QString &start, QString &result) -{ - if (code.startsWith(start)) { - result = code.mid(start.length()); - result = result.left(result.indexOf(QLatin1Char('"'))); - result = result.left(result.indexOf(QLatin1String("</"))); - return !result.isEmpty(); - } - return false; -} - -static bool xmlCData(const QString &code, const QString &start, QString &result) -{ - if (code.startsWith(start)) { - int index = code.indexOf(QLatin1String("<![CDATA[")) + 9; - result = code.mid(index, code.indexOf(QLatin1String("]]>"), index) - index); - return !result.isEmpty(); - } - return false; -} - -static bool xmlExtractTypeFileLine(const QString &code, const QString &tagStart, - Result::Type &result, QString &file, int &line) -{ - if (code.startsWith(tagStart)) { - int start = code.indexOf(QLatin1String(" type=\"")) + 7; - result = TestResult::resultFromString( - code.mid(start, code.indexOf(QLatin1Char('"'), start) - start)); - start = code.indexOf(QLatin1String(" file=\"")) + 7; - file = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start); - start = code.indexOf(QLatin1String(" line=\"")) + 7; - line = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start).toInt(); - return true; - } - return false; -} - -// adapted from qplaintestlogger.cpp -static QString formatResult(double value) -{ - if (value < 0 || value == NAN) - return QLatin1String("NAN"); - if (value == 0) - return QLatin1String("0"); - - int significantDigits = 0; - qreal divisor = 1; - - while (value / divisor >= 1) { - divisor *= 10; - ++significantDigits; - } - - QString beforeDecimalPoint = QString::number(value, 'f', 0); - QString afterDecimalPoint = QString::number(value, 'f', 20); - afterDecimalPoint.remove(0, beforeDecimalPoint.count() + 1); - - const int beforeUse = qMin(beforeDecimalPoint.count(), significantDigits); - const int beforeRemove = beforeDecimalPoint.count() - beforeUse; - - beforeDecimalPoint.chop(beforeRemove); - for (int i = 0; i < beforeRemove; ++i) - beforeDecimalPoint.append(QLatin1Char('0')); - - int afterUse = significantDigits - beforeUse; - if (beforeDecimalPoint == QLatin1String("0") && !afterDecimalPoint.isEmpty()) { - ++afterUse; - int i = 0; - while (i < afterDecimalPoint.count() && afterDecimalPoint.at(i) == QLatin1Char('0')) - ++i; - afterUse += i; - } - - const int afterRemove = afterDecimalPoint.count() - afterUse; - afterDecimalPoint.chop(afterRemove); - - QString result = beforeDecimalPoint; - if (afterUse > 0) - result.append(QLatin1Char('.')); - result += afterDecimalPoint; - - return result; -} - -static bool xmlExtractBenchmarkInformation(const QString &code, const QString &tagStart, - QString &description) -{ - if (code.startsWith(tagStart)) { - int start = code.indexOf(QLatin1String(" metric=\"")) + 9; - const QString metric = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start); - start = code.indexOf(QLatin1String(" value=\"")) + 8; - const double value = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start).toDouble(); - start = code.indexOf(QLatin1String(" iterations=\"")) + 13; - const int iterations = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start).toInt(); - QString metricsText; - if (metric == QLatin1String("WalltimeMilliseconds")) // default - metricsText = QLatin1String("msecs"); - else if (metric == QLatin1String("CPUTicks")) // -tickcounter - metricsText = QLatin1String("CPU ticks"); - else if (metric == QLatin1String("Events")) // -eventcounter - metricsText = QLatin1String("events"); - else if (metric == QLatin1String("InstructionReads")) // -callgrind - metricsText = QLatin1String("instruction reads"); - else if (metric == QLatin1String("CPUCycles")) // -perf - metricsText = QLatin1String("CPU cycles"); - description = QObject::tr("%1 %2 per iteration (total: %3, iterations: %4)") - .arg(formatResult(value)) - .arg(metricsText) - .arg(formatResult(value * (double)iterations)) - .arg(iterations); - return true; - } - return false; -} void emitTestResultCreated(const TestResult &testResult) { emit m_instance->testResultCreated(testResult); } -/****************** XML line parser helper end ******************/ - -void processOutput(QProcess *testRunner) -{ - if (!testRunner) - return; - static QString className; - static QString testCase; - static QString dataTag; - static Result::Type result = Result::UNKNOWN; - static QString description; - static QString file; - static int lineNumber = 0; - static QString duration; - static bool readingDescription = false; - static QString qtVersion; - static QString qtestVersion; - static QString benchmarkDescription; - - while (testRunner->canReadLine()) { - // TODO Qt5 uses UTF-8 - while Qt4 uses ISO-8859-1 - could this be a problem? - const QString line = QString::fromUtf8(testRunner->readLine()).trimmed(); - if (line.isEmpty() || line.startsWith(QLatin1String("<?xml version"))) { - className = QString(); - continue; - } - if (xmlStartsWith(line, QLatin1String("<TestCase name=\""), className)) - continue; - if (xmlStartsWith(line, QLatin1String("<TestFunction name=\""), testCase)) { - dataTag = QString(); - description = QString(); - duration = QString(); - file = QString(); - result = Result::UNKNOWN; - lineNumber = 0; - readingDescription = false; - emitTestResultCreated( - TestResult(QString(), QString(), QString(), Result::MESSAGE_CURRENT_TEST, - QObject::tr("Entering Test Function %1::%2") - .arg(className).arg(testCase))); - continue; - } - if (xmlStartsWith(line, QLatin1String("<Duration msecs=\""), duration)) { - continue; - } - if (xmlExtractTypeFileLine(line, QLatin1String("<Message"), result, file, lineNumber)) - continue; - if (xmlCData(line, QLatin1String("<DataTag>"), dataTag)) - continue; - if (xmlCData(line, QLatin1String("<Description>"), description)) { - if (!line.endsWith(QLatin1String("</Description>"))) - readingDescription = true; - continue; - } - if (xmlExtractTypeFileLine(line, QLatin1String("<Incident"), result, file, lineNumber)) { - if (line.endsWith(QLatin1String("/>"))) { - TestResult testResult(className, testCase, dataTag, result, description); - if (!file.isEmpty()) - file = QFileInfo(testRunner->workingDirectory(), file).canonicalFilePath(); - testResult.setFileName(file); - testResult.setLine(lineNumber); - emitTestResultCreated(testResult); - } - continue; - } - if (xmlExtractBenchmarkInformation(line, QLatin1String("<BenchmarkResult"), benchmarkDescription)) { - TestResult testResult(className, testCase, dataTag, Result::BENCHMARK, benchmarkDescription); - emitTestResultCreated(testResult); - continue; - } - if (line == QLatin1String("</Message>") || line == QLatin1String("</Incident>")) { - TestResult testResult(className, testCase, dataTag, result, description); - if (!file.isEmpty()) - file = QFileInfo(testRunner->workingDirectory(), file).canonicalFilePath(); - testResult.setFileName(file); - testResult.setLine(lineNumber); - emitTestResultCreated(testResult); - description = QString(); - } else if (line == QLatin1String("</TestFunction>") && !duration.isEmpty()) { - TestResult testResult(className, testCase, QString(), Result::MESSAGE_INTERNAL, - QObject::tr("execution took %1ms").arg(duration)); - emitTestResultCreated(testResult); - m_currentFuture->setProgressValue(m_currentFuture->progressValue() + 1); - } else if (line == QLatin1String("</TestCase>") && !duration.isEmpty()) { - TestResult testResult(className, QString(), QString(), Result::MESSAGE_INTERNAL, - QObject::tr("Test execution took %1ms").arg(duration)); - emitTestResultCreated(testResult); - } else if (readingDescription) { - if (line.endsWith(QLatin1String("]]></Description>"))) { - description.append(QLatin1Char('\n')); - description.append(line.left(line.indexOf(QLatin1String("]]></Description>")))); - readingDescription = false; - } else { - description.append(QLatin1Char('\n')); - description.append(line); - } - } else if (xmlStartsWith(line, QLatin1String("<QtVersion>"), qtVersion)) { - emitTestResultCreated(FaultyTestResult(Result::MESSAGE_INTERNAL, - QObject::tr("Qt Version: %1").arg(qtVersion))); - } else if (xmlStartsWith(line, QLatin1String("<QTestVersion>"), qtestVersion)) { - emitTestResultCreated(FaultyTestResult(Result::MESSAGE_INTERNAL, - QObject::tr("QTest Version: %1").arg(qtestVersion))); - } else { -// qDebug() << "Unhandled line:" << line; // TODO remove - } - } -} - static QString executableFilePath(const QString &command, const QProcessEnvironment &environment) { if (command.isEmpty()) @@ -331,29 +78,60 @@ static QString executableFilePath(const QString &command, const QProcessEnvironm return QString(); } -void performTestRun(QFutureInterface<void> &future, const QList<TestConfiguration *> selectedTests, const int timeout, const QString metricsOption, TestRunner* testRunner) +TestRunner *TestRunner::instance() +{ + if (!m_instance) + m_instance = new TestRunner; + return m_instance; +} + +TestRunner::TestRunner(QObject *parent) : + QObject(parent), + m_building(false), + m_executingTests(false) +{ +} + +TestRunner::~TestRunner() +{ + qDeleteAll(m_selectedTests); + m_selectedTests.clear(); + m_instance = 0; +} + +void TestRunner::setSelectedTests(const QList<TestConfiguration *> &selected) +{ + qDeleteAll(m_selectedTests); + m_selectedTests.clear(); + m_selectedTests = selected; +} + +void performTestRun(QFutureInterface<void> &futureInterface, const QList<TestConfiguration *> selectedTests, const int timeout, const QString metricsOption, TestRunner* testRunner) { int testCaseCount = 0; foreach (const TestConfiguration *config, selectedTests) testCaseCount += config->testCaseCount(); - m_currentFuture = &future; QProcess testProcess; testProcess.setReadChannelMode(QProcess::MergedChannels); testProcess.setReadChannel(QProcess::StandardOutput); QObject::connect(testRunner, &TestRunner::requestStopTestRun, &testProcess, [&] () { - future.cancel(); // this kills the process if that is still in the running loop + futureInterface.cancel(); // this kills the process if that is still in the running loop }); - QObject::connect(&testProcess, &QProcess::readyReadStandardOutput, [&] () { - processOutput(&testProcess); + TestXmlOutputReader xmlReader(&testProcess); + QObject::connect(&xmlReader, &TestXmlOutputReader::increaseProgress, [&] () { + futureInterface.setProgressValue(futureInterface.progressValue() + 1); }); + QObject::connect(&xmlReader, &TestXmlOutputReader::testResultCreated, &emitTestResultCreated); + + QObject::connect(&testProcess, &QProcess::readyRead, &xmlReader, &TestXmlOutputReader::processOutput); - m_currentFuture->setProgressRange(0, testCaseCount); - m_currentFuture->setProgressValue(0); + futureInterface.setProgressRange(0, testCaseCount); + futureInterface.setProgressValue(0); foreach (const TestConfiguration *testConfiguration, selectedTests) { - if (m_currentFuture->isCanceled()) + if (futureInterface.isCanceled()) break; QProcessEnvironment environment = testConfiguration->environment().toProcessEnvironment(); @@ -381,7 +159,7 @@ void performTestRun(QFutureInterface<void> &future, const QList<TestConfiguratio executionTimer.start(); if (ok) { while (testProcess.state() == QProcess::Running && executionTimer.elapsed() < timeout) { - if (m_currentFuture->isCanceled()) { + if (futureInterface.isCanceled()) { testProcess.kill(); testProcess.waitForFinished(); emitTestResultCreated(FaultyTestResult(Result::MESSAGE_FATAL, @@ -400,9 +178,7 @@ void performTestRun(QFutureInterface<void> &future, const QList<TestConfiguratio } } } - m_currentFuture->setProgressValue(testCaseCount); - - m_currentFuture = 0; + futureInterface.setProgressValue(testCaseCount); } void TestRunner::runTests() diff --git a/plugins/autotest/testxmloutputreader.cpp b/plugins/autotest/testxmloutputreader.cpp new file mode 100644 index 0000000000..10b6ed02b9 --- /dev/null +++ b/plugins/autotest/testxmloutputreader.cpp @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Creator Enterprise Auto Test Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#include "testxmloutputreader.h" +#include "testresult.h" + +#include <QXmlStreamReader> +#include <QProcess> +#include <QFileInfo> +#include <QDir> + +namespace Autotest { +namespace Internal { + +static bool xmlStartsWith(const QString &code, const QString &start, QString &result) +{ + if (code.startsWith(start)) { + result = code.mid(start.length()); + result = result.left(result.indexOf(QLatin1Char('"'))); + result = result.left(result.indexOf(QLatin1String("</"))); + return !result.isEmpty(); + } + return false; +} + +static bool xmlCData(const QString &code, const QString &start, QString &result) +{ + if (code.startsWith(start)) { + int index = code.indexOf(QLatin1String("<![CDATA[")) + 9; + result = code.mid(index, code.indexOf(QLatin1String("]]>"), index) - index); + return !result.isEmpty(); + } + return false; +} + +static bool xmlExtractTypeFileLine(const QString &code, const QString &tagStart, + Result::Type &result, QString &file, int &line) +{ + if (code.startsWith(tagStart)) { + int start = code.indexOf(QLatin1String(" type=\"")) + 7; + result = TestResult::resultFromString( + code.mid(start, code.indexOf(QLatin1Char('"'), start) - start)); + start = code.indexOf(QLatin1String(" file=\"")) + 7; + file = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start); + start = code.indexOf(QLatin1String(" line=\"")) + 7; + line = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start).toInt(); + return true; + } + return false; +} + + +// adapted from qplaintestlogger.cpp +static QString formatResult(double value) +{ + //NAN is not supported with visual studio 2010 +// if (value < 0 || value == NAN) +// return QLatin1String("NAN"); + if (value == 0) + return QLatin1String("0"); + + int significantDigits = 0; + qreal divisor = 1; + + while (value / divisor >= 1) { + divisor *= 10; + ++significantDigits; + } + + QString beforeDecimalPoint = QString::number(value, 'f', 0); + QString afterDecimalPoint = QString::number(value, 'f', 20); + afterDecimalPoint.remove(0, beforeDecimalPoint.count() + 1); + + const int beforeUse = qMin(beforeDecimalPoint.count(), significantDigits); + const int beforeRemove = beforeDecimalPoint.count() - beforeUse; + + beforeDecimalPoint.chop(beforeRemove); + for (int i = 0; i < beforeRemove; ++i) + beforeDecimalPoint.append(QLatin1Char('0')); + + int afterUse = significantDigits - beforeUse; + if (beforeDecimalPoint == QLatin1String("0") && !afterDecimalPoint.isEmpty()) { + ++afterUse; + int i = 0; + while (i < afterDecimalPoint.count() && afterDecimalPoint.at(i) == QLatin1Char('0')) + ++i; + afterUse += i; + } + + const int afterRemove = afterDecimalPoint.count() - afterUse; + afterDecimalPoint.chop(afterRemove); + + QString result = beforeDecimalPoint; + if (afterUse > 0) + result.append(QLatin1Char('.')); + result += afterDecimalPoint; + + return result; +} + +static bool xmlExtractBenchmarkInformation(const QString &code, const QString &tagStart, + QString &description) +{ + if (code.startsWith(tagStart)) { + int start = code.indexOf(QLatin1String(" metric=\"")) + 9; + const QString metric = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start); + start = code.indexOf(QLatin1String(" value=\"")) + 8; + const double value = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start).toDouble(); + start = code.indexOf(QLatin1String(" iterations=\"")) + 13; + const int iterations = code.mid(start, code.indexOf(QLatin1Char('"'), start) - start).toInt(); + QString metricsText; + if (metric == QLatin1String("WalltimeMilliseconds")) // default + metricsText = QLatin1String("msecs"); + else if (metric == QLatin1String("CPUTicks")) // -tickcounter + metricsText = QLatin1String("CPU ticks"); + else if (metric == QLatin1String("Events")) // -eventcounter + metricsText = QLatin1String("events"); + else if (metric == QLatin1String("InstructionReads")) // -callgrind + metricsText = QLatin1String("instruction reads"); + else if (metric == QLatin1String("CPUCycles")) // -perf + metricsText = QLatin1String("CPU cycles"); + description = QObject::tr("%1 %2 per iteration (total: %3, iterations: %4)") + .arg(formatResult(value)) + .arg(metricsText) + .arg(formatResult(value * (double)iterations)) + .arg(iterations); + return true; + } + return false; +} + +TestXmlOutputReader::TestXmlOutputReader(QProcess *testApplication) + :m_testApplication(testApplication) +{ + connect(m_testApplication, &QProcess::readyReadStandardOutput, + this, &TestXmlOutputReader::processOutput); +} + +TestXmlOutputReader::~TestXmlOutputReader() +{ +} + +void TestXmlOutputReader::processOutput() +{ + if (!m_testApplication || m_testApplication->state() != QProcess::Running) + return; + static QString className; + static QString testCase; + static QString dataTag; + static Result::Type result = Result::UNKNOWN; + static QString description; + static QString file; + static int lineNumber = 0; + static QString duration; + static bool readingDescription = false; + static QString qtVersion; + static QString qtestVersion; + static QString benchmarkDescription; + + while (m_testApplication->canReadLine()) { + // TODO Qt5 uses UTF-8 - while Qt4 uses ISO-8859-1 - could this be a problem? + const QString line = QString::fromUtf8(m_testApplication->readLine()).trimmed(); + if (line.isEmpty() || line.startsWith(QLatin1String("<?xml version"))) { + className = QString(); + continue; + } + if (xmlStartsWith(line, QLatin1String("<TestCase name=\""), className)) + continue; + if (xmlStartsWith(line, QLatin1String("<TestFunction name=\""), testCase)) { + dataTag = QString(); + description = QString(); + duration = QString(); + file = QString(); + result = Result::UNKNOWN; + lineNumber = 0; + readingDescription = false; + testResultCreated(TestResult(QString(), QString(), QString(), Result::MESSAGE_CURRENT_TEST, + QObject::tr("Entering Test Function %1::%2").arg(className).arg(testCase))); + continue; + } + if (xmlStartsWith(line, QLatin1String("<Duration msecs=\""), duration)) { + continue; + } + if (xmlExtractTypeFileLine(line, QLatin1String("<Message"), result, file, lineNumber)) + continue; + if (xmlCData(line, QLatin1String("<DataTag>"), dataTag)) + continue; + if (xmlCData(line, QLatin1String("<Description>"), description)) { + if (!line.endsWith(QLatin1String("</Description>"))) + readingDescription = true; + continue; + } + if (xmlExtractTypeFileLine(line, QLatin1String("<Incident"), result, file, lineNumber)) { + if (line.endsWith(QLatin1String("/>"))) { + TestResult testResult(className, testCase, dataTag, result, description); + if (!file.isEmpty()) + file = QFileInfo(m_testApplication->workingDirectory(), file).canonicalFilePath(); + testResult.setFileName(file); + testResult.setLine(lineNumber); + testResultCreated(testResult); + } + continue; + } + if (xmlExtractBenchmarkInformation(line, QLatin1String("<BenchmarkResult"), benchmarkDescription)) { + TestResult testResult(className, testCase, dataTag, Result::BENCHMARK, benchmarkDescription); + testResultCreated(testResult); + continue; + } + if (line == QLatin1String("</Message>") || line == QLatin1String("</Incident>")) { + TestResult testResult(className, testCase, dataTag, result, description); + if (!file.isEmpty()) + file = QFileInfo(m_testApplication->workingDirectory(), file).canonicalFilePath(); + testResult.setFileName(file); + testResult.setLine(lineNumber); + testResultCreated(testResult); + description = QString(); + } else if (line == QLatin1String("</TestFunction>") && !duration.isEmpty()) { + TestResult testResult(className, testCase, QString(), Result::MESSAGE_INTERNAL, + QObject::tr("execution took %1ms").arg(duration)); + testResultCreated(testResult); + emit increaseProgress(); + } else if (line == QLatin1String("</TestCase>") && !duration.isEmpty()) { + TestResult testResult(className, QString(), QString(), Result::MESSAGE_INTERNAL, + QObject::tr("Test execution took %1ms").arg(duration)); + testResultCreated(testResult); + } else if (readingDescription) { + if (line.endsWith(QLatin1String("]]></Description>"))) { + description.append(QLatin1Char('\n')); + description.append(line.left(line.indexOf(QLatin1String("]]></Description>")))); + readingDescription = false; + } else { + description.append(QLatin1Char('\n')); + description.append(line); + } + } else if (xmlStartsWith(line, QLatin1String("<QtVersion>"), qtVersion)) { + testResultCreated(FaultyTestResult(Result::MESSAGE_INTERNAL, + QObject::tr("Qt Version: %1").arg(qtVersion))); + } else if (xmlStartsWith(line, QLatin1String("<QTestVersion>"), qtestVersion)) { + testResultCreated(FaultyTestResult(Result::MESSAGE_INTERNAL, + QObject::tr("QTest Version: %1").arg(qtestVersion))); + } else { +// qDebug() << "Unhandled line:" << line; // TODO remove + } + } +} + +} // namespace Internal +} // namespace Autotest diff --git a/plugins/autotest/testxmloutputreader.h b/plugins/autotest/testxmloutputreader.h new file mode 100644 index 0000000000..6d15a2b885 --- /dev/null +++ b/plugins/autotest/testxmloutputreader.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Creator Enterprise Auto Test Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com +** +****************************************************************************/ + +#ifndef TESTXMLOUTPUTREADER_H +#define TESTXMLOUTPUTREADER_H + +#include <testresult.h> + +#include <QObject> +#include <QString> + +QT_BEGIN_NAMESPACE +class QXmlStreamReader; +class QIODevice; +class QProcess; +QT_END_NAMESPACE + +namespace Autotest { +namespace Internal { + +class TestXmlOutputReader : public QObject +{ + Q_OBJECT + +public: + TestXmlOutputReader(QProcess *testApplication); + ~TestXmlOutputReader(); + +public slots: + void processOutput(); +signals: + void testResultCreated(const TestResult &testResult); + void increaseProgress(); +private: + QProcess *m_testApplication; +}; + +} // namespace Internal +} // namespace Autotest + +#endif // TESTXMLOUTPUTREADER_H |