tst_QNetworkReply: don't leak on failure in emitErrorForAllReplies()
The old code allocated QSignalSpies on the heap and stored them in a non-owning container, so if one of the many check macros trigger, those objects would be leaked. Ditto QNetworkReplies. The code also used dynamically-sized containers for statically-sized data; a common anti-pattern. Hold the sample QUrls in a C array instead, QSignalSpies in C arrays of std::optional (to delay initialization) and QNetworkReplies in a C array of std::unique_ptr with the existing QScopedPointerDeleteLater deleter. Change-Id: I7305115af15c079abba6d45c5de8db2198ea7a6d Reviewed-by: Juha Vuolle <juha.vuolle@qt.io> (cherry picked from commit 20eba275d836e071c1ad8a5e4d1ef88fc5b23fca) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
0c343c4c85
commit
d272374203
@ -8700,31 +8700,33 @@ void tst_QNetworkReply::ftpAuthentication()
|
|||||||
void tst_QNetworkReply::emitErrorForAllReplies() // QTBUG-36890
|
void tst_QNetworkReply::emitErrorForAllReplies() // QTBUG-36890
|
||||||
{
|
{
|
||||||
// port 100 is not well-known and should be closed
|
// port 100 is not well-known and should be closed
|
||||||
QList<QUrl> urls = QList<QUrl>() << QUrl("http://localhost:100/request1")
|
const QUrl urls[] = {
|
||||||
<< QUrl("http://localhost:100/request2")
|
QUrl("http://localhost:100/request1"),
|
||||||
<< QUrl("http://localhost:100/request3");
|
QUrl("http://localhost:100/request2"),
|
||||||
QList<QNetworkReply *> replies;
|
QUrl("http://localhost:100/request3"),
|
||||||
QList<QSignalSpy *> errorSpies;
|
};
|
||||||
QList<QSignalSpy *> finishedSpies;
|
constexpr auto NUrls = std::size(urls);
|
||||||
for (int a = 0; a < urls.size(); ++a) {
|
|
||||||
QNetworkRequest request(urls.at(a));
|
std::unique_ptr<QNetworkReply, QScopedPointerDeleteLater> replies[NUrls];
|
||||||
|
std::optional<QSignalSpy> errorSpies[NUrls];
|
||||||
|
std::optional<QSignalSpy> finishedSpies[NUrls];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < NUrls; ++i) {
|
||||||
|
QNetworkRequest request(urls[i]);
|
||||||
QNetworkReply *reply = manager.get(request);
|
QNetworkReply *reply = manager.get(request);
|
||||||
replies.append(reply);
|
replies[i].reset(reply);
|
||||||
QSignalSpy *errorSpy = new QSignalSpy(reply, SIGNAL(errorOccurred(QNetworkReply::NetworkError)));
|
errorSpies[i].emplace(reply, SIGNAL(errorOccurred(QNetworkReply::NetworkError)));
|
||||||
errorSpies.append(errorSpy);
|
finishedSpies[i].emplace(reply, SIGNAL(finished()));
|
||||||
QSignalSpy *finishedSpy = new QSignalSpy(reply, SIGNAL(finished()));
|
|
||||||
finishedSpies.append(finishedSpy);
|
|
||||||
QObject::connect(reply, SIGNAL(finished()), SLOT(emitErrorForAllRepliesSlot()));
|
QObject::connect(reply, SIGNAL(finished()), SLOT(emitErrorForAllRepliesSlot()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QTestEventLoop::instance().enterLoop(10);
|
QTestEventLoop::instance().enterLoop(10);
|
||||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||||
for (int a = 0; a < urls.size(); ++a) {
|
|
||||||
QVERIFY(replies.at(a)->isFinished());
|
for (size_t i = 0; i < NUrls; ++i) {
|
||||||
QCOMPARE(errorSpies.at(a)->size(), 1);
|
QVERIFY(replies[i]->isFinished());
|
||||||
delete errorSpies.at(a);
|
QCOMPARE(errorSpies[i]->size(), 1);
|
||||||
QCOMPARE(finishedSpies.at(a)->size(), 1);
|
QCOMPARE(finishedSpies[i]->size(), 1);
|
||||||
delete finishedSpies.at(a);
|
|
||||||
replies.at(a)->deleteLater();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user