autotests fixes
tests / package-smoke-linux (push) Skipped
tests / package-smoke-windows (push) Skipped
tests / macos (push) Successful in 1m22s
tests / linux (pull_request) Successful in 1m54s
tests / package-smoke-macos (push) Skipped
tests / linux (push) Successful in 2m43s
tests / windows (push) Successful in 4m13s
tests / windows (pull_request) Skipped
tests / macos (pull_request) Skipped
tests / package-smoke-linux (pull_request) Skipped
tests / package-smoke-windows (pull_request) Skipped
tests / package-smoke-macos (pull_request) Skipped
tests / package-smoke-linux (push) Skipped
tests / package-smoke-windows (push) Skipped
tests / macos (push) Successful in 1m22s
tests / linux (pull_request) Successful in 1m54s
tests / package-smoke-macos (push) Skipped
tests / linux (push) Successful in 2m43s
tests / windows (push) Successful in 4m13s
tests / windows (pull_request) Skipped
tests / macos (pull_request) Skipped
tests / package-smoke-linux (pull_request) Skipped
tests / package-smoke-windows (pull_request) Skipped
tests / package-smoke-macos (pull_request) Skipped
Signed-off-by: galeon <dertiellis@gmail.com>
This commit is contained in:
1 parent
6a2b596f32
commit
5635dcc558
11 files changed
+134
-52
No files matched your search
@@ -201,12 +201,32 @@ void FakeInternet::unroute(const QString &pattern)
|
||||
|
||||
void FakeInternet::reset()
|
||||
{
|
||||
m_deferred.clear();
|
||||
m_diagnostics.clear();
|
||||
m_routes.clear();
|
||||
m_requests.clear();
|
||||
m_unmatched.clear();
|
||||
m_fallback = FakeResponse::error(404, "fake internet: no route");
|
||||
}
|
||||
|
||||
bool FakeInternet::releaseResponse(const QString &url)
|
||||
{
|
||||
for (qsizetype i = 0; i < m_deferred.size(); ++i) {
|
||||
if (m_deferred.at(i).url == url) {
|
||||
const auto pending = m_deferred.takeAt(i);
|
||||
respond(pending.socket, pending.response, pending.keepAlive);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString FakeInternet::diagnostics() const
|
||||
{
|
||||
return QStringLiteral("TLS backend: %1\nRequests: %2\n%3")
|
||||
.arg(QSslSocket::activeBackend(), requestedUrls().join(u' '), m_diagnostics.join(u'\n'));
|
||||
}
|
||||
|
||||
QList<FakeRequest> FakeInternet::requests() const
|
||||
{
|
||||
return m_requests;
|
||||
@@ -366,9 +386,13 @@ void FakeInternet::dispatch(Connection *connection, FakeRequest request)
|
||||
}
|
||||
|
||||
const bool keepAlive = request.header("connection").toLower() != "close";
|
||||
QPointer<QTcpSocket> socket(connection->socket);
|
||||
QPointer<QSslSocket> socket(connection->socket);
|
||||
if (response.hang)
|
||||
return;
|
||||
if (response.deferred) {
|
||||
m_deferred.append({url, socket, response, keepAlive});
|
||||
return;
|
||||
}
|
||||
if (response.delayMs > 0) {
|
||||
QTimer::singleShot(response.delayMs, this,
|
||||
[this, socket, response, keepAlive] { respond(socket, response, keepAlive); });
|
||||
@@ -378,7 +402,7 @@ void FakeInternet::dispatch(Connection *connection, FakeRequest request)
|
||||
emit requestServed(url);
|
||||
}
|
||||
|
||||
void FakeInternet::respond(QPointer<QTcpSocket> socket, const FakeResponse &response, bool keepAlive)
|
||||
void FakeInternet::respond(QPointer<QSslSocket> socket, const FakeResponse &response, bool keepAlive)
|
||||
{
|
||||
if (!socket || socket->state() != QAbstractSocket::ConnectedState)
|
||||
return;
|
||||
@@ -397,20 +421,28 @@ void FakeInternet::respond(QPointer<QTcpSocket> socket, const FakeResponse &resp
|
||||
head += close ? "Connection: close\r\n" : "Connection: keep-alive\r\n";
|
||||
head += "\r\n";
|
||||
|
||||
socket->write(head);
|
||||
if (response.truncateTo >= 0) {
|
||||
socket->write(response.body.left(response.truncateTo));
|
||||
socket->flush();
|
||||
socket->disconnectFromHost();
|
||||
// Schannel (Windows) на disconnectFromHost шлёт только TLS close_notify и держит
|
||||
// TCP открытым, ожидая ответного close_notify, — клиент тогда висит до таймаута.
|
||||
// Обрыв на то и обрыв: если сокет не закрылся сам, рвём соединение.
|
||||
QTimer::singleShot(200, socket, [socket] {
|
||||
if (socket && socket->state() != QAbstractSocket::UnconnectedState)
|
||||
m_diagnostics << QStringLiteral("truncate: declared=%1, sent=%2")
|
||||
.arg(response.body.size()).arg(response.body.left(response.truncateTo).size());
|
||||
// Сначала отправляем TLS-записи с неполным телом, затем рвём TCP.
|
||||
// disconnectFromHost() выполняет штатное завершение TLS, а здесь
|
||||
// моделируется обрыв. Готовность определяется буферами, не задержкой.
|
||||
connect(socket, &QSslSocket::encryptedBytesWritten, socket, [this, socket](qint64) {
|
||||
QTimer::singleShot(0, socket, [this, socket] {
|
||||
if (!socket || socket->state() != QAbstractSocket::ConnectedState)
|
||||
return;
|
||||
if (socket->bytesToWrite() || socket->encryptedBytesToWrite())
|
||||
return;
|
||||
m_diagnostics << QStringLiteral("truncate: TLS buffers drained, aborting TCP");
|
||||
socket->abort();
|
||||
m_diagnostics << QStringLiteral("truncate: state after abort=%1").arg(socket->state());
|
||||
});
|
||||
});
|
||||
socket->write(head);
|
||||
socket->write(response.body.left(response.truncateTo));
|
||||
return;
|
||||
}
|
||||
socket->write(head);
|
||||
socket->write(response.body);
|
||||
if (close)
|
||||
socket->disconnectFromHost();
|
||||
|
||||
@@ -56,6 +56,7 @@ struct FakeResponse
|
||||
QList<QPair<QByteArray, QByteArray>> headers;
|
||||
int delayMs = 0; // ответить с задержкой
|
||||
bool hang = false; // не отвечать вовсе (для отмены и таймаутов)
|
||||
bool deferred = false; // ждать явного releaseResponse(), без таймера
|
||||
bool drop = false; // оборвать соединение без ответа
|
||||
int truncateTo = -1; // объявить полный размер, отдать столько байт и оборвать
|
||||
|
||||
@@ -95,6 +96,8 @@ public:
|
||||
|
||||
// Сбросить маршруты и журнал.
|
||||
void reset();
|
||||
bool releaseResponse(const QString &url);
|
||||
QString diagnostics() const;
|
||||
|
||||
QList<FakeRequest> requests() const;
|
||||
// Сколько раз был запрошен адрес "https://host/path" (query не учитывается).
|
||||
@@ -122,7 +125,7 @@ private:
|
||||
void onReadyRead(Connection *connection);
|
||||
void processBuffer(Connection *connection);
|
||||
void dispatch(Connection *connection, FakeRequest request);
|
||||
void respond(QPointer<QTcpSocket> socket, const FakeResponse &response, bool keepAlive);
|
||||
void respond(QPointer<QSslSocket> socket, const FakeResponse &response, bool keepAlive);
|
||||
void startTls(Connection *connection);
|
||||
const Route *match(const FakeRequest &request) const;
|
||||
|
||||
@@ -130,6 +133,15 @@ private:
|
||||
FakeResponse m_fallback;
|
||||
QList<FakeRequest> m_requests;
|
||||
QStringList m_unmatched;
|
||||
struct DeferredResponse
|
||||
{
|
||||
QString url;
|
||||
QPointer<QSslSocket> socket;
|
||||
FakeResponse response;
|
||||
bool keepAlive;
|
||||
};
|
||||
QList<DeferredResponse> m_deferred;
|
||||
QStringList m_diagnostics;
|
||||
QByteArray m_certificate;
|
||||
QByteArray m_key;
|
||||
bool m_started = false;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <QtTest/QTest>
|
||||
|
||||
// В initTestCase(): поднять FakeInternet или пропустить весь тест-класс.
|
||||
// С BILAUNCHER_REQUIRE_FAKE_INTERNET=1 (так в CI на Linux) недоступность —
|
||||
// С BILAUNCHER_REQUIRE_FAKE_INTERNET=1 (так в CI на всех ОС) недоступность —
|
||||
// ошибка, а не пропуск: иначе сломанный перехват тихо выключил бы все сетевые тесты.
|
||||
#define BILAUNCHER_START_FAKE_INTERNET(net) \
|
||||
do { \
|
||||
|
||||
Reference in new issue
Block a user