1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// SPDX-FileCopyrightText: 2022 Daniel Vrátil <dvratil@kde.org>
//
// SPDX-License-Identifier: MIT
#include "websockets/qcorowebsocketserver.h"
#include "websockets/qcorowebsocket.h"
#include "testobject.h"
#include <QWebSocketServer>
#include <QWebSocket>
#include <QTest>
class QCoroWebSocketServerTest : public QCoro::TestObject<QCoroWebSocketServerTest> {
Q_OBJECT
public:
QCoroWebSocketServerTest(QObject *parent = nullptr)
: QCoro::TestObject<QCoroWebSocketServerTest>(parent)
{
// On Windows, constructing QWebSocket for the first time takes some time
// (most likely due to loading OpenSSL), which causes the first test to
// time out on the CI.
QWebSocket socket;
}
private:
QCoro::Task<> testNextPendingConnection_coro(QCoro::TestContext) {
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
QCORO_VERIFY(server.listen(QHostAddress::LocalHost));
QWebSocket socket;
QCORO_DELAY(socket.open(server.serverUrl()));
const auto serverSocket = std::unique_ptr<QWebSocket>(co_await qCoro(server).nextPendingConnection());
QCORO_VERIFY(serverSocket != nullptr);
}
void testThenNextPendingConnection_coro(TestLoop &el) {
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
QVERIFY(server.listen(QHostAddress::LocalHost));
QWebSocket socket;
QCORO_DELAY(socket.open(server.serverUrl()));
bool called = false;
qCoro(server).nextPendingConnection().then([&el, &called](QWebSocket *socket) {
el.quit();
called = true;
QVERIFY(socket != nullptr);
socket->deleteLater();
});
el.exec();
QVERIFY(called);
}
QCoro::Task<> testNextPendingConnectionTimeout_coro(QCoro::TestContext) {
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
QCORO_VERIFY(server.listen(QHostAddress::LocalHost));
const auto *socket = co_await qCoro(server).nextPendingConnection(10ms);
QCORO_COMPARE(socket, nullptr);
}
void testThenNextPendingConnectionTimeout_coro(TestLoop &el) {
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
QVERIFY(server.listen(QHostAddress::LocalHost));
bool called = false;
qCoro(server).nextPendingConnection(100ms).then([&el, &called](QWebSocket *socket) {
el.quit();
called = true;
QCOMPARE(socket, nullptr);
});
el.exec();
QVERIFY(called);
}
QCoro::Task<> testClosingServerResumesAwaiters_coro(QCoro::TestContext) {
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
QCORO_VERIFY(server.listen(QHostAddress::LocalHost));
QCORO_DELAY(server.close());
auto *socket = co_await qCoro(server).nextPendingConnection();
QCORO_COMPARE(socket, nullptr);
}
void testThenClosingServerResumesAwaiters_coro(TestLoop &el) {
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
QVERIFY(server.listen(QHostAddress::LocalHost));
QCORO_DELAY(server.close());
bool called = false;
qCoro(server).nextPendingConnection().then([&el, &called](QWebSocket *socket) {
el.quit();
called = true;
QCOMPARE(socket, nullptr);
});
el.exec();
QVERIFY(called);
}
QCoro::Task<> testDoesntCoawaitNonlisteningServer_coro(QCoro::TestContext ctx) {
ctx.setShouldNotSuspend();
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
const auto *socket = co_await qCoro(server).nextPendingConnection();
QCORO_COMPARE(socket, nullptr);
}
QCoro::Task<> testDoesntCoawaitWithPendingConnection_coro(QCoro::TestContext ctx) {
ctx.setShouldNotSuspend();
QWebSocketServer server(QStringLiteral("TestWSServer"), QWebSocketServer::NonSecureMode);
QCORO_VERIFY(server.listen(QHostAddress::LocalHost));
QWebSocket socket;
QCORO_VERIFY(QCoro::waitFor(qCoro(socket).open(server.serverUrl())));
QCORO_COMPARE(socket.state(), QAbstractSocket::ConnectedState);
QTest::qWait(100); // give the server time to register the incoming connection
QCORO_VERIFY(server.hasPendingConnections());
const auto serverSocket = std::unique_ptr<QWebSocket>(co_await qCoro(server).nextPendingConnection());
QCORO_VERIFY(serverSocket);
}
private Q_SLOTS:
addCoroAndThenTests(NextPendingConnection)
addCoroAndThenTests(NextPendingConnectionTimeout)
addCoroAndThenTests(ClosingServerResumesAwaiters)
addTest(DoesntCoawaitNonlisteningServer)
addTest(DoesntCoawaitWithPendingConnection)
};
QTEST_GUILESS_MAIN(QCoroWebSocketServerTest)
#include "qcorowebsocketserver.moc"
|