mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-08 02:17:43 +08:00
qt 6.5.1 original
This commit is contained in:
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_bench_qnetworkdiskcache Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_benchmark(tst_bench_qnetworkdiskcache
|
||||
SOURCES
|
||||
tst_qnetworkdiskcache.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
Qt::Test
|
||||
)
|
@ -0,0 +1,379 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QNetworkDiskCache>
|
||||
#include <QNetworkCacheMetaData>
|
||||
#include <QDir>
|
||||
#include <QBuffer>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#include <QTest>
|
||||
#include <QIODevice>
|
||||
#include <QStandardPaths>
|
||||
#include <QDirIterator>
|
||||
|
||||
|
||||
|
||||
enum Numbers { NumFakeCacheObjects = 200, //entries in pre-populated cache
|
||||
NumInsertions = 100, //insertions to be timed
|
||||
NumRemovals = 100, //removals to be timed
|
||||
NumReadContent = 100, //meta requests to be timed
|
||||
HugeCacheLimit = 50*1024*1024, // max size for a big cache
|
||||
TinyCacheLimit = 1*512*1024}; // max size for a tiny cache
|
||||
|
||||
const QString fakeURLbase = "http://127.0.0.1/fake/";
|
||||
//fake HTTP body aka payload
|
||||
const QByteArray payload("Qt rocks!");
|
||||
|
||||
class tst_qnetworkdiskcache : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
void injectFakeData();
|
||||
void insertOneItem();
|
||||
bool isUrlCached(quint32 id);
|
||||
void cleanRecursive(QString &path);
|
||||
void cleanupCacheObject();
|
||||
void initCacheObject();
|
||||
QString cacheDir;
|
||||
QNetworkDiskCache *cache;
|
||||
|
||||
public slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
private slots:
|
||||
|
||||
void timeInsertion_data();
|
||||
void timeInsertion();
|
||||
void timeRead_data();
|
||||
void timeRead();
|
||||
void timeRemoval_data();
|
||||
void timeRemoval();
|
||||
|
||||
void timeExpiration_data();
|
||||
void timeExpiration();
|
||||
};
|
||||
|
||||
|
||||
void tst_qnetworkdiskcache::initTestCase()
|
||||
{
|
||||
cache = 0;
|
||||
}
|
||||
|
||||
|
||||
void tst_qnetworkdiskcache::cleanupTestCase()
|
||||
{
|
||||
cleanupCacheObject();
|
||||
cleanRecursive(cacheDir);
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::timeInsertion_data()
|
||||
{
|
||||
QTest::addColumn<QString>("cacheRootDirectory");
|
||||
|
||||
QString cacheLoc = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
QTest::newRow("QStandardPaths Cache Location") << cacheLoc;
|
||||
}
|
||||
|
||||
//This functions times an insert() operation.
|
||||
//You can run it after populating the cache with
|
||||
//fake data so that more realistic performance
|
||||
//estimates are obtained.
|
||||
void tst_qnetworkdiskcache::timeInsertion()
|
||||
{
|
||||
|
||||
QFETCH(QString, cacheRootDirectory);
|
||||
|
||||
cacheDir = QString( cacheRootDirectory + QDir::separator() + "man_qndc");
|
||||
QDir d;
|
||||
qDebug() << "Setting cache directory to = " << d.absoluteFilePath(cacheDir);
|
||||
|
||||
//Housekeeping
|
||||
cleanRecursive(cacheDir); // slow op.
|
||||
initCacheObject();
|
||||
|
||||
cache->setCacheDirectory(cacheDir);
|
||||
cache->setMaximumCacheSize(qint64(HugeCacheLimit));
|
||||
cache->clear();
|
||||
|
||||
//populate some fake data to simulate partially full cache
|
||||
injectFakeData(); // SLOW
|
||||
|
||||
//Sanity-check that the first URL that we insert below isn't already in there.
|
||||
QVERIFY(isUrlCached(NumFakeCacheObjects) == false);
|
||||
|
||||
// IMPORTANT: max cache size should be HugeCacheLimit, to avoid evictions below
|
||||
//time insertion of previously-uncached URLs.
|
||||
QBENCHMARK_ONCE {
|
||||
for (quint32 i = NumFakeCacheObjects; i < (NumFakeCacheObjects + NumInsertions); i++) {
|
||||
//prepare metata for url
|
||||
QNetworkCacheMetaData meta;
|
||||
QString fakeURL;
|
||||
QTextStream stream(&fakeURL);
|
||||
stream << fakeURLbase << i;
|
||||
QUrl url(fakeURL);
|
||||
meta.setUrl(url);
|
||||
meta.setSaveToDisk(true);
|
||||
|
||||
//commit payload and metadata to disk
|
||||
QIODevice *device = cache->prepare(meta);
|
||||
device->write(payload);
|
||||
cache->insert(device);
|
||||
}
|
||||
}
|
||||
|
||||
//SLOW cleanup
|
||||
cleanupCacheObject();
|
||||
cleanRecursive(cacheDir);
|
||||
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::timeRead_data()
|
||||
{
|
||||
QTest::addColumn<QString>("cacheRootDirectory");
|
||||
|
||||
QString cacheLoc = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
QTest::newRow("QStandardPaths Cache Location") << cacheLoc;
|
||||
}
|
||||
|
||||
//Times metadata as well payload lookup
|
||||
// i.e metaData(), rawHeaders() and data()
|
||||
void tst_qnetworkdiskcache::timeRead()
|
||||
{
|
||||
|
||||
QFETCH(QString, cacheRootDirectory);
|
||||
|
||||
cacheDir = QString( cacheRootDirectory + QDir::separator() + "man_qndc");
|
||||
QDir d;
|
||||
qDebug() << "Setting cache directory to = " << d.absoluteFilePath(cacheDir);
|
||||
|
||||
//Housekeeping
|
||||
cleanRecursive(cacheDir); // slow op.
|
||||
initCacheObject();
|
||||
cache->setCacheDirectory(cacheDir);
|
||||
cache->setMaximumCacheSize(qint64(HugeCacheLimit));
|
||||
cache->clear();
|
||||
|
||||
//populate some fake data to simulate partially full cache
|
||||
injectFakeData();
|
||||
|
||||
//Entries in the cache should be > what we try to remove
|
||||
QVERIFY(NumFakeCacheObjects > NumReadContent);
|
||||
|
||||
//time metadata lookup of previously inserted URL.
|
||||
QBENCHMARK_ONCE {
|
||||
for (quint32 i = 0; i < NumReadContent; i++) {
|
||||
QString fakeURL;
|
||||
QTextStream stream(&fakeURL);
|
||||
stream << fakeURLbase << i;
|
||||
QUrl url(fakeURL);
|
||||
|
||||
QNetworkCacheMetaData qndc = cache->metaData(url);
|
||||
QVERIFY(qndc.isValid()); // we must have read the metadata
|
||||
|
||||
QNetworkCacheMetaData::RawHeaderList raw(qndc.rawHeaders());
|
||||
QVERIFY(raw.size()); // we must have parsed the headers from the meta
|
||||
|
||||
QIODevice *iodevice(cache->data(url));
|
||||
QVERIFY(iodevice); //must not be NULL
|
||||
iodevice->close();
|
||||
delete iodevice;
|
||||
}
|
||||
}
|
||||
|
||||
//Cleanup (slow)
|
||||
cleanupCacheObject();
|
||||
cleanRecursive(cacheDir);
|
||||
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::timeRemoval_data()
|
||||
{
|
||||
QTest::addColumn<QString>("cacheRootDirectory");
|
||||
|
||||
QString cacheLoc = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
QTest::newRow("QStandardPaths Cache Location") << cacheLoc;
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::timeRemoval()
|
||||
{
|
||||
|
||||
QFETCH(QString, cacheRootDirectory);
|
||||
|
||||
cacheDir = QString( cacheRootDirectory + QDir::separator() + "man_qndc");
|
||||
QDir d;
|
||||
qDebug() << "Setting cache directory to = " << d.absoluteFilePath(cacheDir);
|
||||
|
||||
//Housekeeping
|
||||
initCacheObject();
|
||||
cleanRecursive(cacheDir); // slow op.
|
||||
cache->setCacheDirectory(cacheDir);
|
||||
// Make max cache size HUGE, so that evictions don't happen below
|
||||
cache->setMaximumCacheSize(qint64(HugeCacheLimit));
|
||||
cache->clear();
|
||||
|
||||
//populate some fake data to simulate partially full cache
|
||||
injectFakeData();
|
||||
|
||||
//Sanity-check that the URL is already in there somewhere
|
||||
QVERIFY(isUrlCached(NumRemovals-1) == true);
|
||||
//Entries in the cache should be > what we try to remove
|
||||
QVERIFY(NumFakeCacheObjects > NumRemovals);
|
||||
|
||||
//time removal of previously-inserted URL.
|
||||
QBENCHMARK_ONCE {
|
||||
for (quint32 i = 0; i < NumRemovals; i++) {
|
||||
QString fakeURL;
|
||||
QTextStream stream(&fakeURL);
|
||||
stream << fakeURLbase << i;
|
||||
QUrl url(fakeURL);
|
||||
cache->remove(url);
|
||||
}
|
||||
}
|
||||
|
||||
//Cleanup (slow)
|
||||
cleanupCacheObject();
|
||||
cleanRecursive(cacheDir);
|
||||
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::timeExpiration_data()
|
||||
{
|
||||
QTest::addColumn<QString>("cacheRootDirectory");
|
||||
|
||||
QString cacheLoc = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
QTest::newRow("QStandardPaths Cache Location") << cacheLoc;
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::timeExpiration()
|
||||
{
|
||||
|
||||
QFETCH(QString, cacheRootDirectory);
|
||||
|
||||
cacheDir = QString( cacheRootDirectory + QDir::separator() + "man_qndc");
|
||||
QDir d;
|
||||
qDebug() << "Setting cache directory to = " << d.absoluteFilePath(cacheDir);
|
||||
|
||||
//Housekeeping
|
||||
initCacheObject();
|
||||
cleanRecursive(cacheDir); // slow op.
|
||||
cache->setCacheDirectory(cacheDir);
|
||||
// Make max cache size HUGE, so that evictions don't happen below
|
||||
cache->setMaximumCacheSize(qint64(HugeCacheLimit));
|
||||
cache->clear();
|
||||
|
||||
//populate some fake data to simulate partially full cache
|
||||
injectFakeData();
|
||||
|
||||
//Sanity-check that the URL is already in there somewhere
|
||||
QVERIFY(isUrlCached(NumRemovals-1) == true);
|
||||
//Entries in the cache should be > what we try to remove
|
||||
QVERIFY(NumFakeCacheObjects > NumRemovals);
|
||||
|
||||
|
||||
//Set cache limit lower, so this force 1 round of eviction
|
||||
cache->setMaximumCacheSize(qint64(TinyCacheLimit));
|
||||
|
||||
//time insertions of additional content, which is likely to internally cause evictions
|
||||
QBENCHMARK_ONCE {
|
||||
for (quint32 i = NumFakeCacheObjects; i < (NumFakeCacheObjects + NumInsertions); i++) {
|
||||
//prepare metata for url
|
||||
QNetworkCacheMetaData meta;
|
||||
QString fakeURL;
|
||||
QTextStream stream(&fakeURL);
|
||||
stream << fakeURLbase << i;//codescanner::leave
|
||||
QUrl url(fakeURL);
|
||||
meta.setUrl(url);
|
||||
meta.setSaveToDisk(true);
|
||||
|
||||
//commit payload and metadata to disk
|
||||
QIODevice *device = cache->prepare(meta);
|
||||
device->write(payload);
|
||||
cache->insert(device); // this should trigger evictions, if TinyCacheLimit is small enough
|
||||
}
|
||||
}
|
||||
|
||||
//Cleanup (slow)
|
||||
cleanupCacheObject();
|
||||
cleanRecursive(cacheDir);
|
||||
|
||||
}
|
||||
// This function simulates a partially or fully occupied disk cache
|
||||
// like a normal user of a cache might encounter is real-life browsing.
|
||||
// The point of this is to trigger degradation in file-system and media performance
|
||||
// that occur due to the quantity and layout of data.
|
||||
void tst_qnetworkdiskcache::injectFakeData()
|
||||
{
|
||||
|
||||
QNetworkCacheMetaData::RawHeaderList headers;
|
||||
headers.append(qMakePair(QByteArray("X-TestHeader"),QByteArray("HeaderValue")));
|
||||
|
||||
|
||||
//Prep cache dir with fake data using QNetworkDiskCache APIs
|
||||
for (quint32 i = 0; i < NumFakeCacheObjects; i++) {
|
||||
|
||||
//prepare metata for url
|
||||
QNetworkCacheMetaData meta;
|
||||
QString fakeURL;
|
||||
QTextStream stream(&fakeURL);
|
||||
stream << fakeURLbase << i;
|
||||
QUrl url(fakeURL);
|
||||
meta.setUrl(url);
|
||||
meta.setRawHeaders(headers);
|
||||
meta.setSaveToDisk(true);
|
||||
|
||||
//commit payload and metadata to disk
|
||||
QIODevice *device = cache->prepare(meta);
|
||||
device->write(payload);
|
||||
cache->insert(device);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Checks if the fake URL #id is already cached or not.
|
||||
bool tst_qnetworkdiskcache::isUrlCached(quint32 id)
|
||||
{
|
||||
QString str;
|
||||
QTextStream stream(&str);
|
||||
stream << fakeURLbase << id;
|
||||
QUrl url(str);
|
||||
QIODevice *iod = cache->data(url);
|
||||
return ((iod == 0) ? false : true) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Utility function for recursive directory cleanup.
|
||||
void tst_qnetworkdiskcache::cleanRecursive(QString &path)
|
||||
{
|
||||
QDirIterator it(path, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
QFile f(it.next());
|
||||
bool err = f.remove();
|
||||
Q_UNUSED(err);
|
||||
}
|
||||
|
||||
QDirIterator it2(path, QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||
while (it2.hasNext()) {
|
||||
QString s(it2.next());
|
||||
QDir dir(s);
|
||||
dir.rmdir(s);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::cleanupCacheObject()
|
||||
{
|
||||
delete cache;
|
||||
cache = 0;
|
||||
}
|
||||
|
||||
void tst_qnetworkdiskcache::initCacheObject()
|
||||
{
|
||||
|
||||
cache = new QNetworkDiskCache();
|
||||
|
||||
}
|
||||
QTEST_MAIN(tst_qnetworkdiskcache)
|
||||
#include "tst_qnetworkdiskcache.moc"
|
Reference in New Issue
Block a user