forked from qt-creator/qt-creator
Get rid of the Locker in TestResultModel...
...use signals and slots instead. Additionally re-use the existing item that is displaying the "Entering Test Function..." information. Change-Id: Ibedac01ced9e987d542aa4dc878588fbec84d585 Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
This commit is contained in:
committed by
Christian Stenger
parent
be4c06fdaf
commit
ba8979d066
@@ -51,6 +51,8 @@ static AutotestPlugin *m_instance = 0;
|
|||||||
AutotestPlugin::AutotestPlugin()
|
AutotestPlugin::AutotestPlugin()
|
||||||
: m_settings(new TestSettings)
|
: m_settings(new TestSettings)
|
||||||
{
|
{
|
||||||
|
// needed to be used in QueuedConnection connects
|
||||||
|
qRegisterMetaType<TestResult>();
|
||||||
// Create your members
|
// Create your members
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ class TestResult
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TestResult(const QString &className, const QString &testCase, const QString &dataTag = QString(),
|
TestResult(const QString &className = QString(), const QString &testCase = QString(),
|
||||||
|
const QString &dataTag = QString(),
|
||||||
ResultType result = UNKNOWN, const QString &description = QString());
|
ResultType result = UNKNOWN, const QString &description = QString());
|
||||||
|
|
||||||
QString className() const { return m_class; }
|
QString className() const { return m_class; }
|
||||||
@@ -57,6 +58,7 @@ public:
|
|||||||
QString fileName() const { return m_file; }
|
QString fileName() const { return m_file; }
|
||||||
int line() const { return m_line; }
|
int line() const { return m_line; }
|
||||||
|
|
||||||
|
void setDescription(const QString &description) { m_description = description; }
|
||||||
void setFileName(const QString &fileName) { m_file = fileName; }
|
void setFileName(const QString &fileName) { m_file = fileName; }
|
||||||
void setLine(int line) { m_line = line; }
|
void setLine(int line) { m_line = line; }
|
||||||
|
|
||||||
@@ -87,6 +89,7 @@ bool operator==(const TestResult &t1, const TestResult &t2);
|
|||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Autotest::Internal::TestResult)
|
||||||
Q_DECLARE_METATYPE(Autotest::Internal::ResultType)
|
Q_DECLARE_METATYPE(Autotest::Internal::ResultType)
|
||||||
|
|
||||||
#endif // TESTRESULT_H
|
#endif // TESTRESULT_H
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ TestResultModel::TestResultModel(QObject *parent) :
|
|||||||
|
|
||||||
TestResultModel::~TestResultModel()
|
TestResultModel::~TestResultModel()
|
||||||
{
|
{
|
||||||
QWriteLocker lock(&m_rwLock);
|
|
||||||
m_testResults.clear();
|
m_testResults.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +53,6 @@ QModelIndex TestResultModel::parent(const QModelIndex &) const
|
|||||||
|
|
||||||
int TestResultModel::rowCount(const QModelIndex &parent) const
|
int TestResultModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
QReadLocker lock(&m_rwLock);
|
|
||||||
return parent.isValid() ? 0 : m_testResults.size();
|
return parent.isValid() ? 0 : m_testResults.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +83,6 @@ static QIcon testResultIcon(ResultType result) {
|
|||||||
|
|
||||||
QVariant TestResultModel::data(const QModelIndex &index, int role) const
|
QVariant TestResultModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
QReadLocker lock(&m_rwLock);
|
|
||||||
if (!index.isValid() || index.row() >= m_testResults.count() || index.column() != 0)
|
if (!index.isValid() || index.row() >= m_testResults.count() || index.column() != 0)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
@@ -118,23 +115,17 @@ void TestResultModel::addTestResult(const TestResult &testResult)
|
|||||||
const bool isCurrentTestMssg = testResult.result() == ResultType::MESSAGE_CURRENT_TEST;
|
const bool isCurrentTestMssg = testResult.result() == ResultType::MESSAGE_CURRENT_TEST;
|
||||||
const bool hasCurrentTestMssg = m_availableResultTypes.contains(ResultType::MESSAGE_CURRENT_TEST);
|
const bool hasCurrentTestMssg = m_availableResultTypes.contains(ResultType::MESSAGE_CURRENT_TEST);
|
||||||
|
|
||||||
QReadLocker rLock(&m_rwLock);
|
|
||||||
int position = m_testResults.size();
|
int position = m_testResults.size();
|
||||||
rLock.unlock();
|
|
||||||
|
|
||||||
if (hasCurrentTestMssg && isCurrentTestMssg) {
|
if (hasCurrentTestMssg && isCurrentTestMssg) {
|
||||||
beginRemoveRows(QModelIndex(), position, position);
|
m_testResults.last().setDescription(testResult.description());
|
||||||
QWriteLocker wLock(&m_rwLock);
|
const QModelIndex changed = index(m_testResults.size() - 1, 0, QModelIndex());
|
||||||
m_testResults.replace(position - 1, testResult);
|
emit dataChanged(changed, changed);
|
||||||
wLock.unlock();
|
|
||||||
endRemoveRows();
|
|
||||||
} else {
|
} else {
|
||||||
if (!isCurrentTestMssg && position) // decrement only if at least one other item
|
if (!isCurrentTestMssg && position) // decrement only if at least one other item
|
||||||
--position;
|
--position;
|
||||||
beginInsertRows(QModelIndex(), position, position);
|
beginInsertRows(QModelIndex(), position, position);
|
||||||
QWriteLocker wLock(&m_rwLock);
|
|
||||||
m_testResults.insert(position, testResult);
|
m_testResults.insert(position, testResult);
|
||||||
wLock.unlock();
|
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,13 +139,9 @@ void TestResultModel::addTestResult(const TestResult &testResult)
|
|||||||
|
|
||||||
void TestResultModel::removeCurrentTestMessage()
|
void TestResultModel::removeCurrentTestMessage()
|
||||||
{
|
{
|
||||||
QReadLocker rLock(&m_rwLock);
|
|
||||||
if (m_availableResultTypes.contains(ResultType::MESSAGE_CURRENT_TEST)) {
|
if (m_availableResultTypes.contains(ResultType::MESSAGE_CURRENT_TEST)) {
|
||||||
beginRemoveRows(QModelIndex(), m_testResults.size() - 1, m_testResults.size() - 1);
|
beginRemoveRows(QModelIndex(), m_testResults.size() - 1, m_testResults.size() - 1);
|
||||||
rLock.unlock();
|
|
||||||
QWriteLocker wLock(&m_rwLock);
|
|
||||||
m_testResults.removeLast();
|
m_testResults.removeLast();
|
||||||
wLock.unlock();
|
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
m_availableResultTypes.remove(ResultType::MESSAGE_CURRENT_TEST);
|
m_availableResultTypes.remove(ResultType::MESSAGE_CURRENT_TEST);
|
||||||
}
|
}
|
||||||
@@ -162,14 +149,10 @@ void TestResultModel::removeCurrentTestMessage()
|
|||||||
|
|
||||||
void TestResultModel::clearTestResults()
|
void TestResultModel::clearTestResults()
|
||||||
{
|
{
|
||||||
QReadLocker rLock(&m_rwLock);
|
|
||||||
if (m_testResults.size() == 0)
|
if (m_testResults.size() == 0)
|
||||||
return;
|
return;
|
||||||
beginRemoveRows(QModelIndex(), 0, m_testResults.size() - 1);
|
beginRemoveRows(QModelIndex(), 0, m_testResults.size() - 1);
|
||||||
rLock.unlock();
|
|
||||||
QWriteLocker wLock(&m_rwLock);
|
|
||||||
m_testResults.clear();
|
m_testResults.clear();
|
||||||
wLock.unlock();
|
|
||||||
m_testResultCount.clear();
|
m_testResultCount.clear();
|
||||||
m_lastMaxWidthIndex = 0;
|
m_lastMaxWidthIndex = 0;
|
||||||
m_maxWidthOfFileName = 0;
|
m_maxWidthOfFileName = 0;
|
||||||
@@ -182,15 +165,12 @@ TestResult TestResultModel::testResult(const QModelIndex &index) const
|
|||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return TestResult(QString(), QString());
|
return TestResult(QString(), QString());
|
||||||
QReadLocker lock(&m_rwLock);
|
|
||||||
return m_testResults.at(index.row());
|
return m_testResults.at(index.row());
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestResultModel::maxWidthOfFileName(const QFont &font)
|
int TestResultModel::maxWidthOfFileName(const QFont &font)
|
||||||
{
|
{
|
||||||
QReadLocker lock(&m_rwLock);
|
|
||||||
int count = m_testResults.size();
|
int count = m_testResults.size();
|
||||||
lock.unlock();
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (m_maxWidthOfFileName > 0 && font == m_measurementFont && m_lastMaxWidthIndex == count - 1)
|
if (m_maxWidthOfFileName > 0 && font == m_measurementFont && m_lastMaxWidthIndex == count - 1)
|
||||||
@@ -200,9 +180,7 @@ int TestResultModel::maxWidthOfFileName(const QFont &font)
|
|||||||
m_measurementFont = font;
|
m_measurementFont = font;
|
||||||
|
|
||||||
for (int i = m_lastMaxWidthIndex; i < count; ++i) {
|
for (int i = m_lastMaxWidthIndex; i < count; ++i) {
|
||||||
lock.relock();
|
|
||||||
QString filename = m_testResults.at(i).fileName();
|
QString filename = m_testResults.at(i).fileName();
|
||||||
lock.unlock();
|
|
||||||
const int pos = filename.lastIndexOf(QLatin1Char('/'));
|
const int pos = filename.lastIndexOf(QLatin1Char('/'));
|
||||||
if (pos != -1)
|
if (pos != -1)
|
||||||
filename = filename.mid(pos +1);
|
filename = filename.mid(pos +1);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QReadWriteLock>
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
@@ -67,7 +66,6 @@ private:
|
|||||||
int m_lastMaxWidthIndex;
|
int m_lastMaxWidthIndex;
|
||||||
QFont m_measurementFont;
|
QFont m_measurementFont;
|
||||||
QSet<ResultType> m_availableResultTypes;
|
QSet<ResultType> m_availableResultTypes;
|
||||||
mutable QReadWriteLock m_rwLock;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestResultFilterModel : public QSortFilterProxyModel
|
class TestResultFilterModel : public QSortFilterProxyModel
|
||||||
|
|||||||
@@ -52,8 +52,6 @@ public:
|
|||||||
virtual ~TestResultsPane();
|
virtual ~TestResultsPane();
|
||||||
static TestResultsPane *instance();
|
static TestResultsPane *instance();
|
||||||
|
|
||||||
void addTestResult(const TestResult &result);
|
|
||||||
|
|
||||||
// IOutputPane interface
|
// IOutputPane interface
|
||||||
QWidget *outputWidget(QWidget *parent);
|
QWidget *outputWidget(QWidget *parent);
|
||||||
QList<QWidget *> toolBarWidgets() const;
|
QList<QWidget *> toolBarWidgets() const;
|
||||||
@@ -73,6 +71,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void addTestResult(const TestResult &result);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onItemActivated(const QModelIndex &index);
|
void onItemActivated(const QModelIndex &index);
|
||||||
|
|||||||
@@ -192,6 +192,11 @@ static bool xmlExtractBenchmarkInformation(const QString &code, const QString &t
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emitTestResultCreated(const TestResult &testResult)
|
||||||
|
{
|
||||||
|
emit m_instance->testResultCreated(testResult);
|
||||||
|
}
|
||||||
|
|
||||||
/****************** XML line parser helper end ******************/
|
/****************** XML line parser helper end ******************/
|
||||||
|
|
||||||
void processOutput()
|
void processOutput()
|
||||||
@@ -228,8 +233,8 @@ void processOutput()
|
|||||||
result = ResultType::UNKNOWN;
|
result = ResultType::UNKNOWN;
|
||||||
lineNumber = 0;
|
lineNumber = 0;
|
||||||
readingDescription = false;
|
readingDescription = false;
|
||||||
TestResultsPane::instance()->addTestResult(
|
emitTestResultCreated(
|
||||||
TestResult(className, testCase, QString(), ResultType::MESSAGE_CURRENT_TEST,
|
TestResult(QString(), QString(), QString(), ResultType::MESSAGE_CURRENT_TEST,
|
||||||
QObject::tr("Entering Test Function %1::%2")
|
QObject::tr("Entering Test Function %1::%2")
|
||||||
.arg(className).arg(testCase)));
|
.arg(className).arg(testCase)));
|
||||||
continue;
|
continue;
|
||||||
@@ -253,13 +258,13 @@ void processOutput()
|
|||||||
file = QFileInfo(m_runner->workingDirectory(), file).canonicalFilePath();
|
file = QFileInfo(m_runner->workingDirectory(), file).canonicalFilePath();
|
||||||
testResult.setFileName(file);
|
testResult.setFileName(file);
|
||||||
testResult.setLine(lineNumber);
|
testResult.setLine(lineNumber);
|
||||||
TestResultsPane::instance()->addTestResult(testResult);
|
emitTestResultCreated(testResult);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (xmlExtractBenchmarkInformation(line, QLatin1String("<BenchmarkResult"), bmDescription)) {
|
if (xmlExtractBenchmarkInformation(line, QLatin1String("<BenchmarkResult"), bmDescription)) {
|
||||||
TestResult testResult(className, testCase, dataTag, ResultType::BENCHMARK, bmDescription);
|
TestResult testResult(className, testCase, dataTag, ResultType::BENCHMARK, bmDescription);
|
||||||
TestResultsPane::instance()->addTestResult(testResult);
|
emitTestResultCreated(testResult);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line == QLatin1String("</Message>") || line == QLatin1String("</Incident>")) {
|
if (line == QLatin1String("</Message>") || line == QLatin1String("</Incident>")) {
|
||||||
@@ -268,17 +273,17 @@ void processOutput()
|
|||||||
file = QFileInfo(m_runner->workingDirectory(), file).canonicalFilePath();
|
file = QFileInfo(m_runner->workingDirectory(), file).canonicalFilePath();
|
||||||
testResult.setFileName(file);
|
testResult.setFileName(file);
|
||||||
testResult.setLine(lineNumber);
|
testResult.setLine(lineNumber);
|
||||||
TestResultsPane::instance()->addTestResult(testResult);
|
emitTestResultCreated(testResult);
|
||||||
description = QString();
|
description = QString();
|
||||||
} else if (line == QLatin1String("</TestFunction>") && !duration.isEmpty()) {
|
} else if (line == QLatin1String("</TestFunction>") && !duration.isEmpty()) {
|
||||||
TestResult testResult(className, testCase, QString(), ResultType::MESSAGE_INTERNAL,
|
TestResult testResult(className, testCase, QString(), ResultType::MESSAGE_INTERNAL,
|
||||||
QObject::tr("execution took %1ms").arg(duration));
|
QObject::tr("execution took %1ms").arg(duration));
|
||||||
TestResultsPane::instance()->addTestResult(testResult);
|
emitTestResultCreated(testResult);
|
||||||
m_currentFuture->setProgressValue(m_currentFuture->progressValue() + 1);
|
m_currentFuture->setProgressValue(m_currentFuture->progressValue() + 1);
|
||||||
} else if (line == QLatin1String("</TestCase>") && !duration.isEmpty()) {
|
} else if (line == QLatin1String("</TestCase>") && !duration.isEmpty()) {
|
||||||
TestResult testResult(className, QString(), QString(), ResultType::MESSAGE_INTERNAL,
|
TestResult testResult(className, QString(), QString(), ResultType::MESSAGE_INTERNAL,
|
||||||
QObject::tr("Test execution took %1ms").arg(duration));
|
QObject::tr("Test execution took %1ms").arg(duration));
|
||||||
TestResultsPane::instance()->addTestResult(testResult);
|
emitTestResultCreated(testResult);
|
||||||
} else if (readingDescription) {
|
} else if (readingDescription) {
|
||||||
if (line.endsWith(QLatin1String("]]></Description>"))) {
|
if (line.endsWith(QLatin1String("]]></Description>"))) {
|
||||||
description.append(QLatin1Char('\n'));
|
description.append(QLatin1Char('\n'));
|
||||||
@@ -289,10 +294,10 @@ void processOutput()
|
|||||||
description.append(line);
|
description.append(line);
|
||||||
}
|
}
|
||||||
} else if (xmlStartsWith(line, QLatin1String("<QtVersion>"), qtVersion)) {
|
} else if (xmlStartsWith(line, QLatin1String("<QtVersion>"), qtVersion)) {
|
||||||
TestResultsPane::instance()->addTestResult(FaultyTestResult(ResultType::MESSAGE_INTERNAL,
|
emitTestResultCreated(FaultyTestResult(ResultType::MESSAGE_INTERNAL,
|
||||||
QObject::tr("Qt Version: %1").arg(qtVersion)));
|
QObject::tr("Qt Version: %1").arg(qtVersion)));
|
||||||
} else if (xmlStartsWith(line, QLatin1String("<QTestVersion>"), qtestVersion)) {
|
} else if (xmlStartsWith(line, QLatin1String("<QTestVersion>"), qtestVersion)) {
|
||||||
TestResultsPane::instance()->addTestResult(FaultyTestResult(ResultType::MESSAGE_INTERNAL,
|
emitTestResultCreated(FaultyTestResult(ResultType::MESSAGE_INTERNAL,
|
||||||
QObject::tr("QTest Version: %1").arg(qtestVersion)));
|
QObject::tr("QTest Version: %1").arg(qtestVersion)));
|
||||||
} else {
|
} else {
|
||||||
// qDebug() << "Unhandled line:" << line; // TODO remove
|
// qDebug() << "Unhandled line:" << line; // TODO remove
|
||||||
@@ -344,7 +349,7 @@ bool performExec(const QString &cmd, const QStringList &args, const QString &wor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (runCmd.isEmpty()) {
|
if (runCmd.isEmpty()) {
|
||||||
TestResultsPane::instance()->addTestResult(FaultyTestResult(ResultType::MESSAGE_FATAL,
|
emitTestResultCreated(FaultyTestResult(ResultType::MESSAGE_FATAL,
|
||||||
QObject::tr("*** Could not find command '%1' ***").arg(cmd)));
|
QObject::tr("*** Could not find command '%1' ***").arg(cmd)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -366,7 +371,7 @@ bool performExec(const QString &cmd, const QStringList &args, const QString &wor
|
|||||||
if (m_currentFuture->isCanceled()) {
|
if (m_currentFuture->isCanceled()) {
|
||||||
m_runner->kill();
|
m_runner->kill();
|
||||||
m_runner->waitForFinished();
|
m_runner->waitForFinished();
|
||||||
TestResultsPane::instance()->addTestResult(FaultyTestResult(ResultType::MESSAGE_FATAL,
|
emitTestResultCreated(FaultyTestResult(ResultType::MESSAGE_FATAL,
|
||||||
QObject::tr("*** Test Run canceled by user ***")));
|
QObject::tr("*** Test Run canceled by user ***")));
|
||||||
}
|
}
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
@@ -378,7 +383,7 @@ bool performExec(const QString &cmd, const QStringList &args, const QString &wor
|
|||||||
if (m_runner->state() != QProcess::NotRunning) {
|
if (m_runner->state() != QProcess::NotRunning) {
|
||||||
m_runner->kill();
|
m_runner->kill();
|
||||||
m_runner->waitForFinished();
|
m_runner->waitForFinished();
|
||||||
TestResultsPane::instance()->addTestResult(FaultyTestResult(ResultType::MESSAGE_FATAL,
|
emitTestResultCreated(FaultyTestResult(ResultType::MESSAGE_FATAL,
|
||||||
QObject::tr("*** Test Case canceled due to timeout ***\nMaybe raise the timeout?")));
|
QObject::tr("*** Test Case canceled due to timeout ***\nMaybe raise the timeout?")));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -484,6 +489,10 @@ void TestRunner::runTests()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_executingTests = true;
|
m_executingTests = true;
|
||||||
|
connect(this, &TestRunner::testResultCreated,
|
||||||
|
TestResultsPane::instance(), &TestResultsPane::addTestResult,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
emit testRunStarted();
|
emit testRunStarted();
|
||||||
QFuture<void> future = QtConcurrent::run(&performTestRun , m_selectedTests);
|
QFuture<void> future = QtConcurrent::run(&performTestRun , m_selectedTests);
|
||||||
Core::FutureProgress *progress = Core::ProgressManager::addTask(future, tr("Running Tests"),
|
Core::FutureProgress *progress = Core::ProgressManager::addTask(future, tr("Running Tests"),
|
||||||
@@ -516,6 +525,9 @@ void TestRunner::buildFinished(bool success)
|
|||||||
|
|
||||||
void TestRunner::onFinished()
|
void TestRunner::onFinished()
|
||||||
{
|
{
|
||||||
|
disconnect(this, &TestRunner::testResultCreated,
|
||||||
|
TestResultsPane::instance(), &TestResultsPane::addTestResult);
|
||||||
|
|
||||||
m_executingTests = false;
|
m_executingTests = false;
|
||||||
emit testRunFinished();
|
emit testRunFinished();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void testRunStarted();
|
void testRunStarted();
|
||||||
void testRunFinished();
|
void testRunFinished();
|
||||||
|
void testResultCreated(const TestResult &testResult);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void runTests();
|
void runTests();
|
||||||
|
|||||||
Reference in New Issue
Block a user