1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <private/qdeclarativepixmapcache_p.h>
44 #include <QtDeclarative/qdeclarativeengine.h>
45 #include <QtDeclarative/qdeclarativeimageprovider.h>
46 #include <QNetworkReply>
47 #include "testhttpserver.h"
48 #include "../../../shared/util.h"
50 #ifndef QT_NO_CONCURRENT
51 #include <qtconcurrentrun.h>
55 // These don't let normal people run tests!
56 //#include "../network-settings.h"
59 // In Symbian OS test data is located in applications private dir
63 class tst_qdeclarativepixmapcache : public QObject
67 tst_qdeclarativepixmapcache() :
68 thisfile(QUrl::fromLocalFile(__FILE__)),
71 server.serveDirectory(SRCDIR "/data/http");
82 #ifndef QT_NO_CONCURRENT
86 QDeclarativeEngine engine;
88 TestHTTPServer server;
92 static int slotters=0;
94 class Slotter : public QObject
111 QTestEventLoop::instance().exitLoop();
115 #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
116 static const bool localfile_optimized = true;
118 static const bool localfile_optimized = false;
121 void tst_qdeclarativepixmapcache::single_data()
123 // Note, since QDeclarativePixmapCache is shared, tests affect each other!
124 // so use different files fore all test functions.
126 QTest::addColumn<QUrl>("target");
127 QTest::addColumn<bool>("incache");
128 QTest::addColumn<bool>("exists");
129 QTest::addColumn<bool>("neterror");
131 // File URLs are optimized
132 QTest::newRow("local") << thisfile.resolved(QUrl("data/exists.png")) << localfile_optimized << true << false;
133 QTest::newRow("local") << thisfile.resolved(QUrl("data/notexists.png")) << localfile_optimized << false << false;
134 QTest::newRow("remote") << QUrl("http://127.0.0.1:14452/exists.png") << false << true << false;
135 QTest::newRow("remote") << QUrl("http://127.0.0.1:14452/notexists.png") << false << false << true;
138 void tst_qdeclarativepixmapcache::single()
140 QFETCH(QUrl, target);
141 QFETCH(bool, incache);
142 QFETCH(bool, exists);
143 QFETCH(bool, neterror);
145 QString expectedError;
147 expectedError = "Error downloading " + target.toString() + " - server replied: Not found";
148 } else if (!exists) {
149 expectedError = "Cannot open: " + target.toString();
152 QDeclarativePixmap pixmap;
153 QVERIFY(pixmap.width() <= 0); // Check Qt assumption
155 pixmap.load(&engine, target);
158 QCOMPARE(pixmap.error(), expectedError);
160 QVERIFY(pixmap.status() == QDeclarativePixmap::Ready);
161 QVERIFY(pixmap.width() > 0);
163 QVERIFY(pixmap.status() == QDeclarativePixmap::Error);
164 QVERIFY(pixmap.width() <= 0);
167 QVERIFY(pixmap.width() <= 0);
170 pixmap.connectFinished(&getter, SLOT(got()));
171 QTestEventLoop::instance().enterLoop(10);
172 QVERIFY(!QTestEventLoop::instance().timeout());
173 QVERIFY(getter.gotslot);
175 QVERIFY(pixmap.status() == QDeclarativePixmap::Ready);
176 QVERIFY(pixmap.width() > 0);
178 QVERIFY(pixmap.status() == QDeclarativePixmap::Error);
179 QVERIFY(pixmap.width() <= 0);
181 QCOMPARE(pixmap.error(), expectedError);
185 void tst_qdeclarativepixmapcache::parallel_data()
187 // Note, since QDeclarativePixmapCache is shared, tests affect each other!
188 // so use different files fore all test functions.
190 QTest::addColumn<QUrl>("target1");
191 QTest::addColumn<QUrl>("target2");
192 QTest::addColumn<int>("incache");
193 QTest::addColumn<int>("cancel"); // which one to cancel
195 QTest::newRow("local")
196 << thisfile.resolved(QUrl("data/exists1.png"))
197 << thisfile.resolved(QUrl("data/exists2.png"))
198 << (localfile_optimized ? 2 : 0)
201 QTest::newRow("remote")
202 << QUrl("http://127.0.0.1:14452/exists2.png")
203 << QUrl("http://127.0.0.1:14452/exists3.png")
207 QTest::newRow("remoteagain")
208 << QUrl("http://127.0.0.1:14452/exists2.png")
209 << QUrl("http://127.0.0.1:14452/exists3.png")
213 QTest::newRow("remotecopy")
214 << QUrl("http://127.0.0.1:14452/exists4.png")
215 << QUrl("http://127.0.0.1:14452/exists4.png")
219 QTest::newRow("remotecopycancel")
220 << QUrl("http://127.0.0.1:14452/exists5.png")
221 << QUrl("http://127.0.0.1:14452/exists5.png")
226 void tst_qdeclarativepixmapcache::parallel()
228 QFETCH(QUrl, target1);
229 QFETCH(QUrl, target2);
230 QFETCH(int, incache);
234 targets << target1 << target2;
236 QList<QDeclarativePixmap *> pixmaps;
238 QList<Slotter*> getters;
240 for (int i=0; i<targets.count(); ++i) {
241 QUrl target = targets.at(i);
242 QDeclarativePixmap *pixmap = new QDeclarativePixmap;
244 pixmap->load(&engine, target);
246 QVERIFY(pixmap->status() != QDeclarativePixmap::Error);
247 pixmaps.append(pixmap);
248 if (pixmap->isReady()) {
249 QVERIFY(pixmap->width() > 0);
251 pending.append(false);
253 QVERIFY(pixmap->width() <= 0);
254 getters.append(new Slotter);
255 pixmap->connectFinished(getters[i], SLOT(got()));
256 pending.append(true);
260 QCOMPARE(incache+slotters, targets.count());
263 pixmaps.at(cancel)->clear(getters[cancel]);
268 QTestEventLoop::instance().enterLoop(10);
269 QVERIFY(!QTestEventLoop::instance().timeout());
272 for (int i=0; i<targets.count(); ++i) {
273 QDeclarativePixmap *pixmap = pixmaps[i];
276 QVERIFY(!getters[i]->gotslot);
279 QVERIFY(getters[i]->gotslot);
281 QVERIFY(pixmap->isReady());
282 QVERIFY(pixmap->width() > 0);
290 void tst_qdeclarativepixmapcache::massive()
292 QUrl url = thisfile.resolved(QUrl("data/massive.png"));
294 // Confirm that massive images remain in the cache while they are
295 // in use by the application.
298 QDeclarativePixmap p(0, url);
299 QVERIFY(p.isReady());
300 QVERIFY(p.pixmap().size() == QSize(10000, 1000));
301 cachekey = p.pixmap().cacheKey();
303 QDeclarativePixmap p2(0, url);
304 QVERIFY(p2.isReady());
305 QVERIFY(p2.pixmap().size() == QSize(10000, 1000));
307 QVERIFY(p2.pixmap().cacheKey() == cachekey);
310 // Confirm that massive images are removed from the cache when
311 // they become unused
315 QDeclarativePixmap p(0, url);
316 QVERIFY(p.isReady());
317 QVERIFY(p.pixmap().size() == QSize(10000, 1000));
318 cachekey = p.pixmap().cacheKey();
321 QDeclarativePixmap p2(0, url);
322 QVERIFY(p2.isReady());
323 QVERIFY(p2.pixmap().size() == QSize(10000, 1000));
325 QVERIFY(p2.pixmap().cacheKey() != cachekey);
330 void tst_qdeclarativepixmapcache::cancelcrash()
332 QUrl url("http://127.0.0.1:14452/cancelcrash_notexist.png");
333 for (int ii = 0; ii < 1000; ++ii) {
334 QDeclarativePixmap pix(&engine, url);
338 class MyPixmapProvider : public QDeclarativeImageProvider
342 : QDeclarativeImageProvider(Pixmap) {}
344 virtual QPixmap requestPixmap(const QString &d, QSize *, const QSize &) {
346 QPixmap pix(800, 600);
353 void tst_qdeclarativepixmapcache::shrinkcache()
355 QDeclarativeEngine engine;
356 engine.addImageProvider(QLatin1String("mypixmaps"), new MyPixmapProvider);
358 for (int ii = 0; ii < 4000; ++ii) {
359 QUrl url("image://mypixmaps/" + QString::number(ii));
360 QDeclarativePixmap p(&engine, url);
364 #ifndef QT_NO_CONCURRENT
366 void createNetworkServer()
368 QEventLoop eventLoop;
369 TestHTTPServer server(14453);
370 server.serveDirectory(SRCDIR "/data/http");
371 QTimer::singleShot(100, &eventLoop, SLOT(quit()));
375 #ifndef QT_NO_CONCURRENT
377 void tst_qdeclarativepixmapcache::networkCrash()
379 QFuture<void> future = QtConcurrent::run(createNetworkServer);
380 QDeclarativeEngine engine;
381 for (int ii = 0; ii < 100 ; ++ii) {
382 QDeclarativePixmap* pixmap = new QDeclarativePixmap;
383 pixmap->load(&engine, QUrl(QString("http://127.0.0.1:14453/exists.png")));
394 QTEST_MAIN(tst_qdeclarativepixmapcache)
396 #include "tst_qdeclarativepixmapcache.moc"