Skip to content

Commit

Permalink
Test QNetworkAccessCache insertions with varying expiry times
Browse files Browse the repository at this point in the history
The insertions are sorted by when they expire. So, we test the various
orders to insert entries.

Fixes: QTBUG-95959
Change-Id: I1e8d7f4c77dce5eae3d4bfa5101f296c3eea1961
Reviewed-by: Edward Welbourne <[email protected]>
  • Loading branch information
Morten242 committed Sep 1, 2021
1 parent ca69e5a commit 4757b93
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ private Q_SLOTS:
void httpAbort();

void closeClientSideConnectionEagerlyQtbug20726();
void varyingCacheExpiry_data();
void varyingCacheExpiry();

void dontInsertPartialContentIntoTheCache();

Expand Down Expand Up @@ -7988,6 +7990,110 @@ void tst_QNetworkReply::closeClientSideConnectionEagerlyQtbug20726()
QCOMPARE(serverNotEagerClientClose2.client->state(), QTcpSocket::ConnectedState);
}

void tst_QNetworkReply::varyingCacheExpiry_data()
{
QTest::addColumn<int>("firstExpiry");
QTest::addColumn<int>("secondExpiry");
QTest::addColumn<int>("thirdExpiry");
QTest::addColumn<int>("fourthExpiry");

// The datatags signify the Keep-Alive time-outs of the successive requests:
QTest::newRow("1-2-3-4") << 1 << 2 << 3 << 4;
QTest::newRow("4-1-2-3") << 4 << 1 << 2 << 3;
QTest::newRow("3-4-1-2") << 3 << 4 << 1 << 2;
QTest::newRow("2-3-4-1") << 2 << 3 << 4 << 1;
QTest::newRow("1-2-2-1") << 1 << 2 << 2 << 1;
}

// Test creating a few requests with various expiry timeouts.
// We do this because the internal QNetworkAccessCache inserts them in sorted
// order, so make sure it gets it right.
void tst_QNetworkReply::varyingCacheExpiry()
{
// Local QNAM instance because there may be leftover entries from other
// tests. Which wouldn't be a big deal, it would just get in the way of our
// pattern
QNetworkAccessManager qnam;
QFETCH(int, firstExpiry);
QFETCH(int, secondExpiry);
QFETCH(int, thirdExpiry);
QFETCH(int, fourthExpiry);

int expiryTimes[4] = {
firstExpiry,
secondExpiry,
thirdExpiry,
fourthExpiry,
};

// We need multiple servers because we want to have multiple connections
// in the QNetworkAccessCache, not to just reuse one connection from the
// cache.
MiniHttpServer servers[4] = {
{ httpEmpty200Response },
{ httpEmpty200Response },
{ httpEmpty200Response },
{ httpEmpty200Response },
};
for (MiniHttpServer &server : servers)
server.doClose = false;

QUrl urls[4] = {
u"http://localhost"_qs,
u"http://localhost"_qs,
u"http://localhost"_qs,
u"http://localhost"_qs,
};
for (int i = 0; i < std::size(urls); ++i)
urls[i].setPort(servers[i].serverPort());

// After the initial request is completed the connection is kept alive
// (Keep-Alive). Internally they are added to a sorted linked-list based on
// expiry. So, set the requests to be torn down at varying timeouts.

QNetworkRequest requests[4] = {
QNetworkRequest(urls[0]),
QNetworkRequest(urls[1]),
QNetworkRequest(urls[2]),
QNetworkRequest(urls[3]),
};

for (int i = 0; i < 4; ++i) {
requests[i].setAttribute(QNetworkRequest::Http2AllowedAttribute,
QVariant::fromValue(false));
requests[i].setAttribute(QNetworkRequest::ConnectionCacheExpiryTimeoutSecondsAttribute,
expiryTimes[i]);
}

// The server just uses a normal TCP socket and prints out this error when the client
// disconnects:
for (int i = 0; i < 4; ++i) {
QTest::ignoreMessage(QtDebugMsg,
"slotError QAbstractSocket::RemoteHostClosedError "
"\"The remote host closed the connection\"");
}

// Start each request and wait for it to finish before starting the next
// one, we must do this because the connections are only added to the expiry
// list once finished
for (const auto &request : requests) {
QNetworkReplyPtr reply(qnam.get(request));
QCOMPARE(waitForFinish(reply), Success);
}

int lastExpiry = *std::max_element(std::begin(expiryTimes), std::end(expiryTimes));
auto allServersDisconnected = [&servers]() {
auto socketDisconnected = [](const MiniHttpServer &s) {
return s.client->state() == QAbstractSocket::UnconnectedState;
};
return std::all_of(std::begin(servers), std::end(servers), socketDisconnected);
};
// At least +5 seconds due to CI. Completes much faster locally
bool success = QTest::qWaitFor(allServersDisconnected, lastExpiry * 1000 + 5000);

QVERIFY(success);
}

void tst_QNetworkReply::dontInsertPartialContentIntoTheCache()
{
QByteArray reply206 =
Expand Down

0 comments on commit 4757b93

Please sign in to comment.