aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmlprofiler/tests
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2016-06-03 16:57:37 +0200
committerUlf Hermann <ulf.hermann@qt.io>2016-06-08 08:48:59 +0000
commit6de290a188fc8fbdb9b39ae0fbc1e95e058314fb (patch)
tree58223c49eb1502192d335f42c338554fe6dd27f7 /src/plugins/qmlprofiler/tests
parenta0f956f0509a68d7eaec718bed294661bca49996 (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.cpp324
-rw-r--r--src/plugins/qmlprofiler/tests/pixmapcachemodel_test.h57
-rw-r--r--src/plugins/qmlprofiler/tests/tests.pri6
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