/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. ** ** $QT_BEGIN_LICENSE:LGPL$ ** 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 Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/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 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include "../../auto/qconnectivitytestcommon.h" #include #include #include QTM_USE_NAMESPACE Q_DECLARE_METATYPE(QLlcpSocket::SocketState) Q_DECLARE_METATYPE(QLlcpSocket::SocketError) class tst_QLlcpServer : public QObject { Q_OBJECT public: enum ServerConnectionShutdown { ServerDisconnect, ServerClose, ClientDisconnect, ClientClose }; tst_QLlcpServer(); ~tst_QLlcpServer(); private slots: void tst_construction(); void tst_serverConnection_data(); void tst_serverConnection(); }; Q_DECLARE_METATYPE(tst_QLlcpServer::ServerConnectionShutdown) tst_QLlcpServer::tst_QLlcpServer() { qRegisterMetaType("QLlcpSocket::SocketState"); qRegisterMetaType("QLlcpSocket::SocketError"); } tst_QLlcpServer::~tst_QLlcpServer() { } void tst_QLlcpServer::tst_construction() { QLlcpServer server; QVERIFY(!server.isListening()); QVERIFY(server.serviceUri().isEmpty()); QCOMPARE(server.serverPort(), quint8(0)); QVERIFY(!server.hasPendingConnections()); QVERIFY(!server.nextPendingConnection()); QCOMPARE(server.serverError(), QLlcpSocket::UnknownSocketError); } void tst_QLlcpServer::tst_serverConnection_data() { QTest::addColumn("shutdown"); QTest::addColumn("stream"); QTest::newRow("server disconnect stream") << ServerDisconnect << true; QTest::newRow("server disconnect datagram") << ServerDisconnect << false; QTest::newRow("server close stream") << ServerClose << true; QTest::newRow("server close datagram") << ServerClose << false; QTest::newRow("client disconnect stream") << ClientDisconnect << true; QTest::newRow("client disconnect datagram") << ClientDisconnect << false; QTest::newRow("client close stream") << ClientClose << true; QTest::newRow("client close datagram") << ClientClose << false; } void tst_QLlcpServer::tst_serverConnection() { QFETCH(ServerConnectionShutdown, shutdown); QFETCH(bool, stream); QString service = QLatin1String("urn:nfc:sn:com.nokia.qtmobility.helloserver") + (stream ? QLatin1String(".stream") : QLatin1String(".datagram")); /* Construction */ QLlcpServer *server = new QLlcpServer; QSignalSpy newConnectionSpy(server, SIGNAL(newConnection())); QVERIFY(server->listen(service)); QVERIFY(server->isListening()); QCOMPARE(server->serviceUri(), service); QTRY_VERIFY_TIMEOUT(30000, !newConnectionSpy.isEmpty()); QVERIFY(server->hasPendingConnections()); QLlcpSocket *socket = server->nextPendingConnection(); QVERIFY(socket); QCOMPARE(socket->state(), QLlcpSocket::ConnectedState); QVERIFY(socket->isOpen()); QSignalSpy readyReadSpy(socket, SIGNAL(readyRead())); QSignalSpy disconnectedSpy(socket, SIGNAL(disconnected())); QSignalSpy stateSpy(socket, SIGNAL(stateChanged(QLlcpSocket::SocketState))); QSignalSpy errorSpy(socket, SIGNAL(error(QLlcpSocket::SocketError))); QTRY_VERIFY(!readyReadSpy.isEmpty()); readyReadSpy.clear(); /* Read Hello */ if (stream) { const QByteArray line = socket->readLine().trimmed(); QVERIFY(!line.isEmpty()); QList fields = line.split(' '); QCOMPARE(fields.count(), 2); QCOMPARE(fields.at(0), QByteArray("HELLO")); QCOMPARE(QString::fromUtf8(fields.at(1).constData()), service); } else { QVERIFY(socket->hasPendingDatagrams()); qint64 size = socket->pendingDatagramSize(); QVERIFY(size > 0); QByteArray data; data.resize(size); QCOMPARE(size, socket->readDatagram(data.data(), data.size())); QList fields = data.split(' '); QCOMPARE(fields.count(), 2); QCOMPARE(fields.at(0), QByteArray("HELLO")); QCOMPARE(QString::fromUtf8(fields.at(1).constData()), service); } disconnectedSpy.clear(); /* Write shutdown */ switch (shutdown) { case ServerDisconnect: socket->disconnectFromService(); break; case ServerClose: socket->close(); break; case ClientDisconnect: if (stream) socket->write("DISCONNECT\n"); else socket->writeDatagram("DISCONNECT", 10); break; case ClientClose: if (stream) socket->write("CLOSE\n"); else socket->writeDatagram("CLOSE", 5); break; } /* Verify shutdown */ { QTRY_VERIFY(!disconnectedSpy.isEmpty()); QCOMPARE(disconnectedSpy.count(), 1); QCOMPARE(stateSpy.count(), 2); QCOMPARE(stateSpy.takeFirst().at(0).value(), QLlcpSocket::ClosingState); QCOMPARE(stateSpy.takeFirst().at(0).value(), QLlcpSocket::UnconnectedState); QVERIFY(!socket->isOpen()); if (shutdown == ClientDisconnect || shutdown == ClientClose) { QTRY_VERIFY(!errorSpy.isEmpty()); QCOMPARE(errorSpy.count(), 1); QCOMPARE(errorSpy.takeFirst().at(0).value(), QLlcpSocket::RemoteHostClosedError); QCOMPARE(socket->error(), QLlcpSocket::RemoteHostClosedError); } } delete socket; server->close(); QVERIFY(!server->isListening()); delete server; } QTEST_MAIN(tst_QLlcpServer) #include "tst_qllcpserver.moc"