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 <edward.welbourne@qt.io>
This commit is contained in:
parent
1d8c9978fa
commit
334f09b585
@ -46,6 +46,7 @@
|
|||||||
#endif // NO_SSL
|
#endif // NO_SSL
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "emulationdetector.h"
|
#include "emulationdetector.h"
|
||||||
@ -116,7 +117,7 @@ private:
|
|||||||
|
|
||||||
quint16 serverPort = 0;
|
quint16 serverPort = 0;
|
||||||
QThread *workerThread = nullptr;
|
QThread *workerThread = nullptr;
|
||||||
QNetworkAccessManager manager;
|
std::unique_ptr<QNetworkAccessManager> manager;
|
||||||
|
|
||||||
QTestEventLoop eventLoop;
|
QTestEventLoop eventLoop;
|
||||||
|
|
||||||
@ -130,6 +131,10 @@ private:
|
|||||||
static const Http2::RawSettings defaultServerSettings;
|
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}};
|
const Http2::RawSettings tst_Http2::defaultServerSettings{{Http2::Settings::MAX_CONCURRENT_STREAMS_ID, 100}};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -177,7 +182,7 @@ tst_Http2::~tst_Http2()
|
|||||||
|
|
||||||
void tst_Http2::init()
|
void tst_Http2::init()
|
||||||
{
|
{
|
||||||
manager.clearConnectionCache();
|
manager.reset(new QNetworkAccessManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_Http2::singleRequest_data()
|
void tst_Http2::singleRequest_data()
|
||||||
@ -234,13 +239,14 @@ void tst_Http2::singleRequest()
|
|||||||
QFETCH(const QNetworkRequest::Attribute, h2Attribute);
|
QFETCH(const QNetworkRequest::Attribute, h2Attribute);
|
||||||
request.setAttribute(h2Attribute, QVariant(true));
|
request.setAttribute(h2Attribute, QVariant(true));
|
||||||
|
|
||||||
auto reply = manager.get(request);
|
auto reply = manager->get(request);
|
||||||
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
||||||
// Since we're using self-signed certificates,
|
// Since we're using self-signed certificates,
|
||||||
// ignore SSL errors:
|
// ignore SSL errors:
|
||||||
reply->ignoreSslErrors();
|
reply->ignoreSslErrors();
|
||||||
|
|
||||||
runEventLoop();
|
runEventLoop();
|
||||||
|
STOP_ON_FAILURE
|
||||||
|
|
||||||
QVERIFY(nRequests == 0);
|
QVERIFY(nRequests == 0);
|
||||||
QVERIFY(prefaceOK);
|
QVERIFY(prefaceOK);
|
||||||
@ -276,6 +282,7 @@ void tst_Http2::multipleRequests()
|
|||||||
sendRequest(i, priorities[QRandomGenerator::global()->bounded(3)]);
|
sendRequest(i, priorities[QRandomGenerator::global()->bounded(3)]);
|
||||||
|
|
||||||
runEventLoop();
|
runEventLoop();
|
||||||
|
STOP_ON_FAILURE
|
||||||
|
|
||||||
QVERIFY(nRequests == 0);
|
QVERIFY(nRequests == 0);
|
||||||
QVERIFY(prefaceOK);
|
QVERIFY(prefaceOK);
|
||||||
@ -305,7 +312,7 @@ void tst_Http2::flowControlClientSide()
|
|||||||
params.maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize * 5;
|
params.maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize * 5;
|
||||||
params.settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID] = Http2::defaultSessionWindowSize;
|
params.settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID] = Http2::defaultSessionWindowSize;
|
||||||
// Inform our manager about non-default settings:
|
// 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)}};
|
const Http2::RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, quint32(3)}};
|
||||||
ServerPtr srv(newServer(serverSettings, defaultConnectionType(), params));
|
ServerPtr srv(newServer(serverSettings, defaultConnectionType(), params));
|
||||||
@ -323,6 +330,7 @@ void tst_Http2::flowControlClientSide()
|
|||||||
sendRequest(i);
|
sendRequest(i);
|
||||||
|
|
||||||
runEventLoop(120000);
|
runEventLoop(120000);
|
||||||
|
STOP_ON_FAILURE
|
||||||
|
|
||||||
QVERIFY(nRequests == 0);
|
QVERIFY(nRequests == 0);
|
||||||
QVERIFY(prefaceOK);
|
QVERIFY(prefaceOK);
|
||||||
@ -363,6 +371,7 @@ void tst_Http2::flowControlServerSide()
|
|||||||
sendRequest(i, QNetworkRequest::NormalPriority, payload);
|
sendRequest(i, QNetworkRequest::NormalPriority, payload);
|
||||||
|
|
||||||
runEventLoop(120000);
|
runEventLoop(120000);
|
||||||
|
STOP_ON_FAILURE
|
||||||
|
|
||||||
QVERIFY(nRequests == 0);
|
QVERIFY(nRequests == 0);
|
||||||
QVERIFY(prefaceOK);
|
QVERIFY(prefaceOK);
|
||||||
@ -383,7 +392,7 @@ void tst_Http2::pushPromise()
|
|||||||
Http2::ProtocolParameters params;
|
Http2::ProtocolParameters params;
|
||||||
// Defaults are good, except ENABLE_PUSH:
|
// Defaults are good, except ENABLE_PUSH:
|
||||||
params.settingsFrameData[Settings::ENABLE_PUSH_ID] = 1;
|
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));
|
ServerPtr srv(newServer(defaultServerSettings, defaultConnectionType(), params));
|
||||||
srv->enablePushPromise(true, QByteArray("/script.js"));
|
srv->enablePushPromise(true, QByteArray("/script.js"));
|
||||||
@ -399,12 +408,13 @@ void tst_Http2::pushPromise()
|
|||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
|
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
|
||||||
|
|
||||||
auto reply = manager.get(request);
|
auto reply = manager->get(request);
|
||||||
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
||||||
// Since we're using self-signed certificates, ignore SSL errors:
|
// Since we're using self-signed certificates, ignore SSL errors:
|
||||||
reply->ignoreSslErrors();
|
reply->ignoreSslErrors();
|
||||||
|
|
||||||
runEventLoop();
|
runEventLoop();
|
||||||
|
STOP_ON_FAILURE
|
||||||
|
|
||||||
QVERIFY(nRequests == 0);
|
QVERIFY(nRequests == 0);
|
||||||
QVERIFY(prefaceOK);
|
QVERIFY(prefaceOK);
|
||||||
@ -422,7 +432,7 @@ void tst_Http2::pushPromise()
|
|||||||
url.setPath("/script.js");
|
url.setPath("/script.js");
|
||||||
QNetworkRequest promisedRequest(url);
|
QNetworkRequest promisedRequest(url);
|
||||||
promisedRequest.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
|
promisedRequest.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
|
||||||
reply = manager.get(promisedRequest);
|
reply = manager->get(promisedRequest);
|
||||||
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
||||||
reply->ignoreSslErrors();
|
reply->ignoreSslErrors();
|
||||||
|
|
||||||
@ -473,7 +483,7 @@ void tst_Http2::goaway()
|
|||||||
url.setPath(QString("/%1").arg(i));
|
url.setPath(QString("/%1").arg(i));
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
|
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
|
||||||
replies[i] = manager.get(request);
|
replies[i] = manager->get(request);
|
||||||
QCOMPARE(replies[i]->error(), QNetworkReply::NoError);
|
QCOMPARE(replies[i]->error(), QNetworkReply::NoError);
|
||||||
void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) =
|
void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) =
|
||||||
&QNetworkReply::error;
|
&QNetworkReply::error;
|
||||||
@ -483,6 +493,7 @@ void tst_Http2::goaway()
|
|||||||
}
|
}
|
||||||
|
|
||||||
runEventLoop(5000 + responseTimeoutMS);
|
runEventLoop(5000 + responseTimeoutMS);
|
||||||
|
STOP_ON_FAILURE
|
||||||
|
|
||||||
// No request processed, no 'replyFinished' slot calls:
|
// No request processed, no 'replyFinished' slot calls:
|
||||||
QCOMPARE(nRequests, 0);
|
QCOMPARE(nRequests, 0);
|
||||||
@ -526,6 +537,7 @@ void tst_Http2::earlyResponse()
|
|||||||
sendRequest(1, QNetworkRequest::NormalPriority, {1000000, Qt::Uninitialized});
|
sendRequest(1, QNetworkRequest::NormalPriority, {1000000, Qt::Uninitialized});
|
||||||
|
|
||||||
runEventLoop();
|
runEventLoop();
|
||||||
|
STOP_ON_FAILURE
|
||||||
|
|
||||||
QVERIFY(nRequests == 0);
|
QVERIFY(nRequests == 0);
|
||||||
QVERIFY(prefaceOK);
|
QVERIFY(prefaceOK);
|
||||||
@ -543,7 +555,7 @@ void tst_Http2::clearHTTP2State()
|
|||||||
windowUpdates = 0;
|
windowUpdates = 0;
|
||||||
prefaceOK = false;
|
prefaceOK = false;
|
||||||
serverGotSettingsACK = false;
|
serverGotSettingsACK = false;
|
||||||
manager.setProperty(Http2::http2ParametersPropertyName, QVariant());
|
manager->setProperty(Http2::http2ParametersPropertyName, QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_Http2::runEventLoop(int ms)
|
void tst_Http2::runEventLoop(int ms)
|
||||||
@ -596,9 +608,9 @@ void tst_Http2::sendRequest(int streamNumber,
|
|||||||
|
|
||||||
QNetworkReply *reply = nullptr;
|
QNetworkReply *reply = nullptr;
|
||||||
if (payload.size())
|
if (payload.size())
|
||||||
reply = manager.post(request, payload);
|
reply = manager->post(request, payload);
|
||||||
else
|
else
|
||||||
reply = manager.get(request);
|
reply = manager->get(request);
|
||||||
|
|
||||||
reply->ignoreSslErrors();
|
reply->ignoreSslErrors();
|
||||||
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
|
||||||
@ -690,14 +702,29 @@ void tst_Http2::replyFinished()
|
|||||||
QVERIFY(nRequests);
|
QVERIFY(nRequests);
|
||||||
|
|
||||||
if (const auto reply = qobject_cast<QNetworkReply *>(sender())) {
|
if (const auto reply = qobject_cast<QNetworkReply *>(sender())) {
|
||||||
|
if (reply->error() != QNetworkReply::NoError)
|
||||||
|
stopEventLoop();
|
||||||
|
|
||||||
QCOMPARE(reply->error(), QNetworkReply::NoError);
|
QCOMPARE(reply->error(), QNetworkReply::NoError);
|
||||||
|
|
||||||
const QVariant http2Used(reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute));
|
const QVariant http2Used(reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute));
|
||||||
|
if (!http2Used.isValid() || !http2Used.toBool())
|
||||||
|
stopEventLoop();
|
||||||
|
|
||||||
QVERIFY(http2Used.isValid());
|
QVERIFY(http2Used.isValid());
|
||||||
QVERIFY(http2Used.toBool());
|
QVERIFY(http2Used.toBool());
|
||||||
|
|
||||||
const QVariant spdyUsed(reply->attribute(QNetworkRequest::SpdyWasUsedAttribute));
|
const QVariant spdyUsed(reply->attribute(QNetworkRequest::SpdyWasUsedAttribute));
|
||||||
|
if (!spdyUsed.isValid() || spdyUsed.toBool())
|
||||||
|
stopEventLoop();
|
||||||
|
|
||||||
QVERIFY(spdyUsed.isValid());
|
QVERIFY(spdyUsed.isValid());
|
||||||
QVERIFY(!spdyUsed.toBool());
|
QVERIFY(!spdyUsed.toBool());
|
||||||
|
|
||||||
const QVariant code(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute));
|
const QVariant code(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute));
|
||||||
|
if (!code.isValid() || !code.canConvert<int>() || code.value<int>() != 200)
|
||||||
|
stopEventLoop();
|
||||||
|
|
||||||
QVERIFY(code.isValid());
|
QVERIFY(code.isValid());
|
||||||
QVERIFY(code.canConvert<int>());
|
QVERIFY(code.canConvert<int>());
|
||||||
QCOMPARE(code.value<int>(), 200);
|
QCOMPARE(code.value<int>(), 200);
|
||||||
@ -715,6 +742,8 @@ void tst_Http2::replyFinishedWithError()
|
|||||||
if (const auto reply = qobject_cast<QNetworkReply *>(sender())) {
|
if (const auto reply = qobject_cast<QNetworkReply *>(sender())) {
|
||||||
// For now this is a 'generic' code, it just verifies some error was
|
// For now this is a 'generic' code, it just verifies some error was
|
||||||
// reported without testing its type.
|
// reported without testing its type.
|
||||||
|
if (reply->error() == QNetworkReply::NoError)
|
||||||
|
stopEventLoop();
|
||||||
QVERIFY(reply->error() != QNetworkReply::NoError);
|
QVERIFY(reply->error() != QNetworkReply::NoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user