diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-01-21 14:51:45 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2011-01-21 14:51:45 (GMT) |
commit | a2ba4ccd2c2d3daf2a4d719295c59395f03aba0b (patch) | |
tree | e0a6304ce350164a1731a62257384a984f593551 /tests/auto/qnetworkreply | |
parent | 6886c21e0743fdfb1e5d053e0e193aeeed5fe8b2 (diff) | |
download | Qt-a2ba4ccd2c2d3daf2a4d719295c59395f03aba0b.zip Qt-a2ba4ccd2c2d3daf2a4d719295c59395f03aba0b.tar.gz Qt-a2ba4ccd2c2d3daf2a4d719295c59395f03aba0b.tar.bz2 |
Fix crashes in httpProxyCommandsSynchronous test case
Due to a race condition, the test could fail before its QThread had even
started, resulting in a crash during thread startup. This is addressed
using a semaphore to synchronise startup & ensure the sub thread is running
before continuing the test.
Additionally, if the test failed the QThread would be destroyed while
still running, which according to the documentation will cause crashes.
This is addressed using QScopedPointer to clean up when the test exits
early due to failure.
Reviewed-by: Markus Goetz
Diffstat (limited to 'tests/auto/qnetworkreply')
-rw-r--r-- | tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index b1fddfa..390d5bf 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -47,6 +47,7 @@ #include <QtCore/QEventLoop> #include <QtCore/QFile> #include <QtCore/QSharedPointer> +#include <QtCore/QScopedPointer> #include <QtCore/QTemporaryFile> #include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket> @@ -410,16 +411,23 @@ public: QTcpSocket *client; // always the last one that was received QByteArray dataToTransmit; QByteArray receivedData; + QSemaphore ready; bool doClose; bool doSsl; bool multiple; int totalConnections; - MiniHttpServer(const QByteArray &data, bool ssl = false) + MiniHttpServer(const QByteArray &data, bool ssl = false, QThread *thread = 0) : client(0), dataToTransmit(data), doClose(true), doSsl(ssl), multiple(false), totalConnections(0) { listen(); + if (thread) { + connect(thread, SIGNAL(started()), this, SLOT(threadStartedSlot())); + moveToThread(thread); + thread->start(); + ready.acquire(); + } } protected: @@ -492,6 +500,11 @@ public slots: } } } + + void threadStartedSlot() + { + ready.release(); + } }; class MyCookieJar: public QNetworkCookieJar @@ -4478,6 +4491,26 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous_data() httpProxyCommands_data(); } +struct QThreadCleanup +{ + static inline void cleanup(QThread *thread) + { + thread->quit(); + if (thread->wait(3000)) + delete thread; + else + qWarning("thread hung, leaking memory so test can finish"); + } +}; + +struct QDeleteLaterCleanup +{ + static inline void cleanup(QObject *o) + { + o->deleteLater(); + } +}; + void tst_QNetworkReply::httpProxyCommandsSynchronous() { QFETCH(QUrl, url); @@ -4487,11 +4520,9 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() // when using synchronous commands, we need a different event loop for // the server thread, because the client is never returning to the // event loop - MiniHttpServer proxyServer(responseToSend); - QThread serverThread; - proxyServer.moveToThread(&serverThread); - serverThread.start(); - QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort()); + QScopedPointer<QThread, QThreadCleanup> serverThread(new QThread); + QScopedPointer<MiniHttpServer, QDeleteLaterCleanup> proxyServer(new MiniHttpServer(responseToSend, false, serverThread.data())); + QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer->serverPort()); manager.setProxy(proxy); QNetworkRequest request(url); @@ -4504,8 +4535,6 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() QNetworkReplyPtr reply = manager.get(request); QVERIFY(reply->isFinished()); // synchronous manager.setProxy(QNetworkProxy()); - serverThread.quit(); - serverThread.wait(3000); //qDebug() << reply->error() << reply->errorString(); @@ -4513,7 +4542,7 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() // especially since it won't succeed in the HTTPS case // so just check that the command was correct - QString receivedHeader = proxyServer.receivedData.left(expectedCommand.length()); + QString receivedHeader = proxyServer->receivedData.left(expectedCommand.length()); QCOMPARE(receivedHeader, expectedCommand); } |