Provide a threaded TestHTTPServer
This allows us to do blocking operations that interact with the test server in the main thread. The threaded server is used in tests that don't explicitly require asynchronous operation. Change-Id: Ibcb28e79a1114cb9cfb812e86aae0a1af71c569e Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
parent
9e15fb156a
commit
35da68a15c
|
@ -4203,9 +4203,7 @@ void tst_qqmlecmascript::importScripts()
|
||||||
QFETCH(QStringList, propertyNames);
|
QFETCH(QStringList, propertyNames);
|
||||||
QFETCH(QVariantList, propertyValues);
|
QFETCH(QVariantList, propertyValues);
|
||||||
|
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory() + "/remote");
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory() + "/remote");
|
|
||||||
|
|
||||||
QStringList importPathList = engine.importPathList();
|
QStringList importPathList = engine.importPathList();
|
||||||
|
|
||||||
|
|
|
@ -2543,9 +2543,7 @@ void tst_qqmllanguage::basicRemote()
|
||||||
QFETCH(QString, type);
|
QFETCH(QString, type);
|
||||||
QFETCH(QString, error);
|
QFETCH(QString, error);
|
||||||
|
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
url = server.baseUrl().resolved(url);
|
url = server.baseUrl().resolved(url);
|
||||||
|
|
||||||
|
@ -2590,9 +2588,7 @@ void tst_qqmllanguage::importsRemote()
|
||||||
QFETCH(QString, type);
|
QFETCH(QString, type);
|
||||||
QFETCH(QString, error);
|
QFETCH(QString, error);
|
||||||
|
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
qml.replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString());
|
qml.replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString());
|
||||||
|
|
||||||
|
@ -2685,9 +2681,7 @@ void tst_qqmllanguage::importsInstalledRemote()
|
||||||
QFETCH(QString, type);
|
QFETCH(QString, type);
|
||||||
QFETCH(QString, error);
|
QFETCH(QString, error);
|
||||||
|
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
QString serverdir = server.urlString("/lib/");
|
QString serverdir = server.urlString("/lib/");
|
||||||
engine.setImportPathList(QStringList(defaultImportPathList) << serverdir);
|
engine.setImportPathList(QStringList(defaultImportPathList) << serverdir);
|
||||||
|
@ -2752,9 +2746,7 @@ void tst_qqmllanguage::importsPath()
|
||||||
QFETCH(QString, qml);
|
QFETCH(QString, qml);
|
||||||
QFETCH(QString, value);
|
QFETCH(QString, value);
|
||||||
|
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
for (int i = 0; i < importPath.count(); ++i)
|
for (int i = 0; i < importPath.count(); ++i)
|
||||||
importPath[i].replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString());
|
importPath[i].replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString());
|
||||||
|
@ -3386,9 +3378,7 @@ void tst_qqmllanguage::registeredCompositeTypeWithAttachedProperty()
|
||||||
// QTBUG-18268
|
// QTBUG-18268
|
||||||
void tst_qqmllanguage::remoteLoadCrash()
|
void tst_qqmllanguage::remoteLoadCrash()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
QQmlComponent component(&engine);
|
QQmlComponent component(&engine);
|
||||||
component.setData("import QtQuick 2.0; Text {}", server.url("/remoteLoadCrash.qml"));
|
component.setData("import QtQuick 2.0; Text {}", server.url("/remoteLoadCrash.qml"));
|
||||||
|
@ -3877,9 +3867,7 @@ void tst_qqmllanguage::compositeSingletonQmlDirError()
|
||||||
// Load a remote composite singleton type via qmldir that defines the type as a singleton
|
// Load a remote composite singleton type via qmldir that defines the type as a singleton
|
||||||
void tst_qqmllanguage::compositeSingletonRemote()
|
void tst_qqmllanguage::compositeSingletonRemote()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
QFile f(testFile("singletonTest15.qml"));
|
QFile f(testFile("singletonTest15.qml"));
|
||||||
QVERIFY(f.open(QIODevice::ReadOnly));
|
QVERIFY(f.open(QIODevice::ReadOnly));
|
||||||
|
|
|
@ -239,9 +239,7 @@ void tst_qqmlmoduleplugin::importPluginWithQmlFile()
|
||||||
|
|
||||||
void tst_qqmlmoduleplugin::remoteImportWithQuotedUrl()
|
void tst_qqmlmoduleplugin::remoteImportWithQuotedUrl()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(m_dataImportsDirectory);
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(m_dataImportsDirectory);
|
|
||||||
|
|
||||||
QQmlEngine engine;
|
QQmlEngine engine;
|
||||||
QQmlComponent component(&engine);
|
QQmlComponent component(&engine);
|
||||||
|
|
|
@ -252,9 +252,7 @@ void tst_qquickanimatedimage::remote()
|
||||||
QFETCH(QString, fileName);
|
QFETCH(QString, fileName);
|
||||||
QFETCH(bool, paused);
|
QFETCH(bool, paused);
|
||||||
|
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
QQmlEngine engine;
|
QQmlEngine engine;
|
||||||
QQmlComponent component(&engine, server.url(fileName));
|
QQmlComponent component(&engine, server.url(fileName));
|
||||||
|
|
|
@ -435,9 +435,7 @@ void tst_QQuickLoader::noResize()
|
||||||
|
|
||||||
void tst_QQuickLoader::networkRequestUrl()
|
void tst_QQuickLoader::networkRequestUrl()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
QQmlComponent component(&engine);
|
QQmlComponent component(&engine);
|
||||||
const QString qml = "import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"" + server.baseUrl().toString() + "/Rect120x60.qml\"; onLoaded: signalCount += 1 }";
|
const QString qml = "import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"" + server.baseUrl().toString() + "/Rect120x60.qml\"; onLoaded: signalCount += 1 }";
|
||||||
|
@ -460,9 +458,7 @@ void tst_QQuickLoader::networkRequestUrl()
|
||||||
/* XXX Component waits until all dependencies are loaded. Is this actually possible? */
|
/* XXX Component waits until all dependencies are loaded. Is this actually possible? */
|
||||||
void tst_QQuickLoader::networkComponent()
|
void tst_QQuickLoader::networkComponent()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory(), TestHTTPServer::Delay);
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
|
|
||||||
|
|
||||||
QQmlComponent component(&engine);
|
QQmlComponent component(&engine);
|
||||||
const QString qml = "import QtQuick 2.0\n"
|
const QString qml = "import QtQuick 2.0\n"
|
||||||
|
@ -471,8 +467,9 @@ void tst_QQuickLoader::networkComponent()
|
||||||
" Component { id: comp; NW.Rect120x60 {} }\n"
|
" Component { id: comp; NW.Rect120x60 {} }\n"
|
||||||
" Loader { sourceComponent: comp } }";
|
" Loader { sourceComponent: comp } }";
|
||||||
component.setData(qml.toUtf8(), dataDirectory());
|
component.setData(qml.toUtf8(), dataDirectory());
|
||||||
QCOMPARE(component.status(), QQmlComponent::Loading);
|
// The component may be loaded synchronously or asynchronously, so we cannot test for
|
||||||
server.sendDelayedItem();
|
// status == Loading here. Also, it makes no sense to instruct the server to send here
|
||||||
|
// because in the synchronous case we're already done loading.
|
||||||
QTRY_COMPARE(component.status(), QQmlComponent::Ready);
|
QTRY_COMPARE(component.status(), QQmlComponent::Ready);
|
||||||
|
|
||||||
QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
|
QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
|
||||||
|
@ -492,9 +489,7 @@ void tst_QQuickLoader::networkComponent()
|
||||||
|
|
||||||
void tst_QQuickLoader::failNetworkRequest()
|
void tst_QQuickLoader::failNetworkRequest()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
QTest::ignoreMessage(QtWarningMsg, QString(server.baseUrl().toString() + "/IDontExist.qml: File not found").toUtf8());
|
QTest::ignoreMessage(QtWarningMsg, QString(server.baseUrl().toString() + "/IDontExist.qml: File not found").toUtf8());
|
||||||
|
|
||||||
|
@ -708,9 +703,7 @@ void tst_QQuickLoader::initialPropertyValues()
|
||||||
QFETCH(QStringList, propertyNames);
|
QFETCH(QStringList, propertyNames);
|
||||||
QFETCH(QVariantList, propertyValues);
|
QFETCH(QVariantList, propertyValues);
|
||||||
|
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory());
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory());
|
|
||||||
|
|
||||||
foreach (const QString &warning, expectedWarnings)
|
foreach (const QString &warning, expectedWarnings)
|
||||||
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
|
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
|
||||||
|
|
|
@ -2599,9 +2599,7 @@ void tst_qquicktextedit::cursorDelegate()
|
||||||
|
|
||||||
void tst_qquicktextedit::remoteCursorDelegate()
|
void tst_qquicktextedit::remoteCursorDelegate()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory(), TestHTTPServer::Delay);
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
|
|
||||||
|
|
||||||
QQuickView view;
|
QQuickView view;
|
||||||
|
|
||||||
|
@ -2737,20 +2735,21 @@ void tst_qquicktextedit::delegateLoading()
|
||||||
QFETCH(QString, qmlfile);
|
QFETCH(QString, qmlfile);
|
||||||
QFETCH(QString, error);
|
QFETCH(QString, error);
|
||||||
|
|
||||||
TestHTTPServer server;
|
QHash<QString, TestHTTPServer::Mode> dirs;
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
dirs[testFile("httpfail")] = TestHTTPServer::Disconnect;
|
||||||
server.serveDirectory(testFile("httpfail"), TestHTTPServer::Disconnect);
|
dirs[testFile("httpslow")] = TestHTTPServer::Delay;
|
||||||
server.serveDirectory(testFile("httpslow"), TestHTTPServer::Delay);
|
dirs[testFile("http")] = TestHTTPServer::Normal;
|
||||||
server.serveDirectory(testFile("http"));
|
ThreadedTestHTTPServer server(dirs);
|
||||||
|
|
||||||
error.replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString());
|
error.replace(QStringLiteral("{{ServerBaseUrl}}"), server.baseUrl().toString());
|
||||||
|
|
||||||
|
if (!error.isEmpty())
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
|
||||||
QQuickView view(server.url(qmlfile));
|
QQuickView view(server.url(qmlfile));
|
||||||
view.show();
|
view.show();
|
||||||
view.requestActivate();
|
view.requestActivate();
|
||||||
|
|
||||||
if (!error.isEmpty()) {
|
if (!error.isEmpty()) {
|
||||||
QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
|
|
||||||
QTRY_VERIFY(view.status()==QQuickView::Error);
|
QTRY_VERIFY(view.status()==QQuickView::Error);
|
||||||
QTRY_VERIFY(!view.rootObject()); // there is fail item inside this test
|
QTRY_VERIFY(!view.rootObject()); // there is fail item inside this test
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2857,10 +2857,7 @@ void tst_qquicktextinput::cursorDelegate()
|
||||||
|
|
||||||
void tst_qquicktextinput::remoteCursorDelegate()
|
void tst_qquicktextinput::remoteCursorDelegate()
|
||||||
{
|
{
|
||||||
TestHTTPServer server;
|
ThreadedTestHTTPServer server(dataDirectory(), TestHTTPServer::Delay);
|
||||||
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
|
||||||
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
|
|
||||||
|
|
||||||
QQuickView view;
|
QQuickView view;
|
||||||
|
|
||||||
QQmlComponent component(view.engine(), server.url("/RemoteCursor.qml"));
|
QQmlComponent component(view.engine(), server.url("/RemoteCursor.qml"));
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
|
@ -80,6 +81,16 @@ The following request urls will then result in the appropriate action:
|
||||||
\row \li http://localhost:14445/slowMain.qml \li slowMain.qml returned after 500ms
|
\row \li http://localhost:14445/slowMain.qml \li slowMain.qml returned after 500ms
|
||||||
\endtable
|
\endtable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static QUrl localHostUrl(quint16 port)
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setScheme(QStringLiteral("http"));
|
||||||
|
url.setHost(QStringLiteral("127.0.0.1"));
|
||||||
|
url.setPort(port);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
TestHTTPServer::TestHTTPServer()
|
TestHTTPServer::TestHTTPServer()
|
||||||
: m_state(AwaitingHeader)
|
: m_state(AwaitingHeader)
|
||||||
{
|
{
|
||||||
|
@ -93,11 +104,12 @@ bool TestHTTPServer::listen()
|
||||||
|
|
||||||
QUrl TestHTTPServer::baseUrl() const
|
QUrl TestHTTPServer::baseUrl() const
|
||||||
{
|
{
|
||||||
QUrl url;
|
return localHostUrl(m_server.serverPort());
|
||||||
url.setScheme(QStringLiteral("http"));
|
}
|
||||||
url.setHost(QStringLiteral("127.0.0.1"));
|
|
||||||
url.setPort(m_server.serverPort());
|
quint16 TestHTTPServer::port() const
|
||||||
return url;
|
{
|
||||||
|
return m_server.serverPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl TestHTTPServer::url(const QString &documentPath) const
|
QUrl TestHTTPServer::url(const QString &documentPath) const
|
||||||
|
@ -377,3 +389,60 @@ void TestHTTPServer::serveGET(QTcpSocket *socket, const QByteArray &data)
|
||||||
socket->disconnectFromHost();
|
socket->disconnectFromHost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThreadedTestHTTPServer::ThreadedTestHTTPServer(const QString &dir, TestHTTPServer::Mode mode) :
|
||||||
|
m_port(0)
|
||||||
|
{
|
||||||
|
m_dirs[dir] = mode;
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadedTestHTTPServer::ThreadedTestHTTPServer(const QHash<QString, TestHTTPServer::Mode> &dirs) :
|
||||||
|
m_dirs(dirs), m_port(0)
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadedTestHTTPServer::~ThreadedTestHTTPServer()
|
||||||
|
{
|
||||||
|
quit();
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl ThreadedTestHTTPServer::baseUrl() const
|
||||||
|
{
|
||||||
|
return localHostUrl(m_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl ThreadedTestHTTPServer::url(const QString &documentPath) const
|
||||||
|
{
|
||||||
|
return baseUrl().resolved(documentPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ThreadedTestHTTPServer::urlString(const QString &documentPath) const
|
||||||
|
{
|
||||||
|
return url(documentPath).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadedTestHTTPServer::run()
|
||||||
|
{
|
||||||
|
TestHTTPServer server;
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
QVERIFY2(server.listen(), qPrintable(server.errorString()));
|
||||||
|
m_port = server.port();
|
||||||
|
for (QHash<QString, TestHTTPServer::Mode>::ConstIterator i = m_dirs.constBegin();
|
||||||
|
i != m_dirs.constEnd(); ++i) {
|
||||||
|
server.serveDirectory(i.key(), i.value());
|
||||||
|
}
|
||||||
|
m_condition.wakeAll();
|
||||||
|
}
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadedTestHTTPServer::start()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
QThread::start();
|
||||||
|
m_condition.wait(&m_mutex);
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QWaitCondition>
|
||||||
|
|
||||||
class TestHTTPServer : public QObject
|
class TestHTTPServer : public QObject
|
||||||
{
|
{
|
||||||
|
@ -45,6 +48,7 @@ public:
|
||||||
TestHTTPServer();
|
TestHTTPServer();
|
||||||
|
|
||||||
bool listen();
|
bool listen();
|
||||||
|
quint16 port() const;
|
||||||
QUrl baseUrl() const;
|
QUrl baseUrl() const;
|
||||||
QUrl url(const QString &documentPath) const;
|
QUrl url(const QString &documentPath) const;
|
||||||
QString urlString(const QString &documentPath) const;
|
QString urlString(const QString &documentPath) const;
|
||||||
|
@ -100,5 +104,29 @@ private:
|
||||||
QTcpServer m_server;
|
QTcpServer m_server;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ThreadedTestHTTPServer : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ThreadedTestHTTPServer(const QString &dir, TestHTTPServer::Mode mode = TestHTTPServer::Normal);
|
||||||
|
ThreadedTestHTTPServer(const QHash<QString, TestHTTPServer::Mode> &dirs);
|
||||||
|
~ThreadedTestHTTPServer();
|
||||||
|
|
||||||
|
QUrl baseUrl() const;
|
||||||
|
QUrl url(const QString &documentPath) const;
|
||||||
|
QString urlString(const QString &documentPath) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void start();
|
||||||
|
|
||||||
|
QHash<QString, TestHTTPServer::Mode> m_dirs;
|
||||||
|
quint16 m_port;
|
||||||
|
QMutex m_mutex;
|
||||||
|
QWaitCondition m_condition;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // TESTHTTPSERVER_H
|
#endif // TESTHTTPSERVER_H
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue