summaryrefslogtreecommitdiff
path: root/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp')
-rw-r--r--tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp390
1 files changed, 390 insertions, 0 deletions
diff --git a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
new file mode 100644
index 0000000..c2ba842
--- /dev/null
+++ b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Kurt Pattyn <pattyn.kurt@gmail.com>.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QString>
+#include <QtTest>
+#include <QNetworkProxy>
+#include <QtWebSockets/QWebSocketServer>
+#include <QtWebSockets/QWebSocket>
+#include <QtWebSockets/QWebSocketCorsAuthenticator>
+#include <QtWebSockets/qwebsocketprotocol.h>
+
+QT_USE_NAMESPACE
+
+Q_DECLARE_METATYPE(QWebSocketProtocol::Version)
+Q_DECLARE_METATYPE(QWebSocketProtocol::CloseCode)
+Q_DECLARE_METATYPE(QWebSocketServer::SslMode)
+Q_DECLARE_METATYPE(QWebSocketCorsAuthenticator *)
+#ifndef QT_NO_SSL
+Q_DECLARE_METATYPE(QSslError)
+#endif
+
+class tst_QWebSocketServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWebSocketServer();
+
+private Q_SLOTS:
+ void init();
+ void initTestCase();
+ void cleanupTestCase();
+ void tst_initialisation();
+ void tst_settersAndGetters();
+ void tst_listening();
+ void tst_connectivity();
+ void tst_maxPendingConnections();
+ void tst_serverDestroyedWhileSocketConnected();
+};
+
+tst_QWebSocketServer::tst_QWebSocketServer()
+{
+}
+
+void tst_QWebSocketServer::init()
+{
+ qRegisterMetaType<QWebSocketProtocol::Version>("QWebSocketProtocol::Version");
+ qRegisterMetaType<QWebSocketProtocol::CloseCode>("QWebSocketProtocol::CloseCode");
+ qRegisterMetaType<QWebSocketServer::SslMode>("QWebSocketServer::SslMode");
+ qRegisterMetaType<QWebSocketCorsAuthenticator *>("QWebSocketCorsAuthenticator *");
+#ifndef QT_NO_SSL
+ qRegisterMetaType<QSslError>("QSslError");
+#endif
+}
+
+void tst_QWebSocketServer::initTestCase()
+{
+}
+
+void tst_QWebSocketServer::cleanupTestCase()
+{
+}
+
+void tst_QWebSocketServer::tst_initialisation()
+{
+ {
+ QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
+
+ QVERIFY(server.serverName().isEmpty());
+ QCOMPARE(server.secureMode(), QWebSocketServer::NonSecureMode);
+ QVERIFY(!server.isListening());
+ QCOMPARE(server.maxPendingConnections(), 30);
+ QCOMPARE(server.serverPort(), quint16(0));
+ QCOMPARE(server.serverAddress(), QHostAddress());
+ QCOMPARE(server.socketDescriptor(), -1);
+ QVERIFY(!server.hasPendingConnections());
+ QVERIFY(!server.nextPendingConnection());
+ QCOMPARE(server.error(), QWebSocketProtocol::CloseCodeNormal);
+ QVERIFY(server.errorString().isEmpty());
+ #ifndef QT_NO_NETWORKPROXY
+ QCOMPARE(server.proxy().type(), QNetworkProxy::DefaultProxy);
+ #endif
+ #ifndef QT_NO_SSL
+ QCOMPARE(server.sslConfiguration(), QSslConfiguration::defaultConfiguration());
+ #endif
+ QCOMPARE(server.supportedVersions().count(), 1);
+ QCOMPARE(server.supportedVersions().at(0), QWebSocketProtocol::VersionLatest);
+ QCOMPARE(server.supportedVersions().at(0), QWebSocketProtocol::Version13);
+
+ server.close();
+ //closing a server should not affect any of the parameters
+ //certainly if the server was not opened before
+
+ QVERIFY(server.serverName().isEmpty());
+ QCOMPARE(server.secureMode(), QWebSocketServer::NonSecureMode);
+ QVERIFY(!server.isListening());
+ QCOMPARE(server.maxPendingConnections(), 30);
+ QCOMPARE(server.serverPort(), quint16(0));
+ QCOMPARE(server.serverAddress(), QHostAddress());
+ QCOMPARE(server.socketDescriptor(), -1);
+ QVERIFY(!server.hasPendingConnections());
+ QVERIFY(!server.nextPendingConnection());
+ QCOMPARE(server.error(), QWebSocketProtocol::CloseCodeNormal);
+ QVERIFY(server.errorString().isEmpty());
+ #ifndef QT_NO_NETWORKPROXY
+ QCOMPARE(server.proxy().type(), QNetworkProxy::DefaultProxy);
+ #endif
+ #ifndef QT_NO_SSL
+ QCOMPARE(server.sslConfiguration(), QSslConfiguration::defaultConfiguration());
+ #endif
+ QCOMPARE(server.supportedVersions().count(), 1);
+ QCOMPARE(server.supportedVersions().at(0), QWebSocketProtocol::VersionLatest);
+ QCOMPARE(server.supportedVersions().at(0), QWebSocketProtocol::Version13);
+ QCOMPARE(server.serverUrl(), QUrl());
+ }
+
+ {
+#ifndef QT_NO_SSL
+ QWebSocketServer sslServer(QString(), QWebSocketServer::SecureMode);
+ QCOMPARE(sslServer.secureMode(), QWebSocketServer::SecureMode);
+#endif
+ }
+}
+
+void tst_QWebSocketServer::tst_settersAndGetters()
+{
+ QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
+
+ server.setMaxPendingConnections(23);
+ QCOMPARE(server.maxPendingConnections(), 23);
+ server.setMaxPendingConnections(INT_MIN);
+ QCOMPARE(server.maxPendingConnections(), INT_MIN);
+ server.setMaxPendingConnections(INT_MAX);
+ QCOMPARE(server.maxPendingConnections(), INT_MAX);
+
+ QVERIFY(!server.setSocketDescriptor(-2));
+ QCOMPARE(server.socketDescriptor(), -1);
+
+ server.setServerName(QStringLiteral("Qt WebSocketServer"));
+ QCOMPARE(server.serverName(), QStringLiteral("Qt WebSocketServer"));
+
+#ifndef QT_NO_NETWORKPROXY
+ QNetworkProxy proxy(QNetworkProxy::Socks5Proxy);
+ server.setProxy(proxy);
+ QCOMPARE(server.proxy(), proxy);
+#endif
+#ifndef QT_NO_SSL
+ //cannot set an ssl configuration on a non secure server
+ QSslConfiguration sslConfiguration = QSslConfiguration::defaultConfiguration();
+ sslConfiguration.setPeerVerifyDepth(sslConfiguration.peerVerifyDepth() + 1);
+ server.setSslConfiguration(sslConfiguration);
+ QVERIFY(server.sslConfiguration() != sslConfiguration);
+ QCOMPARE(server.sslConfiguration(), QSslConfiguration::defaultConfiguration());
+
+ QWebSocketServer sslServer(QString(), QWebSocketServer::SecureMode);
+ sslServer.setSslConfiguration(sslConfiguration);
+ QCOMPARE(sslServer.sslConfiguration(), sslConfiguration);
+ QVERIFY(sslServer.sslConfiguration() != QSslConfiguration::defaultConfiguration());
+#endif
+}
+
+void tst_QWebSocketServer::tst_listening()
+{
+ //These listening tests are not too extensive, as the implementation of QWebSocketServer
+ //relies on QTcpServer
+
+ QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
+
+ QSignalSpy serverAcceptErrorSpy(&server, SIGNAL(acceptError(QAbstractSocket::SocketError)));
+ QSignalSpy serverConnectionSpy(&server, SIGNAL(newConnection()));
+ QSignalSpy serverErrorSpy(&server,
+ SIGNAL(serverError(QWebSocketProtocol::CloseCode)));
+ QSignalSpy corsAuthenticationSpy(&server,
+ SIGNAL(originAuthenticationRequired(QWebSocketCorsAuthenticator*)));
+ QSignalSpy serverClosedSpy(&server, SIGNAL(closed()));
+#ifndef QT_NO_SSL
+ QSignalSpy peerVerifyErrorSpy(&server, SIGNAL(peerVerifyError(QSslError)));
+ QSignalSpy sslErrorsSpy(&server, SIGNAL(sslErrors(QList<QSslError>)));
+#endif
+
+ QVERIFY(server.listen()); //listen on all network interface, choose an appropriate port
+ QVERIFY(server.isListening());
+ QCOMPARE(serverClosedSpy.count(), 0);
+ server.close();
+ QVERIFY(serverClosedSpy.wait(1000));
+ QVERIFY(!server.isListening());
+ QCOMPARE(serverErrorSpy.count(), 0);
+
+ QVERIFY(!server.listen(QHostAddress(QStringLiteral("1.2.3.4")), 0));
+ QCOMPARE(server.error(), QWebSocketProtocol::CloseCodeAbnormalDisconnection);
+ QCOMPARE(server.errorString().toLatin1().constData(), "The address is not available");
+ QVERIFY(!server.isListening());
+
+ QCOMPARE(serverAcceptErrorSpy.count(), 0);
+ QCOMPARE(serverConnectionSpy.count(), 0);
+ QCOMPARE(corsAuthenticationSpy.count(), 0);
+#ifndef QT_NO_SSL
+ QCOMPARE(peerVerifyErrorSpy.count(), 0);
+ QCOMPARE(sslErrorsSpy.count(), 0);
+#endif
+ QCOMPARE(serverErrorSpy.count(), 1);
+ QCOMPARE(serverClosedSpy.count(), 1);
+}
+
+void tst_QWebSocketServer::tst_connectivity()
+{
+ QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
+ QSignalSpy serverConnectionSpy(&server, SIGNAL(newConnection()));
+ QSignalSpy serverErrorSpy(&server,
+ SIGNAL(serverError(QWebSocketProtocol::CloseCode)));
+ QSignalSpy corsAuthenticationSpy(&server,
+ SIGNAL(originAuthenticationRequired(QWebSocketCorsAuthenticator*)));
+ QSignalSpy serverClosedSpy(&server, SIGNAL(closed()));
+#ifndef QT_NO_SSL
+ QSignalSpy peerVerifyErrorSpy(&server, SIGNAL(peerVerifyError(QSslError)));
+ QSignalSpy sslErrorsSpy(&server, SIGNAL(sslErrors(QList<QSslError>)));
+#endif
+ QWebSocket socket;
+ QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected()));
+
+ QVERIFY(server.listen());
+ QCOMPARE(server.serverAddress(), QHostAddress(QHostAddress::Any));
+ QCOMPARE(server.serverUrl(), QUrl(QStringLiteral("ws://") + QHostAddress(QHostAddress::LocalHost).toString() +
+ QStringLiteral(":").append(QString::number(server.serverPort()))));
+
+ socket.open(server.serverUrl().toString());
+
+ if (socketConnectedSpy.count() == 0)
+ QVERIFY(socketConnectedSpy.wait());
+ QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
+ QCOMPARE(serverConnectionSpy.count(), 1);
+ QCOMPARE(corsAuthenticationSpy.count(), 1);
+
+ QCOMPARE(serverClosedSpy.count(), 0);
+
+ server.close();
+
+ QVERIFY(serverClosedSpy.wait());
+ QCOMPARE(serverClosedSpy.count(), 1);
+#ifndef QT_NO_SSL
+ QCOMPARE(peerVerifyErrorSpy.count(), 0);
+ QCOMPARE(sslErrorsSpy.count(), 0);
+#endif
+ QCOMPARE(serverErrorSpy.count(), 0);
+}
+
+void tst_QWebSocketServer::tst_maxPendingConnections()
+{
+ //tests if maximum connections are respected
+ //also checks if there are no side-effects like signals that are unexpectedly thrown
+ QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
+ server.setMaxPendingConnections(2);
+ QSignalSpy serverConnectionSpy(&server, SIGNAL(newConnection()));
+ QSignalSpy serverErrorSpy(&server,
+ SIGNAL(serverError(QWebSocketProtocol::CloseCode)));
+ QSignalSpy corsAuthenticationSpy(&server,
+ SIGNAL(originAuthenticationRequired(QWebSocketCorsAuthenticator*)));
+ QSignalSpy serverClosedSpy(&server, SIGNAL(closed()));
+#ifndef QT_NO_SSL
+ QSignalSpy peerVerifyErrorSpy(&server, SIGNAL(peerVerifyError(QSslError)));
+ QSignalSpy sslErrorsSpy(&server, SIGNAL(sslErrors(QList<QSslError>)));
+#endif
+ QSignalSpy serverAcceptErrorSpy(&server, SIGNAL(acceptError(QAbstractSocket::SocketError)));
+
+ QWebSocket socket1;
+ QWebSocket socket2;
+ QWebSocket socket3;
+
+ QSignalSpy socket1ConnectedSpy(&socket1, SIGNAL(connected()));
+ QSignalSpy socket2ConnectedSpy(&socket2, SIGNAL(connected()));
+ QSignalSpy socket3ConnectedSpy(&socket3, SIGNAL(connected()));
+
+ QVERIFY(server.listen());
+
+ socket1.open(server.serverUrl().toString());
+
+ if (socket1ConnectedSpy.count() == 0)
+ QVERIFY(socket1ConnectedSpy.wait());
+ QCOMPARE(socket1.state(), QAbstractSocket::ConnectedState);
+ QCOMPARE(serverConnectionSpy.count(), 1);
+ QCOMPARE(corsAuthenticationSpy.count(), 1);
+ socket2.open(server.serverUrl().toString());
+ if (socket2ConnectedSpy.count() == 0)
+ QVERIFY(socket2ConnectedSpy.wait());
+ QCOMPARE(socket2.state(), QAbstractSocket::ConnectedState);
+ QCOMPARE(serverConnectionSpy.count(), 2);
+ QCOMPARE(corsAuthenticationSpy.count(), 2);
+ socket3.open(server.serverUrl().toString());
+ if (socket3ConnectedSpy.count() == 0)
+ QVERIFY(!socket3ConnectedSpy.wait(250));
+ QCOMPARE(socket3.state(), QAbstractSocket::UnconnectedState);
+ QCOMPARE(serverConnectionSpy.count(), 2);
+ QCOMPARE(corsAuthenticationSpy.count(), 2);
+
+ QVERIFY(server.hasPendingConnections());
+ QWebSocket *pSocket = server.nextPendingConnection();
+ QVERIFY(pSocket);
+ delete pSocket;
+ QVERIFY(server.hasPendingConnections());
+ pSocket = server.nextPendingConnection();
+ QVERIFY(pSocket);
+ delete pSocket;
+ QVERIFY(!server.hasPendingConnections());
+ QVERIFY(!server.nextPendingConnection());
+
+//will resolve in another commit
+#ifndef Q_OS_WIN
+ QCOMPARE(serverErrorSpy.count(), 1);
+ QCOMPARE(serverErrorSpy.at(0).at(0).value<QWebSocketProtocol::CloseCode>(),
+ QWebSocketProtocol::CloseCodeAbnormalDisconnection);
+#endif
+ QCOMPARE(serverClosedSpy.count(), 0);
+
+ server.close();
+
+ QVERIFY(serverClosedSpy.wait());
+ QCOMPARE(serverClosedSpy.count(), 1);
+#ifndef QT_NO_SSL
+ QCOMPARE(peerVerifyErrorSpy.count(), 0);
+ QCOMPARE(sslErrorsSpy.count(), 0);
+#endif
+ QCOMPARE(serverAcceptErrorSpy.count(), 0);
+}
+
+void tst_QWebSocketServer::tst_serverDestroyedWhileSocketConnected()
+{
+ QWebSocketServer * server = new QWebSocketServer(QString(), QWebSocketServer::NonSecureMode);
+ QSignalSpy serverConnectionSpy(server, SIGNAL(newConnection()));
+ QSignalSpy corsAuthenticationSpy(server,
+ SIGNAL(originAuthenticationRequired(QWebSocketCorsAuthenticator*)));
+ QSignalSpy serverClosedSpy(server, SIGNAL(closed()));
+
+ QWebSocket socket;
+ QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected()));
+ QSignalSpy socketDisconnectedSpy(&socket, SIGNAL(disconnected()));
+
+ QVERIFY(server->listen());
+ QCOMPARE(server->serverAddress(), QHostAddress(QHostAddress::Any));
+ QCOMPARE(server->serverUrl(), QUrl(QStringLiteral("ws://") + QHostAddress(QHostAddress::LocalHost).toString() +
+ QStringLiteral(":").append(QString::number(server->serverPort()))));
+
+ socket.open(server->serverUrl().toString());
+
+ if (socketConnectedSpy.count() == 0)
+ QVERIFY(socketConnectedSpy.wait());
+ QCOMPARE(socket.state(), QAbstractSocket::ConnectedState);
+ QCOMPARE(serverConnectionSpy.count(), 1);
+ QCOMPARE(corsAuthenticationSpy.count(), 1);
+
+ QCOMPARE(serverClosedSpy.count(), 0);
+
+ delete server;
+
+ if (socketDisconnectedSpy.count() == 0)
+ QVERIFY(socketDisconnectedSpy.wait());
+ QCOMPARE(socketDisconnectedSpy.count(), 1);
+}
+
+QTEST_MAIN(tst_QWebSocketServer)
+
+#include "tst_qwebsocketserver.moc"