213 líneas
7 KiB
MQL5
213 líneas
7 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| UnitTests.mq5 |
|
|
//| Unit Tests for Package sockets |
|
|
//| Organization: douglasrechia |
|
|
//+------------------------------------------------------------------+
|
|
#include "../knitpkg/build/BuildInfo.mqh"
|
|
|
|
#property copyright "Douglas Rechia"
|
|
#property link "https://knitpkg.dev"
|
|
#property description ""
|
|
#property description "Version: " + MANIFEST_VERSION
|
|
#property description ""
|
|
#property description "Description: Unit tests for package sockets"
|
|
#property description "Organization: douglasrechia"
|
|
#property description "Author: Douglas Rechia"
|
|
#property description "License: MIT"
|
|
#property description ""
|
|
#property description "Powered by KnitPkg for MetaTrader"
|
|
#property description "https://knitpkg.dev"
|
|
|
|
// Include the headers under test
|
|
#include "../knitpkg/include/douglasrechia/sockets/Sockets.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| TestSocketBasicFunctionality |
|
|
//| Tests basic socket functionality in single-threaded environment |
|
|
//| Strategy: Create server, then client connects to it in same |
|
|
//| thread using non-blocking sockets |
|
|
//+------------------------------------------------------------------+
|
|
bool TestSocketBasicFunctionality()
|
|
{
|
|
const ushort TEST_PORT = 9999;
|
|
const string TEST_MESSAGE = "Hello Socket";
|
|
const string MESSAGE_SEPARATOR = "\n";
|
|
|
|
// Step 1: Create server socket
|
|
douglasrechia::ServerSocket* server = new douglasrechia::ServerSocket(TEST_PORT);
|
|
if(!server.Created())
|
|
{
|
|
Print("Failed to create server: ", server.GetLastError());
|
|
delete server;
|
|
return false;
|
|
}
|
|
Print("Server created successfully on port ", TEST_PORT);
|
|
|
|
// Step 2: Create client socket and connect to localhost
|
|
douglasrechia::ClientSocket* client = new douglasrechia::ClientSocket("127.0.0.1", TEST_PORT);
|
|
if(!client.IsSocketConnected())
|
|
{
|
|
Print("Failed to connect client: ", client.GetLastError());
|
|
delete client;
|
|
delete server;
|
|
return false;
|
|
}
|
|
Print("Client connected successfully");
|
|
|
|
// Step 3: Server accepts the connection (non-blocking, may need retries)
|
|
douglasrechia::ClientSocket* acceptedClient = NULL;
|
|
int acceptRetries = 0;
|
|
while(acceptedClient == NULL && acceptRetries < 100)
|
|
{
|
|
acceptedClient = server.Accept();
|
|
if(acceptedClient == NULL)
|
|
{
|
|
Sleep(10);
|
|
acceptRetries++;
|
|
}
|
|
}
|
|
|
|
if(acceptedClient == NULL)
|
|
{
|
|
Print("Server failed to accept connection: ", server.GetLastError());
|
|
delete client;
|
|
delete server;
|
|
return false;
|
|
}
|
|
Print("Server accepted client connection");
|
|
|
|
// Step 4: Client sends message
|
|
string messageToSend = TEST_MESSAGE + MESSAGE_SEPARATOR;
|
|
if(!client.Send(messageToSend))
|
|
{
|
|
Print("Client failed to send message: ", client.GetLastError());
|
|
delete acceptedClient;
|
|
delete client;
|
|
delete server;
|
|
return false;
|
|
}
|
|
Print("Client sent message: '", TEST_MESSAGE, "'");
|
|
|
|
// Step 5: Server receives message (non-blocking, may need retries)
|
|
string receivedMessage = "";
|
|
int receiveRetries = 0;
|
|
while(receivedMessage == "" && receiveRetries < 100)
|
|
{
|
|
receivedMessage = acceptedClient.Receive(MESSAGE_SEPARATOR);
|
|
if(receivedMessage == "")
|
|
{
|
|
Sleep(10);
|
|
receiveRetries++;
|
|
}
|
|
}
|
|
|
|
if(receivedMessage == "")
|
|
{
|
|
Print("Server failed to receive message: ", acceptedClient.GetLastError());
|
|
delete acceptedClient;
|
|
delete client;
|
|
delete server;
|
|
return false;
|
|
}
|
|
Print("Server received message: '", receivedMessage, "'");
|
|
|
|
// Step 6: Verify message content
|
|
bool messageMatches = (receivedMessage == TEST_MESSAGE);
|
|
if(!messageMatches)
|
|
{
|
|
Print("Message mismatch! Expected: '", TEST_MESSAGE, "', Got: '", receivedMessage, "'");
|
|
}
|
|
|
|
// Step 7: Test echo back - server sends response
|
|
string echoMessage = "Echo: " + receivedMessage + MESSAGE_SEPARATOR;
|
|
if(!acceptedClient.Send(echoMessage))
|
|
{
|
|
Print("Server failed to send echo: ", acceptedClient.GetLastError());
|
|
delete acceptedClient;
|
|
delete client;
|
|
delete server;
|
|
return false;
|
|
}
|
|
Print("Server sent echo message");
|
|
|
|
// Step 8: Client receives echo
|
|
string echoReceived = "";
|
|
receiveRetries = 0;
|
|
while(echoReceived == "" && receiveRetries < 100)
|
|
{
|
|
echoReceived = client.Receive(MESSAGE_SEPARATOR);
|
|
if(echoReceived == "")
|
|
{
|
|
Sleep(10);
|
|
receiveRetries++;
|
|
}
|
|
}
|
|
|
|
if(echoReceived == "")
|
|
{
|
|
Print("Client failed to receive echo: ", client.GetLastError());
|
|
delete acceptedClient;
|
|
delete client;
|
|
delete server;
|
|
return false;
|
|
}
|
|
Print("Client received echo: '", echoReceived, "'");
|
|
|
|
string expectedEcho = "Echo: " + TEST_MESSAGE;
|
|
bool echoMatches = (echoReceived == expectedEcho);
|
|
if(!echoMatches)
|
|
{
|
|
Print("Echo mismatch! Expected: '", expectedEcho, "', Got: '", echoReceived, "'");
|
|
}
|
|
|
|
// Cleanup
|
|
delete acceptedClient;
|
|
delete client;
|
|
delete server;
|
|
|
|
Print("Test completed successfully");
|
|
return messageMatches && echoMatches;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| DoTests |
|
|
//+------------------------------------------------------------------+
|
|
void DoTests(int &testsPerformed,int &testsPassed)
|
|
{
|
|
string testName="";
|
|
|
|
//--- TestSocketBasicFunctionality
|
|
testsPerformed++;
|
|
testName="TestSocketBasicFunctionality";
|
|
if(TestSocketBasicFunctionality())
|
|
{
|
|
testsPassed++;
|
|
PrintFormat("%s pass",testName);
|
|
}
|
|
else
|
|
PrintFormat("%s failed",testName);
|
|
|
|
//---
|
|
// Add more tests here as needed
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| UnitTests() |
|
|
//+------------------------------------------------------------------+
|
|
void UnitTests(const string packageName)
|
|
{
|
|
PrintFormat("Unit tests for Package %s\n",packageName);
|
|
//--- initial values
|
|
int testsPerformed=0;
|
|
int testsPassed=0;
|
|
//--- test distributions
|
|
DoTests(testsPerformed,testsPassed);
|
|
//--- print statistics
|
|
PrintFormat("\n%d of %d passed",testsPassed,testsPerformed);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Script program start function |
|
|
//+------------------------------------------------------------------+
|
|
void OnStart()
|
|
{
|
|
UnitTests("sockets");
|
|
}
|
|
//+------------------------------------------------------------------+
|