Add tests for the tcp server/client
This commit is contained in:
parent
3fd27905ee
commit
0fd50eb227
3 changed files with 373 additions and 0 deletions
343
tests/unit/service/test_tcp.cpp
Normal file
343
tests/unit/service/test_tcp.cpp
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
#include <QtTest/QtTest>
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include "service/tcpserver.h"
|
||||
#include "service/tcpclient.h"
|
||||
#include "service/server.h"
|
||||
#include "service/service.h"
|
||||
#include "items/item.h"
|
||||
|
||||
class TestTcp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
// Setup for all tests
|
||||
}
|
||||
|
||||
void testTcpServerCreation()
|
||||
{
|
||||
TcpServer server;
|
||||
|
||||
// Server should be created successfully
|
||||
QVERIFY(true);
|
||||
}
|
||||
|
||||
void testTcpServerLaunch()
|
||||
{
|
||||
TcpServer server;
|
||||
|
||||
// Launch server on any address, port 0 means dynamic port
|
||||
bool result = server.launch(QHostAddress::Any, 0);
|
||||
|
||||
QVERIFY(result);
|
||||
|
||||
// Server should be listening after launch
|
||||
QVERIFY(server.isListening());
|
||||
}
|
||||
|
||||
void testTcpServerLaunchSpecificPort()
|
||||
{
|
||||
TcpServer server;
|
||||
|
||||
// Try to launch on a specific port
|
||||
bool result = server.launch(QHostAddress::LocalHost, 0);
|
||||
|
||||
QVERIFY(result);
|
||||
|
||||
// Server should be listening
|
||||
QVERIFY(server.isListening());
|
||||
}
|
||||
|
||||
void testTcpClientCreation()
|
||||
{
|
||||
TcpClient client;
|
||||
|
||||
// Client should be created successfully
|
||||
QVERIFY(true);
|
||||
}
|
||||
|
||||
void testTcpProtocolMessageFormat()
|
||||
{
|
||||
// Test the protocol message format: "MSG JSON LEN <size>\n<json>"
|
||||
QJsonObject json;
|
||||
json["MessageType"] = "TestMessage";
|
||||
json["Data"] = QJsonArray();
|
||||
|
||||
QByteArray jsonData = QJsonDocument(json).toJson();
|
||||
QString message = QString("MSG JSON LEN %1\n").arg(jsonData.size()) + QString::fromUtf8(jsonData);
|
||||
|
||||
// Verify message format
|
||||
QVERIFY(message.startsWith("MSG JSON LEN "));
|
||||
QVERIFY(message.contains("\n"));
|
||||
|
||||
// Parse the message size
|
||||
QStringList parts = message.split("\n");
|
||||
QVERIFY(parts.size() >= 1);
|
||||
|
||||
QString sizeStr = parts[0].mid(13); // Skip "MSG JSON LEN "
|
||||
bool ok;
|
||||
quint64 size = sizeStr.toUInt(&ok);
|
||||
QVERIFY(ok);
|
||||
QVERIFY(size == jsonData.size());
|
||||
}
|
||||
|
||||
void testTcpProtocolParseCommand()
|
||||
{
|
||||
// Test parsing a command from the protocol
|
||||
QByteArray command = "MSG JSON LEN 123\n";
|
||||
|
||||
QVERIFY(command.startsWith("MSG JSON LEN "));
|
||||
|
||||
QByteArray sizeStr = command.mid(13);
|
||||
sizeStr.chop(1); // Remove newline
|
||||
|
||||
bool ok;
|
||||
quint64 size = sizeStr.toLongLong(&ok);
|
||||
QVERIFY(ok);
|
||||
QVERIFY(size == 123);
|
||||
}
|
||||
|
||||
void testTcpServerSendJson()
|
||||
{
|
||||
// Start server
|
||||
TcpServer server;
|
||||
bool serverResult = server.launch(QHostAddress::LocalHost, 0);
|
||||
QVERIFY(serverResult);
|
||||
|
||||
// Connect a client to trigger client list
|
||||
QTcpSocket clientSocket;
|
||||
clientSocket.connectToHost(QHostAddress::LocalHost, server.getServerPort());
|
||||
QVERIFY(clientSocket.waitForConnected(1000));
|
||||
|
||||
// Give server time to accept connection
|
||||
QTest::qWait(200);
|
||||
|
||||
// Send JSON from server
|
||||
QJsonObject json;
|
||||
json["MessageType"] = "TestMessage";
|
||||
json["Data"] = QJsonArray();
|
||||
|
||||
server.sendJson(json);
|
||||
|
||||
// Give more time for data to be sent
|
||||
QTest::qWait(200);
|
||||
|
||||
// Client should receive data (or at least the connection should work)
|
||||
// Note: This may fail due to timing in test environment
|
||||
QVERIFY(clientSocket.state() == QTcpSocket::ConnectedState);
|
||||
|
||||
// Cleanup
|
||||
clientSocket.close();
|
||||
}
|
||||
|
||||
void testTcpServerProcessIncomingJson()
|
||||
{
|
||||
// Start server
|
||||
TcpServer server;
|
||||
bool serverResult = server.launch(QHostAddress::LocalHost, 0);
|
||||
QVERIFY(serverResult);
|
||||
|
||||
// Connect client
|
||||
QTcpSocket clientSocket;
|
||||
clientSocket.connectToHost(QHostAddress::LocalHost, server.getServerPort());
|
||||
QVERIFY(clientSocket.waitForConnected(1000));
|
||||
|
||||
// Give server time to accept connection
|
||||
QTest::qWait(100);
|
||||
|
||||
// Send a message that the server can process
|
||||
QJsonObject json;
|
||||
json["MessageType"] = "GetItems";
|
||||
json["Data"] = QJsonArray();
|
||||
|
||||
QByteArray jsonData = QJsonDocument(json).toJson();
|
||||
QString message = QString("MSG JSON LEN %1\n").arg(jsonData.size()) + QString::fromUtf8(jsonData);
|
||||
|
||||
clientSocket.write(message.toUtf8());
|
||||
clientSocket.flush();
|
||||
|
||||
// Give server time to process
|
||||
QTest::qWait(100);
|
||||
|
||||
// Cleanup
|
||||
clientSocket.close();
|
||||
}
|
||||
|
||||
void testTcpServerMultipleClients()
|
||||
{
|
||||
// Start server
|
||||
TcpServer server;
|
||||
bool serverResult = server.launch(QHostAddress::LocalHost, 0);
|
||||
QVERIFY(serverResult);
|
||||
|
||||
// Connect multiple clients
|
||||
QTcpSocket client1;
|
||||
client1.connectToHost(QHostAddress::LocalHost, server.getServerPort());
|
||||
QVERIFY(client1.waitForConnected(1000));
|
||||
|
||||
QTcpSocket client2;
|
||||
client2.connectToHost(QHostAddress::LocalHost, server.getServerPort());
|
||||
QVERIFY(client2.waitForConnected(1000));
|
||||
|
||||
// Give server time to accept connections
|
||||
QTest::qWait(200);
|
||||
|
||||
// Send message to all clients
|
||||
QJsonObject json;
|
||||
json["MessageType"] = "TestMessage";
|
||||
json["Data"] = QJsonArray();
|
||||
|
||||
server.sendJson(json);
|
||||
|
||||
// Give time for data to be sent
|
||||
QTest::qWait(200);
|
||||
|
||||
// Both clients should be connected (timing may affect actual data receipt)
|
||||
QVERIFY(client1.state() == QTcpSocket::ConnectedState);
|
||||
QVERIFY(client2.state() == QTcpSocket::ConnectedState);
|
||||
|
||||
// Cleanup
|
||||
client1.close();
|
||||
client2.close();
|
||||
}
|
||||
|
||||
void testItemUpdateMessageFormat()
|
||||
{
|
||||
// Test creating an item update message format
|
||||
Item item(1, "test_item", 1);
|
||||
|
||||
QJsonObject itemJson;
|
||||
item.store(itemJson);
|
||||
|
||||
QJsonArray items;
|
||||
items.append(itemJson);
|
||||
|
||||
// Manually create the message (since createMessage is protected)
|
||||
QJsonObject message;
|
||||
message["MessageType"] = "ItemUpdate";
|
||||
message["Data"] = items;
|
||||
message["FullList"] = false;
|
||||
|
||||
QVERIFY(message["MessageType"].toString() == "ItemUpdate");
|
||||
QVERIFY(message["Data"].toArray().size() == 1);
|
||||
QVERIFY(message["FullList"].toBool() == false);
|
||||
}
|
||||
|
||||
void testSensorUpdateMessageFormat()
|
||||
{
|
||||
// Test creating a sensor update message format
|
||||
Sensor sensor(Sensor::TYPE_TEMPERATURE, 1, 25.0, "temp_sensor");
|
||||
|
||||
QJsonObject sensorJson;
|
||||
sensor.store(sensorJson);
|
||||
|
||||
QJsonArray sensors;
|
||||
sensors.append(sensorJson);
|
||||
|
||||
// Manually create the message (since createMessage is protected)
|
||||
QJsonObject message;
|
||||
message["MessageType"] = "SensorUpdate";
|
||||
message["Data"] = sensors;
|
||||
|
||||
QVERIFY(message["MessageType"].toString() == "SensorUpdate");
|
||||
QVERIFY(message["Data"].toArray().size() == 1);
|
||||
}
|
||||
|
||||
void testTcpClientSocketState()
|
||||
{
|
||||
// Test that TcpClient creates a socket
|
||||
TcpClient client;
|
||||
|
||||
// The client should have a valid socket (internal implementation detail)
|
||||
// We can verify the client was created successfully
|
||||
QVERIFY(true);
|
||||
}
|
||||
|
||||
void testTcpServerClientConnection()
|
||||
{
|
||||
// Start server
|
||||
TcpServer server;
|
||||
bool serverResult = server.launch(QHostAddress::LocalHost, 0);
|
||||
QVERIFY(serverResult);
|
||||
|
||||
// Connect a client
|
||||
QTcpSocket clientSocket;
|
||||
clientSocket.connectToHost(QHostAddress::LocalHost, server.getServerPort());
|
||||
|
||||
bool waitResult = clientSocket.waitForConnected(1000);
|
||||
QVERIFY(waitResult);
|
||||
|
||||
// Verify connection state
|
||||
QVERIFY(clientSocket.state() == QTcpSocket::ConnectedState);
|
||||
|
||||
// Cleanup
|
||||
clientSocket.close();
|
||||
}
|
||||
|
||||
void testTcpServerDisconnection()
|
||||
{
|
||||
// Start server
|
||||
TcpServer server;
|
||||
bool serverResult = server.launch(QHostAddress::LocalHost, 0);
|
||||
QVERIFY(serverResult);
|
||||
|
||||
// Connect a client
|
||||
QTcpSocket* client = new QTcpSocket();
|
||||
client->connectToHost(QHostAddress::LocalHost, server.getServerPort());
|
||||
QVERIFY(client->waitForConnected(1000));
|
||||
|
||||
// Give server time to accept connection
|
||||
QTest::qWait(100);
|
||||
|
||||
// Disconnect client
|
||||
client->disconnectFromHost();
|
||||
QTest::qWait(100);
|
||||
|
||||
// Cleanup
|
||||
delete client;
|
||||
}
|
||||
|
||||
void testTcpProtocolLargeMessage()
|
||||
{
|
||||
// Test the protocol with a larger message
|
||||
QJsonObject json;
|
||||
json["MessageType"] = "TestMessage";
|
||||
|
||||
// Create a large data array
|
||||
QJsonArray data;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
data.append(QJsonObject{{"id", i}, {"value", QString("item%1").arg(i)}});
|
||||
}
|
||||
json["Data"] = data;
|
||||
|
||||
QByteArray jsonData = QJsonDocument(json).toJson();
|
||||
QString message = QString("MSG JSON LEN %1\n").arg(jsonData.size()) + QString::fromUtf8(jsonData);
|
||||
|
||||
// Verify message format
|
||||
QVERIFY(message.startsWith("MSG JSON LEN "));
|
||||
|
||||
// Parse the message size
|
||||
QStringList parts = message.split("\n");
|
||||
QString sizeStr = parts[0].mid(13);
|
||||
bool ok;
|
||||
quint64 size = sizeStr.toUInt(&ok);
|
||||
QVERIFY(ok);
|
||||
QVERIFY(size == jsonData.size());
|
||||
}
|
||||
|
||||
void cleanupTestCase()
|
||||
{
|
||||
// Cleanup after all tests
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_APPLESS_MAIN(TestTcp)
|
||||
|
||||
#include "test_tcp.moc"
|
||||
Loading…
Add table
Add a link
Reference in a new issue