From 334f09b585b9a90bc3dde0fcda4ebec67478d7a3 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 16 Jul 2019 12:27:34 +0200 Subject: tst_http2 - make the test less rough in general 1. Use per-case QNAM objects 2. In a slots (connected to QNetworkReplies) - if an error detected - stop the event loop (no reason to continue waiting) and then do normal QVERIFY/QCOMPARE things. 3. In tests, check QTest::currentTestFailed after the event loop returned - if an error was detected by a slot, no need to continue with QCOMPARE/QVERIFY in the test itself. Task-number: QTBUG-77053 Change-Id: I3827a629a2749becd3dc6eee7fd6994d96441e65 Reviewed-by: Edward Welbourne --- tests/auto/network/access/http2/tst_http2.cpp | 51 +++++++++++++++++++++------ 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 579eb89c0a..f7d74e66b2 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -46,6 +46,7 @@ #endif // NO_SSL #include +#include #include #include "emulationdetector.h" @@ -116,7 +117,7 @@ private: quint16 serverPort = 0; QThread *workerThread = nullptr; - QNetworkAccessManager manager; + std::unique_ptr manager; QTestEventLoop eventLoop; @@ -130,6 +131,10 @@ private: static const Http2::RawSettings defaultServerSettings; }; +#define STOP_ON_FAILURE \ + if (QTest::currentTestFailed()) \ + return; + const Http2::RawSettings tst_Http2::defaultServerSettings{{Http2::Settings::MAX_CONCURRENT_STREAMS_ID, 100}}; namespace { @@ -177,7 +182,7 @@ tst_Http2::~tst_Http2() void tst_Http2::init() { - manager.clearConnectionCache(); + manager.reset(new QNetworkAccessManager); } void tst_Http2::singleRequest_data() @@ -234,13 +239,14 @@ void tst_Http2::singleRequest() QFETCH(const QNetworkRequest::Attribute, h2Attribute); request.setAttribute(h2Attribute, QVariant(true)); - auto reply = manager.get(request); + auto reply = manager->get(request); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); // Since we're using self-signed certificates, // ignore SSL errors: reply->ignoreSslErrors(); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -276,6 +282,7 @@ void tst_Http2::multipleRequests() sendRequest(i, priorities[QRandomGenerator::global()->bounded(3)]); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -305,7 +312,7 @@ void tst_Http2::flowControlClientSide() params.maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize * 5; params.settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID] = Http2::defaultSessionWindowSize; // Inform our manager about non-default settings: - manager.setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); + manager->setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); const Http2::RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, quint32(3)}}; ServerPtr srv(newServer(serverSettings, defaultConnectionType(), params)); @@ -323,6 +330,7 @@ void tst_Http2::flowControlClientSide() sendRequest(i); runEventLoop(120000); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -363,6 +371,7 @@ void tst_Http2::flowControlServerSide() sendRequest(i, QNetworkRequest::NormalPriority, payload); runEventLoop(120000); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -383,7 +392,7 @@ void tst_Http2::pushPromise() Http2::ProtocolParameters params; // Defaults are good, except ENABLE_PUSH: params.settingsFrameData[Settings::ENABLE_PUSH_ID] = 1; - manager.setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); + manager->setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); ServerPtr srv(newServer(defaultServerSettings, defaultConnectionType(), params)); srv->enablePushPromise(true, QByteArray("/script.js")); @@ -399,12 +408,13 @@ void tst_Http2::pushPromise() QNetworkRequest request(url); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true)); - auto reply = manager.get(request); + auto reply = manager->get(request); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); // Since we're using self-signed certificates, ignore SSL errors: reply->ignoreSslErrors(); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -422,7 +432,7 @@ void tst_Http2::pushPromise() url.setPath("/script.js"); QNetworkRequest promisedRequest(url); promisedRequest.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true)); - reply = manager.get(promisedRequest); + reply = manager->get(promisedRequest); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); reply->ignoreSslErrors(); @@ -473,7 +483,7 @@ void tst_Http2::goaway() url.setPath(QString("/%1").arg(i)); QNetworkRequest request(url); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true)); - replies[i] = manager.get(request); + replies[i] = manager->get(request); QCOMPARE(replies[i]->error(), QNetworkReply::NoError); void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) = &QNetworkReply::error; @@ -483,6 +493,7 @@ void tst_Http2::goaway() } runEventLoop(5000 + responseTimeoutMS); + STOP_ON_FAILURE // No request processed, no 'replyFinished' slot calls: QCOMPARE(nRequests, 0); @@ -526,6 +537,7 @@ void tst_Http2::earlyResponse() sendRequest(1, QNetworkRequest::NormalPriority, {1000000, Qt::Uninitialized}); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -543,7 +555,7 @@ void tst_Http2::clearHTTP2State() windowUpdates = 0; prefaceOK = false; serverGotSettingsACK = false; - manager.setProperty(Http2::http2ParametersPropertyName, QVariant()); + manager->setProperty(Http2::http2ParametersPropertyName, QVariant()); } void tst_Http2::runEventLoop(int ms) @@ -596,9 +608,9 @@ void tst_Http2::sendRequest(int streamNumber, QNetworkReply *reply = nullptr; if (payload.size()) - reply = manager.post(request, payload); + reply = manager->post(request, payload); else - reply = manager.get(request); + reply = manager->get(request); reply->ignoreSslErrors(); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); @@ -690,14 +702,29 @@ void tst_Http2::replyFinished() QVERIFY(nRequests); if (const auto reply = qobject_cast(sender())) { + if (reply->error() != QNetworkReply::NoError) + stopEventLoop(); + QCOMPARE(reply->error(), QNetworkReply::NoError); + const QVariant http2Used(reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute)); + if (!http2Used.isValid() || !http2Used.toBool()) + stopEventLoop(); + QVERIFY(http2Used.isValid()); QVERIFY(http2Used.toBool()); + const QVariant spdyUsed(reply->attribute(QNetworkRequest::SpdyWasUsedAttribute)); + if (!spdyUsed.isValid() || spdyUsed.toBool()) + stopEventLoop(); + QVERIFY(spdyUsed.isValid()); QVERIFY(!spdyUsed.toBool()); + const QVariant code(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)); + if (!code.isValid() || !code.canConvert() || code.value() != 200) + stopEventLoop(); + QVERIFY(code.isValid()); QVERIFY(code.canConvert()); QCOMPARE(code.value(), 200); @@ -715,6 +742,8 @@ void tst_Http2::replyFinishedWithError() if (const auto reply = qobject_cast(sender())) { // For now this is a 'generic' code, it just verifies some error was // reported without testing its type. + if (reply->error() == QNetworkReply::NoError) + stopEventLoop(); QVERIFY(reply->error() != QNetworkReply::NoError); } -- cgit v1.2.3