diff --git a/plugins/autotest/autotest.pro b/plugins/autotest/autotest.pro index 6d2423bdd74..507d9303003 100644 --- a/plugins/autotest/autotest.pro +++ b/plugins/autotest/autotest.pro @@ -22,7 +22,9 @@ SOURCES += \ testresultspane.cpp \ testresultmodel.cpp \ testresultdelegate.cpp \ - testtreeitemdelegate.cpp + testtreeitemdelegate.cpp \ + testsettings.cpp \ + testsettingspage.cpp HEADERS += \ testtreeview.h \ @@ -40,8 +42,13 @@ HEADERS += \ testresultspane.h \ testresultmodel.h \ testresultdelegate.h \ - testtreeitemdelegate.h + testtreeitemdelegate.h \ + testsettings.h \ + testsettingspage.h RESOURCES += \ autotest.qrc +FORMS += \ + testsettingspage.ui + diff --git a/plugins/autotest/autotest.qrc b/plugins/autotest/autotest.qrc index 7b98beaab96..2770aff5fe2 100644 --- a/plugins/autotest/autotest.qrc +++ b/plugins/autotest/autotest.qrc @@ -1,5 +1,6 @@ + images/autotest.png images/class.png images/func.png images/expand.png diff --git a/plugins/autotest/autotestconstants.h b/plugins/autotest/autotestconstants.h index a4f6bdc7d9f..fc254e42283 100644 --- a/plugins/autotest/autotestconstants.h +++ b/plugins/autotest/autotestconstants.h @@ -24,12 +24,13 @@ namespace Autotest { namespace Constants { -const char ACTION_ID[] = "AutoTest.Action"; -const char MENU_ID[] = "AutoTest.Menu"; -const char AUTOTEST_ID[] = "AutoTest.ATP"; -const char AUTOTEST_CONTEXT[] = "Auto Tests"; -const char TASK_INDEX[] = "AutoTest.Task.Index"; -const char UNNAMED_QUICKTESTS[] = QT_TR_NOOP(""); +const char ACTION_ID[] = "AutoTest.Action"; +const char MENU_ID[] = "AutoTest.Menu"; +const char AUTOTEST_ID[] = "AutoTest.ATP"; +const char AUTOTEST_CONTEXT[] = "Auto Tests"; +const char TASK_INDEX[] = "AutoTest.Task.Index"; +const char UNNAMED_QUICKTESTS[] = QT_TR_NOOP(""); +const char AUTOTEST_SETTINGS_CATEGORY[] = "ZY.Tests"; } // namespace Autotest } // namespace Constants diff --git a/plugins/autotest/autotestplugin.cpp b/plugins/autotest/autotestplugin.cpp index 065b561f5ff..2f99db04ae2 100644 --- a/plugins/autotest/autotestplugin.cpp +++ b/plugins/autotest/autotestplugin.cpp @@ -19,6 +19,8 @@ #include "autotestplugin.h" #include "autotestconstants.h" #include "testrunner.h" +#include "testsettings.h" +#include "testsettingspage.h" #include "testtreeview.h" #include "testtreemodel.h" #include "testresultspane.h" @@ -43,9 +45,13 @@ using namespace Autotest::Internal; +static AutotestPlugin *m_instance = 0; + AutotestPlugin::AutotestPlugin() + : m_settings(new TestSettings) { // Create your members + m_instance = this; } AutotestPlugin::~AutotestPlugin() @@ -58,6 +64,11 @@ AutotestPlugin::~AutotestPlugin() delete runner; } +AutotestPlugin *AutotestPlugin::instance() +{ + return m_instance; +} + bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorString) { // Register objects in the plugin manager's object pool @@ -90,6 +101,10 @@ bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorStri menu->addAction(cmd); Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); + m_settings->fromSettings(Core::ICore::settings()); + TestSettingsPage *settingsPage = new TestSettingsPage(m_settings); + addAutoReleasedObject(settingsPage); + addAutoReleasedObject(new TestViewFactory); addAutoReleasedObject(TestResultsPane::instance()); diff --git a/plugins/autotest/autotestplugin.h b/plugins/autotest/autotestplugin.h index 6391f050feb..6d5365ddeea 100644 --- a/plugins/autotest/autotestplugin.h +++ b/plugins/autotest/autotestplugin.h @@ -26,6 +26,8 @@ namespace Autotest { namespace Internal { +struct TestSettings; + class AutotestPlugin : public ExtensionSystem::IPlugin { Q_OBJECT @@ -35,12 +37,19 @@ public: AutotestPlugin(); ~AutotestPlugin(); + static AutotestPlugin *instance(); + bool initialize(const QStringList &arguments, QString *errorString); void extensionsInitialized(); ShutdownFlag aboutToShutdown(); + QSharedPointer settings() const { return m_settings; } + private slots: void triggerAction(); + +private: + const QSharedPointer m_settings; }; } // namespace Internal diff --git a/plugins/autotest/images/autotest.png b/plugins/autotest/images/autotest.png new file mode 100644 index 00000000000..3f52e9bf08f Binary files /dev/null and b/plugins/autotest/images/autotest.png differ diff --git a/plugins/autotest/testresultspane.cpp b/plugins/autotest/testresultspane.cpp index 998e80f57fe..cb28412a4c9 100644 --- a/plugins/autotest/testresultspane.cpp +++ b/plugins/autotest/testresultspane.cpp @@ -16,10 +16,12 @@ ** ****************************************************************************/ +#include "autotestplugin.h" #include "testresultspane.h" #include "testresultmodel.h" #include "testresultdelegate.h" #include "testrunner.h" +#include "testsettings.h" #include "testtreemodel.h" #include @@ -271,6 +273,11 @@ void TestResultsPane::onRunSelectedTriggered() void TestResultsPane::initializeFilterMenu() { + const bool omitIntern = AutotestPlugin::instance()->settings()->omitInternalMssg; + // FilterModel has all messages enabled by default + if (omitIntern) + m_filterModel->toggleTestResultType(ResultType::MESSAGE_INTERNAL); + QMap textAndType; textAndType.insert(ResultType::PASS, tr("Pass")); textAndType.insert(ResultType::FAIL, tr("Fail")); @@ -285,7 +292,7 @@ void TestResultsPane::initializeFilterMenu() QAction *action = new QAction(m_filterMenu); action->setText(textAndType.value(result)); action->setCheckable(true); - action->setChecked(true); + action->setChecked(result != ResultType::MESSAGE_INTERNAL || !omitIntern); action->setData(result); m_filterMenu->addAction(action); } diff --git a/plugins/autotest/testrunner.cpp b/plugins/autotest/testrunner.cpp index 2c0b035a1c7..4ec7478453e 100644 --- a/plugins/autotest/testrunner.cpp +++ b/plugins/autotest/testrunner.cpp @@ -17,8 +17,10 @@ ****************************************************************************/ #include "autotestconstants.h" +#include "autotestplugin.h" #include "testresultspane.h" #include "testrunner.h" +#include "testsettings.h" #include // REMOVE @@ -112,6 +114,53 @@ static bool xmlExtractTypeFileLine(const QString &code, const QString &tagStart, 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) { @@ -134,9 +183,9 @@ static bool xmlExtractBenchmarkInformation(const QString &code, const QString &t else if (metric == QLatin1String("CPUCycles")) // -perf metricsTxt = QLatin1String("CPU cycles"); description = QObject::tr("%1 %2 per iteration (total: %3, iterations: %4)") - .arg(QString::number(value, 'f', 6)) + .arg(formatResult(value)) .arg(metricsTxt) - .arg(QString::number(value * (double)iterations, 'g', 3)) + .arg(formatResult(value * (double)iterations)) .arg(iterations); return true; } @@ -282,7 +331,7 @@ static QString which(const QString &path, const QString &cmd) } bool performExec(const QString &cmd, const QStringList &args, const QString &workingDir, - const Utils::Environment &env, int timeout = 60000) + const Utils::Environment &env, int timeout) { QString runCmd; if (!QDir::toNativeSeparators(cmd).contains(QDir::separator())) { @@ -354,6 +403,10 @@ void performTestRun(QFutureInterface &future, const QList settings = AutotestPlugin::instance()->settings(); + const int timeout = settings->timeout; + const QString metricsOption = TestSettings::metricsTypeToOption(settings->metrics); + foreach (const TestConfiguration *tc, selectedTests) { if (future.isCanceled()) break; @@ -363,10 +416,12 @@ void performTestRun(QFutureInterface &future, const QListenvironment(); args << QLatin1String("-xml"); + if (!metricsOption.isEmpty()) + args << metricsOption; if (tc->testCases().count()) args << tc->testCases(); - performExec(cmd, args, workDir, env); + performExec(cmd, args, workDir, env, timeout); } future.setProgressValue(testCaseCount); diff --git a/plugins/autotest/testsettings.cpp b/plugins/autotest/testsettings.cpp new file mode 100644 index 00000000000..17a9f7c7aa5 --- /dev/null +++ b/plugins/autotest/testsettings.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** 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 "testsettings.h" + +#include + +namespace Autotest { +namespace Internal { + +static const char group[] = "Autotest"; +static const char timeoutKey[] = "Timeout"; +static const char metricsKey[] = "Metrics"; +static const char omitInternalKey[] = "OmitInternal"; +static const int defaultTimeout = 60000; + +TestSettings::TestSettings() + : timeout(defaultTimeout), metrics(Walltime), omitInternalMssg(true) +{ +} + +void TestSettings::toSettings(QSettings *s) const +{ + s->beginGroup(QLatin1String(group)); + s->setValue(QLatin1String(timeoutKey), timeout); + s->setValue(QLatin1String(metricsKey), metrics); + s->setValue(QLatin1String(omitInternalKey), omitInternalMssg); + s->endGroup(); +} + +static MetricsType intToMetrics(int value) +{ + switch (value) { + case Walltime: + return Walltime; + case TickCounter: + return TickCounter; + case EventCounter: + return EventCounter; + case CallGrind: + return CallGrind; + case Perf: + return Perf; + default: + return Walltime; + } +} + +void TestSettings::fromSettings(const QSettings *s) +{ + const QString root = QLatin1String(group) + QLatin1Char('/'); + timeout = s->value(root + QLatin1String(timeoutKey), defaultTimeout).toInt(); + metrics = intToMetrics(s->value(root + QLatin1String(metricsKey), Walltime).toInt()); + omitInternalMssg = s->value(root + QLatin1String(omitInternalKey), true).toBool(); +} + +bool TestSettings::equals(const TestSettings &rhs) const +{ + return timeout == rhs.timeout && metrics == rhs.metrics + && omitInternalMssg == rhs.omitInternalMssg; +} + +QString TestSettings::metricsTypeToOption(const MetricsType type) +{ + switch (type) { + case MetricsType::Walltime: + return QString(); + case MetricsType::TickCounter: + return QLatin1String("-tickcounter"); + case MetricsType::EventCounter: + return QLatin1String("-eventcounter"); + case MetricsType::CallGrind: + return QLatin1String("-callgrind"); + case MetricsType::Perf: + return QLatin1String("-perf"); + default: + return QString(); + } +} + +} // namespace Internal +} // namespace Autotest diff --git a/plugins/autotest/testsettings.h b/plugins/autotest/testsettings.h new file mode 100644 index 00000000000..dc82647d105 --- /dev/null +++ b/plugins/autotest/testsettings.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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 TESTSETTINGS_H +#define TESTSETTINGS_H + +#include + +QT_BEGIN_NAMESPACE +class QSettings; +QT_END_NAMESPACE + +namespace Autotest { +namespace Internal { + +enum MetricsType { + Walltime, + TickCounter, + EventCounter, + CallGrind, + Perf +}; + +struct TestSettings +{ + TestSettings(); + void toSettings(QSettings *s) const; + void fromSettings(const QSettings *s); + bool equals(const TestSettings &rhs) const; + static QString metricsTypeToOption(const MetricsType type); + + int timeout; + MetricsType metrics; + bool omitInternalMssg; +}; + +inline bool operator==(const TestSettings &s1, const TestSettings &s2) { return s1.equals(s2); } +inline bool operator!=(const TestSettings &s1, const TestSettings &s2) { return !s1.equals(s2); } + +} // namespace Internal +} // namespace Autotest + +#endif // TESTSETTINGS_H diff --git a/plugins/autotest/testsettingspage.cpp b/plugins/autotest/testsettingspage.cpp new file mode 100644 index 00000000000..64be40bb9be --- /dev/null +++ b/plugins/autotest/testsettingspage.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** 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 "autotestconstants.h" +#include "testsettingspage.h" +#include "testsettings.h" + +#include + +#include + +namespace Autotest { +namespace Internal { + +TestSettingsWidget::TestSettingsWidget(QWidget *parent) + : QWidget(parent) +{ + m_ui.setupUi(this); + m_ui.callgrindRB->setEnabled(Utils::HostOsInfo::isAnyUnixHost()); // valgrind available on UNIX + m_ui.perfRB->setEnabled(Utils::HostOsInfo::isLinuxHost()); // according to docs perf Linux only +} + +void TestSettingsWidget::setSettings(const TestSettings &settings) +{ + m_ui.timeoutSpin->setValue(settings.timeout / 1000); // we store milliseconds + m_ui.omitInternalMsgCB->setChecked(settings.omitInternalMssg); + + switch (settings.metrics) { + case MetricsType::Walltime: + m_ui.walltimeRB->setChecked(true); + break; + case MetricsType::TickCounter: + m_ui.tickcounterRB->setChecked(true); + break; + case MetricsType::EventCounter: + m_ui.eventCounterRB->setChecked(true); + break; + case MetricsType::CallGrind: + m_ui.callgrindRB->setChecked(true); + break; + case MetricsType::Perf: + m_ui.perfRB->setChecked(true); + break; + default: + m_ui.walltimeRB->setChecked(true); + } +} + +TestSettings TestSettingsWidget::settings() const +{ + TestSettings result; + result.timeout = m_ui.timeoutSpin->value() * 1000; // we display seconds + result.omitInternalMssg = m_ui.omitInternalMsgCB->isChecked(); + + if (m_ui.walltimeRB->isChecked()) + result.metrics = MetricsType::Walltime; + else if (m_ui.tickcounterRB->isChecked()) + result.metrics = MetricsType::TickCounter; + else if (m_ui.eventCounterRB->isChecked()) + result.metrics = MetricsType::EventCounter; + else if (m_ui.callgrindRB->isChecked()) + result.metrics = MetricsType::CallGrind; + else if (m_ui.perfRB->isChecked()) + result.metrics = MetricsType::Perf; + + return result; +} + +TestSettingsPage::TestSettingsPage(const QSharedPointer &settings) + : m_settings(settings), m_widget(0) +{ + setId("A.General"); + setDisplayName(tr("General")); + setCategory(Constants::AUTOTEST_SETTINGS_CATEGORY); + setDisplayCategory(tr("Test Settings")); + setCategoryIcon(QLatin1String(":/images/autotest.png")); +} + +TestSettingsPage::~TestSettingsPage() +{ +} + +QWidget *TestSettingsPage::widget() +{ + if (!m_widget) { + m_widget = new TestSettingsWidget; + m_widget->setSettings(*m_settings); + } + return m_widget; +} + +void TestSettingsPage::apply() +{ + if (!m_widget) // page was not shown at all + return; + const TestSettings newSettings = m_widget->settings(); + if (newSettings != *m_settings) { + *m_settings = newSettings; + m_settings->toSettings(Core::ICore::settings()); + } +} + +} // namespace Internal +} // namespace Autotest diff --git a/plugins/autotest/testsettingspage.h b/plugins/autotest/testsettingspage.h new file mode 100644 index 00000000000..cc30026fe27 --- /dev/null +++ b/plugins/autotest/testsettingspage.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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 TESTSETTINGSPAGE_H +#define TESTSETTINGSPAGE_H + +#include "ui_testsettingspage.h" + +#include + +#include + +namespace Autotest { +namespace Internal { + +struct TestSettings; + +class TestSettingsWidget : public QWidget +{ + Q_OBJECT +public: + explicit TestSettingsWidget(QWidget *parent = 0); + + void setSettings(const TestSettings &settings); + TestSettings settings() const; + +private: + Ui::TestSettingsPage m_ui; + +}; + +class TestSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT +public: + explicit TestSettingsPage(const QSharedPointer &settings); + ~TestSettingsPage(); + + QWidget *widget(); + void apply(); + void finish() { } + +private: + QSharedPointer m_settings; + QPointer m_widget; +}; + +} // namespace Internal +} // namespace Autotest + +#endif // TESTSETTINGSPAGE_H diff --git a/plugins/autotest/testsettingspage.ui b/plugins/autotest/testsettingspage.ui new file mode 100644 index 00000000000..1a68db4b21b --- /dev/null +++ b/plugins/autotest/testsettingspage.ui @@ -0,0 +1,258 @@ + + + Autotest::Internal::TestSettingsPage + + + + 0 + 0 + 462 + 292 + + + + Form + + + + + + + + + + + + Timeout used when executing test cases. This will apply for each test case on its own, not the whole project. + + + Timeout: + + + + + + + Timeout used when executing test cases. This will apply for each test case on its own, not the whole project. + + + s + + + 5 + + + 36000 + + + 60 + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + If checked Internal Messages won't be shown by default. (You can still enable them on the test results filter) + + + Omit Internal Messages + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + 0 + 0 + + + + Benchmark Metrics + + + + + + + + + 0 + 0 + + + + Use Walltime metrics for executing benchmarks. (default) + + + Walltime + + + true + + + + + + + + 0 + 0 + + + + Use tick counter for executing benchmarks. + + + Tickcounter + + + + + + + + 0 + 0 + + + + Use event counter when executing benchmarks. + + + Eventcounter + + + + + + + false + + + + 0 + 0 + + + + Use callgrind when executing benchmark. (valgrind must be installed) + + + Callgrind + + + + + + + false + + + + 0 + 0 + + + + Use perf when executing benchmarks. (perf must be installed) + + + Perf + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + +