init
This commit is contained in:
+75
@@ -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")
|
||||
+151
@@ -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;
|
||||
}
|
||||
Executable
+77
@@ -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;
|
||||
}
|
||||
+151
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user