This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,75 @@
#######################################################################
# Software License Agreement (AGPL-3 License)
#
# OpenViBE SDK Test Software
# Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
# Copyright (C) Inria, 2015-2017,V1.0
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License version 3,
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#######################################################################
PROJECT(openvibe-module-socket-test)
# ---------------------------------
# Target macros
# Defines target operating system, architecture and compiler
# ---------------------------------
SET_BUILD_PLATFORM()
# ----------------------
# Configure test target
# ----------------------
# Test that needs to called with parameters
SET(TEST_WITH_PARAM
uoSocketClientServerBaseTest.cpp
uoSocketClientServerSyncCommunicationTest.cpp
uoSocketClientServerASyncCommunicationTest.cpp
)
# Test that needs to called without parameters
SET(TEST_NO_PARAM
)
# Create test sources list
# This macro auto-generate ${PROJECT_NAME}.cpp
# in the build tree. ${PROJECT_NAME}.cpp is
# the test driver called by ctest to run
# the different tests added to this target.
CREATE_TEST_SOURCELIST (Tests
${PROJECT_NAME}.cpp
${TEST_WITH_PARAM}
${TEST_NO_PARAM}
)
ADD_EXECUTABLE(${PROJECT_NAME} ${Tests})
INCLUDE("FindOpenViBE")
INCLUDE("FindOpenViBECommon")
INCLUDE("FindOpenViBEModuleSocket")
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${TESTS_FOLDER})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OVT_UNIT_TOOLKIT_LIB} ${OV_MODULE_SOCKET})
# Add test without parameter to driver
FOREACH(test ${TEST_NO_PARAM})
GET_FILENAME_COMPONENT(TName ${test} NAME_WE)
ADD_TEST(NAME ${TName} COMMAND ${PROJECT_NAME} ${TName})
ENDFOREACH()
# Add test with parameter to driver
SET(LOCALHOST "127.0.0.1")
SET(TEST_PORT "1024")
ADD_TEST(NAME uoSocketClientServerBaseTest COMMAND ${PROJECT_NAME} uoSocketClientServerBaseTest ${LOCALHOST} ${TEST_PORT})
ADD_TEST(NAME uoSocketClientServerHostNameTest COMMAND ${PROJECT_NAME} uoSocketClientServerBaseTest "localhost" ${TEST_PORT})
ADD_TEST(NAME uoSocketClientServerSyncCommunicationTest COMMAND ${PROJECT_NAME} uoSocketClientServerSyncCommunicationTest ${LOCALHOST} ${TEST_PORT} "1000")
ADD_TEST(NAME uoSocketClientServerASyncCommunicationTest COMMAND ${PROJECT_NAME} uoSocketClientServerASyncCommunicationTest ${LOCALHOST} ${TEST_PORT} "1000")
@@ -0,0 +1,151 @@
/*********************************************************************
* Software License Agreement (AGPL-3 License)
*
* OpenViBE SDK Test Software
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
* Copyright (C) Inria, 2015-2017,V1.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <cstring>
#include <thread>
#include <condition_variable>
#include <vector>
#include "socket/IConnection.h"
#include "socket/IConnectionClient.h"
#include "socket/IConnectionServer.h"
#include "ovtAssert.h"
namespace {
std::condition_variable gServerStartedCondVar;
std::mutex gServerStartedMutex;
std::vector<std::string> gReceivedData;
bool gServerStarted = false;
// server callback run from a child thread
void onServerListening(const int port, const size_t expectedPacketCount)
{
gReceivedData.clear();
Socket::IConnection* clientConnection = nullptr;
// create server
Socket::IConnectionServer* server = Socket::createConnectionServer();
server->listen(port);
// keep the scope braces here, as it ensures mutex is released
{
std::lock_guard<std::mutex> lockOnServerStart(gServerStartedMutex);
gServerStarted = true;
}
// notify main thread that the server is created so that it can connect a single client
gServerStartedCondVar.notify_one();
// loop until all packet are received
while (gReceivedData.size() < expectedPacketCount)
{
if (server->isReadyToReceive()) { clientConnection = server->accept(); }
if (clientConnection && clientConnection->isReadyToReceive())
{
size_t dataSize = 0;
size_t bytesToReceive = sizeof(dataSize);
size_t bytesReceived = 0;
char dataBuffer[32];
// first receive data size
while (bytesReceived < bytesToReceive) { bytesReceived += clientConnection->receiveBuffer(&dataSize, bytesToReceive - bytesReceived); }
// then receive data
bytesToReceive = dataSize;
bytesReceived = 0;
while (bytesReceived < bytesToReceive) { bytesReceived += clientConnection->receiveBuffer(dataBuffer, bytesToReceive - bytesReceived); }
gReceivedData.push_back(std::string(dataBuffer, dataSize));
}
}
server->release();
}
void sendData(Socket::IConnectionClient* client, void* data, const size_t size)
{
const size_t bytesToSend = size;
size_t bytesSent = 0;
while (bytesSent < bytesToSend) { bytesSent += client->sendBuffer(data, bytesToSend - bytesSent); }
}
} // namespace
int uoSocketClientServerASyncCommunicationTest(int argc, char* argv[])
{
OVT_ASSERT(argc == 4, "Failure to retrieve tests arguments. Expecting: server_name port_number packet_count");
const std::string serverName = argv[1];
int portNumber = std::atoi(argv[2]);
size_t packetCount = size_t(std::atoi(argv[3]));
// test asynchronous data transmission from a single client to server:
// - launch a server on a background thread
// - connect a single client
// - make client sending data
// - marke server receiving and storing data
// - join the thread and do the assertions on received data when no data race is possible
// create client
Socket::IConnectionClient* client = Socket::createConnectionClient();
// launch server on background thread
std::thread serverThread(onServerListening, portNumber, packetCount);
// wait until the server is started to connect clients
std::unique_lock<std::mutex> lock(gServerStartedMutex);
gServerStartedCondVar.wait(lock, []() { return gServerStarted; });
client->connect(serverName.c_str(), portNumber);
// transmit data
// transmission follows the protocol: data size transmission + data transmission
const std::string baseData = "Data packet index: ";
for (size_t sendIndex = 0; sendIndex < packetCount; ++sendIndex)
{
std::string tmp = baseData + std::to_string(sendIndex);
size_t size = tmp.size();
sendData(client, &size, sizeof(size));
sendData(client, const_cast<char*>(tmp.c_str()), size);
}
serverThread.join(); // wait until the end of the thread
// release resources
client->close();
client->release();
// do the assertion on the main thread
OVT_ASSERT(gReceivedData.size() == packetCount, "Failure to retrieve packet count");
for (size_t receivedIndex = 0; receivedIndex < packetCount; ++receivedIndex)
{
OVT_ASSERT_STREQ(gReceivedData[receivedIndex], (baseData + std::to_string(receivedIndex)), "Failure to retrieve packet");
}
return EXIT_SUCCESS;
}
@@ -0,0 +1,77 @@
/*********************************************************************
* Software License Agreement (AGPL-3 License)
*
* OpenViBE SDK Test Software
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
* Copyright (C) Inria, 2015-2017,V1.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "socket/IConnection.h"
#include "socket/IConnectionClient.h"
#include "socket/IConnectionServer.h"
#include "ovtAssert.h"
int uoSocketClientServerBaseTest(int argc, char* argv[])
{
OVT_ASSERT(argc == 3, "Failure to retrieve tests arguments. Expecting: server_name port_number");
const std::string name = argv[1];
char* end;
const size_t port = strtol(argv[2], &end, 10);
// basic tests on server and clients
Socket::IConnectionServer* server = Socket::createConnectionServer();
Socket::IConnectionClient* client = Socket::createConnectionClient();
OVT_ASSERT(!server->isConnected(), "Failure to check for connection state before connection happens");
OVT_ASSERT(server->listen(port) && server->isConnected(), "Failure to make socket listening for input connections");
OVT_ASSERT(!server->listen(port), "Failure to generate connection error if the socket is already connected");
OVT_ASSERT(!server->isReadyToReceive(), "Failure to check for readyness to receive when no client is connected");
OVT_ASSERT(server->close() && !server->isConnected(), "Failure to close connection");
OVT_ASSERT(!client->isConnected(), "Failure to check for connection state before connection happens");
OVT_ASSERT(!client->connect(name.c_str(), port) && !client->isConnected(), "Failure to generate connection error due to no server currently running");
OVT_ASSERT(server->listen(port), "Failure to make socket listening for input connections after a disconnection");
OVT_ASSERT(!client->connect("bad_server_name", port) && !client->isConnected(), "Failure to generate connection error caused by wrong server name");
OVT_ASSERT(!client->connect(name.c_str(), 0) && !client->isConnected(), "Failure to generate connection error caused by wrong port number");
OVT_ASSERT(client->connect(name.c_str(), port) && client->isConnected(), "Failure to connect to server");
OVT_ASSERT(client->close() && !client->isConnected(), "Failure to disconnect");
// Test method getSocketPort
size_t guessedPort;
OVT_ASSERT(server->getSocketPort(guessedPort), "Failure to get socket informations");
OVT_ASSERT(guessedPort == port, "Get Socket information should return server port.");
OVT_ASSERT(client->connect(name.c_str(), guessedPort) && client->isConnected(), "Failure to connect to server");
OVT_ASSERT(client->close() && !client->isConnected(), "Failure to disconnect");
OVT_ASSERT(server->close() && !server->isConnected(), "Failure to close connection");
// Test to connect using port 0
OVT_ASSERT(server->listen(0) && server->isConnected(), "Failure to make socket listening for input connections");
OVT_ASSERT(server->getSocketPort(guessedPort), "Failure to get socket informations");
OVT_ASSERT(client->connect(name.c_str(), guessedPort) && client->isConnected(), "Failure to connect to server");
OVT_ASSERT(client->close() && !client->isConnected(), "Failure to disconnect");
OVT_ASSERT(server->close() && !server->isConnected(), "Failure to close connection");
// Release ressources
server->release();
client->release();
return EXIT_SUCCESS;
}
@@ -0,0 +1,151 @@
/*********************************************************************
* Software License Agreement (AGPL-3 License)
*
* OpenViBE SDK Test Software
* Based on OpenViBE V1.1.0, Copyright (C) Inria, 2006-2015
* Copyright (C) Inria, 2015-2017,V1.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <vector>
#include "socket/IConnection.h"
#include "socket/IConnectionClient.h"
#include "socket/IConnectionServer.h"
#include "ovtAssert.h"
namespace {
std::condition_variable gServerStartedCondVar;
std::mutex gServerStartedMutex;
std::condition_variable gClientConnectedCondVar;
std::mutex gClientConnectedMutex;
std::vector<std::string> gReceivedData;
bool gServerStarted = false;
bool gClientConnected = false;
// server callback run from a child thread
void onServerListening(const int port, const size_t packetCount)
{
// only the server side modifies gReceivedData thus no need to handle race condition
gReceivedData.clear();
Socket::IConnection* clientConnection = nullptr;
// create server
Socket::IConnectionServer* server = Socket::createConnectionServer();
server->listen(port);
// keep the scope braces here, as it ensures mutex is released
{
std::lock_guard<std::mutex> lockOnServerStart(gServerStartedMutex);
gServerStarted = true;
}
gServerStartedCondVar.notify_one();
// connect clients
while (!clientConnection) { if (server->isReadyToReceive()) { clientConnection = server->accept(); } }
// keep the scope braces here, as it ensures mutex is released
{
std::lock_guard<std::mutex> lockOnClientConnected(gClientConnectedMutex);
gClientConnected = true;
}
gClientConnectedCondVar.notify_one();
while (gReceivedData.size() < packetCount)
{
if (clientConnection->isReadyToReceive())
{
size_t dataSize = 0;
char dataBuffer[64];
clientConnection->receiveBufferBlocking(&dataSize, sizeof(dataSize));
clientConnection->receiveBufferBlocking(dataBuffer, dataSize);
gReceivedData.push_back(std::string(dataBuffer, dataSize));
}
}
server->release();
}
} // namespace
int uoSocketClientServerSyncCommunicationTest(int argc, char* argv[])
{
OVT_ASSERT(argc == 4, "Failure to retrieve tests arguments. Expecting: server_name port_number packet_count");
const std::string serverName = argv[1];
char* end;
const size_t port = strtol(argv[2], &end, 10);
size_t packetCount = strtol(argv[3], &end, 10);
// test synchronous data transmission from a single client to server:
// - launch a server on a background thread
// - connect single client
// - make client sending data
// - make server receiving and storing data
// - join the thread and do assertions on received data in the main thread
// create a client
Socket::IConnectionClient* client = Socket::createConnectionClient();
// launch server on background thread
std::thread serverThread(onServerListening, port, packetCount);
// wait until the server is started to connect client
std::unique_lock<std::mutex> lockOnServerStart(gServerStartedMutex);
gServerStartedCondVar.wait(lockOnServerStart, []() { return gServerStarted; });
client->connect(serverName.c_str(), port);
// wait until the connection is made to transmit data
std::unique_lock<std::mutex> lockOnClientConnected(gClientConnectedMutex);
gClientConnectedCondVar.wait(lockOnClientConnected, []() { return gClientConnected; });
// transmit data
// transmission follows the protocol: data size transmission + data transmission
const std::string baseData = "Data packet index: ";
for (size_t sendIndex = 0; sendIndex < packetCount; ++sendIndex)
{
std::string dataString = baseData + std::to_string(sendIndex);
size_t dataSize = dataString.size();
client->sendBufferBlocking(&dataSize, sizeof(dataSize));
client->sendBufferBlocking(dataString.c_str(), dataSize);
}
serverThread.join(); // wait until the end of the thread
// release resources
client->close();
client->release();
// do the assertion on the main thread
OVT_ASSERT(gReceivedData.size() == packetCount, "Failure to retrieve packet count");
for (size_t receivedIndex = 0; receivedIndex < packetCount; ++receivedIndex)
{
OVT_ASSERT_STREQ(gReceivedData[receivedIndex], (baseData + std::to_string(receivedIndex)), "Failure to retrieve packet");
}
return EXIT_SUCCESS;
}