Add Network tests (#2304)

Also changes the way timeouts happen, since right now if a timeout was met (which it mostly wasn't), it would run the error callback twice causing potentially undefined behaviour
This commit is contained in:
pajlada
2020-12-26 12:42:39 +01:00
committed by GitHub
parent 2f5df3db4a
commit 0e66b17ff0
15 changed files with 362 additions and 22 deletions
+8
View File
@@ -29,6 +29,14 @@ const Qt::KeyboardModifiers showAddSplitRegions =
Qt::ControlModifier | Qt::AltModifier;
const Qt::KeyboardModifiers showResizeHandlesModifiers = Qt::ControlModifier;
#ifndef ATTR_UNUSED
# ifdef Q_OS_WIN
# define ATTR_UNUSED
# else
# define ATTR_UNUSED __attribute__((unused))
# endif
#endif
static const char *ANONYMOUS_USERNAME_LABEL ATTR_UNUSED = " - anonymous - ";
template <typename T>
+26 -15
View File
@@ -10,23 +10,20 @@
#include <QCryptographicHash>
#include <QFile>
#include <QNetworkReply>
#include <QtConcurrent>
#include "common/QLogging.hpp"
namespace chatterino {
NetworkData::NetworkData()
: timer_(new QTimer())
, lifetimeManager_(new QObject)
: lifetimeManager_(new QObject)
{
timer_->setSingleShot(true);
DebugCount::increase("NetworkData");
}
NetworkData::~NetworkData()
{
this->timer_->deleteLater();
this->lifetimeManager_->deleteLater();
DebugCount::decrease("NetworkData");
@@ -84,13 +81,14 @@ void loadUncached(const std::shared_ptr<NetworkData> &data)
worker->moveToThread(&NetworkManager::workerThread);
if (data->hasTimeout_)
{
data->timer_->setSingleShot(true);
data->timer_->start();
}
auto onUrlRequested = [data, worker]() mutable {
if (data->hasTimeout_)
{
data->timer_ = new QTimer();
data->timer_->setSingleShot(true);
data->timer_->start(data->timeoutMS_);
}
auto reply = [&]() -> QNetworkReply * {
switch (data->requestType_)
{
@@ -128,7 +126,7 @@ void loadUncached(const std::shared_ptr<NetworkData> &data)
return;
}
if (data->timer_->isActive())
if (data->timer_ != nullptr && data->timer_->isActive())
{
QObject::connect(
data->timer_, &QTimer::timeout, worker, [reply, data]() {
@@ -158,11 +156,18 @@ void loadUncached(const std::shared_ptr<NetworkData> &data)
// TODO(pajlada): A reply was received, kill the timeout timer
if (reply->error() != QNetworkReply::NetworkError::NoError)
{
if (reply->error() ==
QNetworkReply::NetworkError::OperationCanceledError)
{
//operation cancelled, most likely timed out
return;
}
if (data->onError_)
{
auto error = reply->error();
postToThread([data, error] {
data->onError_(NetworkResult({}, error));
auto status = reply->attribute(
QNetworkRequest::HttpStatusCodeAttribute);
postToThread([data, code = status.toInt()] {
data->onError_(NetworkResult({}, code));
});
}
return;
@@ -193,6 +198,12 @@ void loadUncached(const std::shared_ptr<NetworkData> &data)
reply->deleteLater();
};
if (data->timer_ != nullptr)
{
QObject::connect(reply, &QNetworkReply::finished, data->timer_,
&QObject::deleteLater);
}
QObject::connect(
reply, &QNetworkReply::finished, worker,
[data, handleReply, worker]() mutable {
+4 -1
View File
@@ -5,7 +5,9 @@
#include <QHttpMultiPart>
#include <QNetworkRequest>
#include <QTimer>
#include <functional>
#include <memory>
class QNetworkReply;
@@ -54,7 +56,8 @@ struct NetworkData {
// to enable the timer, the "setTimeout" function needs to be called before
// execute is called
bool hasTimeout_{};
QTimer *timer_;
int timeoutMS_{};
QTimer *timer_ = nullptr;
QObject *lifetimeManager_;
QString getHash();
+1 -1
View File
@@ -117,7 +117,7 @@ NetworkRequest NetworkRequest::headerList(const QStringList &headers) &&
NetworkRequest NetworkRequest::timeout(int ms) &&
{
this->data->hasTimeout_ = true;
this->data->timer_->setInterval(ms);
this->data->timeoutMS_ = ms;
return std::move(*this);
}
+1
View File
@@ -1,6 +1,7 @@
#pragma once
#include <rapidjson/document.h>
#include <QJsonArray>
#include <QJsonObject>
namespace chatterino {
+1
View File
@@ -8,6 +8,7 @@
#include <QRegularExpression>
#include <QString>
#include <QUuid>
#include <pajlada/serialize.hpp>
#include <memory>
@@ -2,6 +2,10 @@
#include "controllers/filters/parser/Types.hpp"
#include <QMap>
#include <QRegularExpression>
#include <QString>
namespace filterparser {
static const QMap<QString, QString> validIdentifiersMap = {
+8
View File
@@ -5,6 +5,14 @@
namespace chatterino {
#ifndef ATTR_UNUSED
# ifdef Q_OS_WIN
# define ATTR_UNUSED
# else
# define ATTR_UNUSED __attribute__((unused))
# endif
#endif
static const char *ANONYMOUS_USERNAME ATTR_UNUSED = "justinfan64537";
inline QByteArray getDefaultClientID()
+1
View File
@@ -2,6 +2,7 @@
#include "common/NetworkRequest.hpp"
#include <QJsonArray>
#include <QString>
#include <QStringList>
#include <QUrl>
+1
View File
@@ -1,5 +1,6 @@
#pragma once
#include <QApplication>
#include <QObject>
#include <type_traits>