diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2016-06-03 16:57:37 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2016-06-08 08:48:59 +0000 |
commit | 6de290a188fc8fbdb9b39ae0fbc1e95e058314fb (patch) | |
tree | 58223c49eb1502192d335f42c338554fe6dd27f7 /src/plugins/qmlprofiler/tests | |
parent | a0f956f0509a68d7eaec718bed294661bca49996 (diff) |
QmlProfiler: Add tests for pixmap cache model
Change-Id: Ic3114f6cd205434e2a489112d070300a3c842352
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
Diffstat (limited to 'src/plugins/qmlprofiler/tests')
-rw-r--r-- | src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp | 324 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/tests/pixmapcachemodel_test.h | 57 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/tests/tests.pri | 6 |
3 files changed, 385 insertions, 2 deletions
diff --git a/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp b/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp new file mode 100644 index 00000000000..ad3f6f09b66 --- /dev/null +++ b/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.cpp @@ -0,0 +1,324 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "pixmapcachemodel_test.h" +#include <QtTest> + +namespace QmlProfiler { +namespace Internal { + +PixmapCacheModelTest::PixmapCacheModelTest(QObject *parent) : QObject(parent), + manager(nullptr), model(&manager) +{ +} + +void PixmapCacheModelTest::initTestCase() +{ + manager.startAcquiring(); + manager.traceTime()->setTime(1, 300); + + QmlEventType type; + type.message = PixmapCacheEvent; + type.rangeType = MaximumRangeType; + type.location = QmlEventLocation("dings.png", -1, -1); + + for (int i = 0; i < MaximumPixmapEventType; ++i) { + type.detailType = i; + eventTypeIndices[i] = manager.qmlModel()->addEventType(type); + } + + // random data, should still result in consistent model. + for (int i = 0; i < 100; ++i) { + QmlEvent event; + event.setTypeIndex(eventTypeIndices[(i * 13) % MaximumPixmapEventType]); + event.setTimestamp(i); + event.setNumbers({i + 1, i - 1, i * 2}); + manager.qmlModel()->addEvent(event); + } + + type.location = QmlEventLocation("blah.png", -1, -1); + for (int i = 0; i < MaximumPixmapEventType; ++i) { + type.detailType = i; + eventTypeIndices[i + MaximumPixmapEventType] = manager.qmlModel()->addEventType(type); + } + + + // Explicitly test some "interesting" things + int nextItem = model.count(); + QmlEvent event; + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapLoadingStarted]); + event.setTimestamp(101); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncached); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Loading); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapCacheCountChanged]); + event.setNumbers({0, 0, 200}); // cache count increase + event.setTimestamp(102); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::ToBeCached); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Loading); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapLoadingError]); + event.setTimestamp(103); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Corrupt); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Error); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapCacheCountChanged]); + event.setNumbers({0, 0, 199}); // cache count decrease + event.setTimestamp(104); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncacheable); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Error); + + + ++nextItem; + QCOMPARE(model.count(), nextItem); + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapLoadingStarted]); + event.setTimestamp(105); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncached); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Loading); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapLoadingError]); + event.setTimestamp(106); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncacheable); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Error); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapCacheCountChanged]); + // We still cache the previous item, even though it's uncacheable. + // This way we get a corrupt cache entry ... + event.setNumbers({0, 0, 200}); + event.setTimestamp(107); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem - 1), PixmapCacheModel::Corrupt); + QCOMPARE(model.loadState(nextItem - 1), PixmapCacheModel::Error); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncacheable); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Error); + + // ... which is immediately removed by another cache count change + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapCacheCountChanged]); + event.setNumbers({0, 0, 199}); // cache count decrease, removes the corrupt entry + event.setTimestamp(108); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem - 1), PixmapCacheModel::Uncacheable); + QCOMPARE(model.loadState(nextItem - 1), PixmapCacheModel::Error); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncacheable); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Error); + + + ++nextItem; + QCOMPARE(model.count(), nextItem); + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapLoadingStarted]); + event.setTimestamp(109); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncached); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Loading); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapCacheCountChanged]); + event.setNumbers({0, 0, 200}); // cache count increase + event.setTimestamp(110); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::ToBeCached); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Loading); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapSizeKnown]); + event.setNumbers({50, 50}); + event.setTimestamp(111); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Cached); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Loading); + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapCacheCountChanged]); + event.setNumbers({0, 0, 199}); // cache count decrease + event.setTimestamp(112); + manager.qmlModel()->addEvent(event); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncached); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Loading); + + // one pixmap item, and two cache count changes with known size + QCOMPARE(model.count(), nextItem + 3); + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapSizeKnown]); + event.setNumbers({20, 30}); + event.setTimestamp(113); + manager.qmlModel()->addEvent(event); // Results in Uncached, with valid size + QCOMPARE(model.count(), nextItem + 3); // no item added here; we just store the size + + event.setTypeIndex(eventTypeIndices[MaximumPixmapEventType + PixmapLoadingError]); + event.setTimestamp(114); + // terminates the still loading item, adding another cache count change + manager.qmlModel()->addEvent(event); + QCOMPARE(model.count(), nextItem + 4); + QCOMPARE(model.cacheState(nextItem), PixmapCacheModel::Uncacheable); + QCOMPARE(model.loadState(nextItem), PixmapCacheModel::Error); + + + // some more random data + for (int i = MaximumPixmapEventType; i < 2 * MaximumPixmapEventType; ++i) { + for (int j = 0; j < i; ++j) { + QmlEvent event; + event.setTypeIndex(eventTypeIndices[i]); + event.setTimestamp(i + j + 200); + event.setNumbers({i + 1, i - 1, i - j}); + manager.qmlModel()->addEvent(event); + } + } + + + manager.acquiringDone(); + + QCOMPARE(manager.state(), QmlProfilerModelManager::Done); +} + +void PixmapCacheModelTest::testConsistency() +{ + // one unique URL + QCOMPARE(model.expandedRowCount(), 4); + QVERIFY(model.collapsedRowCount() >= model.expandedRowCount()); + + float prevHeight = 0; + qint64 currentTime = -1; + qint64 currentEnd = -1; + QHash<int, qint64> collapsedEnds; + for (int i = 0; i < model.count(); ++i) { + int *typesEnd = eventTypeIndices + 2 * MaximumPixmapEventType; + QVERIFY(std::find(eventTypeIndices, typesEnd, model.typeId(i)) != typesEnd); + + QVERIFY(model.startTime(i) >= currentTime); + currentTime = model.startTime(i); + QVERIFY(currentTime >= manager.traceTime()->startTime()); + currentEnd = model.endTime(i); + QVERIFY(currentEnd <= manager.traceTime()->endTime()); + + const QVariantMap details = model.details(i); + + int collapsedRow = model.collapsedRow(i); + int expandedRow = model.expandedRow(i); + + switch (collapsedRow) { + case 0: + QFAIL("There should be no events in row 0"); + break; + case 1: + QVERIFY(model.relativeHeight(i) != prevHeight); + prevHeight = model.relativeHeight(i); + QCOMPARE(expandedRow, 1); + break; + default: + QVERIFY(expandedRow > 1); + QCOMPARE(model.relativeHeight(i), 1.0f); + QVERIFY(collapsedRow < model.collapsedRowCount()); + if (collapsedEnds.contains(collapsedRow)) + QVERIFY(collapsedEnds[collapsedRow] <= currentTime); + collapsedEnds[collapsedRow] = model.endTime(i); + } + + + switch (expandedRow) { + case 0: + QFAIL("There should be no events in row 0"); + break; + case 1: + QCOMPARE(collapsedRow, 1); + QVERIFY(details[QLatin1String("displayName")].toString() == model.tr("Image Cached")); + break; + default: + QVERIFY(collapsedRow > 1); + QCOMPARE(model.relativeHeight(i), 1.0f); + QVERIFY(expandedRow < model.expandedRowCount()); + QVERIFY(details[QLatin1String("displayName")].toString() == model.tr("Image Loaded")); + QCOMPARE(details[model.tr("Duration")].toString(), + QmlProfilerDataModel::formatTime(model.duration(i))); + // In expanded view pixmaps of the same URL but different sizes are allowed to overlap. + // It looks bad, but that should be a rare thing. + break; + } + + QVERIFY(details.contains(model.tr("Cache Size"))); + QString filename = details[model.tr("File")].toString(); + QVERIFY(filename == QString("dings.png") || filename == QString("blah.png")); + QVERIFY(details.contains(model.tr("Width"))); + QVERIFY(details.contains(model.tr("Height"))); + } +} + +void PixmapCacheModelTest::testRowMaxValue() +{ + QCOMPARE(model.rowMaxValue(2), 0); + QVERIFY(model.rowMaxValue(1) > 0); +} + +void PixmapCacheModelTest::testColor() +{ + QColor row1Color; + QColor dingsColor; + QColor blahColor; + for (int i = 0; i < model.count(); ++i) { + if (model.collapsedRow(i) == 1) { + if (!row1Color.isValid()) + row1Color = model.color(i); + else + QCOMPARE(model.color(i), row1Color); + } else { + const QmlEventType &type = manager.qmlModel()->eventTypes()[model.typeId(i)]; + QColor &pixmapColor = (type.location.filename == QString("blah.png")) ? + blahColor : dingsColor; + if (!pixmapColor.isValid()) + pixmapColor = model.color(i); + else + QCOMPARE(model.color(i), pixmapColor); + } + } +} + +void PixmapCacheModelTest::testLabels() +{ + const QVariantList labels = model.labels(); + QCOMPARE(labels.length(), 3); + + const QVariantMap countRow = labels[0].toMap(); + + QCOMPARE(countRow[QString("description")].toString(), model.tr("Cache Size")); + QCOMPARE(countRow[QString("id")].toInt(), 0); + + const QVariantMap dingsRow = labels[1].toMap(); + QCOMPARE(dingsRow[QString("description")].toString(), QString("dings.png")); + QCOMPARE(dingsRow[QString("id")].toInt(), 1); // urlIndex + 1 + + const QVariantMap blahRow = labels[2].toMap(); + QCOMPARE(blahRow[QString("description")].toString(), QString("blah.png")); + QCOMPARE(blahRow[QString("id")].toInt(), 2); // urlIndex + 1 +} + +void PixmapCacheModelTest::cleanupTestCase() +{ + manager.clear(); + QCOMPARE(model.count(), 0); +} + +} // namespace Internal +} // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.h b/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.h new file mode 100644 index 00000000000..8a6448bb105 --- /dev/null +++ b/src/plugins/qmlprofiler/tests/pixmapcachemodel_test.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <qmlprofiler/pixmapcachemodel.h> +#include <qmlprofiler/qmlprofilermodelmanager.h> +#include <QObject> + +namespace QmlProfiler { +namespace Internal { + +class PixmapCacheModelTest : public QObject +{ + Q_OBJECT +public: + PixmapCacheModelTest(QObject *parent = 0); + +private slots: + void initTestCase(); + void testConsistency(); + void testRowMaxValue(); + void testColor(); + void testLabels(); + void cleanupTestCase(); + +private: + QmlProfilerModelManager manager; + PixmapCacheModel model; + + int eventTypeIndices[2 * MaximumPixmapEventType]; +}; + +} // namespace Internal +} // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/tests/tests.pri b/src/plugins/qmlprofiler/tests/tests.pri index 9c5a8d894e0..248c4cc182e 100644 --- a/src/plugins/qmlprofiler/tests/tests.pri +++ b/src/plugins/qmlprofiler/tests/tests.pri @@ -5,7 +5,8 @@ SOURCES += \ $$PWD/flamegraphview_test.cpp \ $$PWD/inputeventsmodel_test.cpp \ $$PWD/localqmlprofilerrunner_test.cpp \ - $$PWD/memoryusagemodel_test.cpp + $$PWD/memoryusagemodel_test.cpp \ + $$PWD/pixmapcachemodel_test.cpp HEADERS += \ $$PWD/debugmessagesmodel_test.h \ @@ -14,4 +15,5 @@ HEADERS += \ $$PWD/flamegraphview_test.h \ $$PWD/inputeventsmodel_test.h \ $$PWD/localqmlprofilerrunner_test.h \ - $$PWD/memoryusagemodel_test.h + $$PWD/memoryusagemodel_test.h \ + $$PWD/pixmapcachemodel_test.h |