From c72722fa8247841d6326ad5bfad2566fba9a1db9 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Tue, 21 Feb 2017 18:27:42 -0600 Subject: [PATCH] Begin to add mock siad for testing --- UnitTests/MockSiad.cpp | 136 ++++++++++++++++++++++++++++ UnitTests/MockSiad.h | 22 +++++ UnitTests/UnitTests.vcxproj | 10 +- UnitTests/UnitTests.vcxproj.filters | 6 ++ 4 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 UnitTests/MockSiad.cpp create mode 100644 UnitTests/MockSiad.h diff --git a/UnitTests/MockSiad.cpp b/UnitTests/MockSiad.cpp new file mode 100644 index 0000000..b228c3a --- /dev/null +++ b/UnitTests/MockSiad.cpp @@ -0,0 +1,136 @@ +#include "stdafx.h" +#include "MockSiad.h" + +class CMockClient +{ +public: + CMockClient(SOCKET socket, std::function removedCallback) : + _socket(socket) + { + _clientThread.reset(new std::thread([this]() + { + Run(); + })); + } + +public: + ~CMockClient() + { + ::SetEvent(_stopEvent); + _clientThread->join(); + ::CloseHandle(_stopEvent); + } + +private: + SOCKET _socket; + HANDLE _stopEvent; + std::function NotifyClientRemoved; + std::unique_ptr _clientThread; + +private: + void Run() + { + bool connected = true; + bool stopRequested; + while (connected && !(stopRequested = (::WaitForSingleObject(_stopEvent, 1) == WAIT_TIMEOUT))) + { + timeval tv = { 1, 0 }; + FD_SET readFds, exceptFds; + FD_ZERO(&readFds); + FD_ZERO(&exceptFds); + FD_SET(_socket, &readFds); + FD_SET(_socket, &exceptFds); + int selectResult = ::select(0, &readFds, nullptr, &exceptFds, &tv); + if (selectResult != SOCKET_ERROR) + { + if (FD_ISSET(_socket, &readFds)) + { + + } + else if (FD_ISSET(_socket, &exceptFds)) + { + connected = false; + } + } + } + + closesocket(_socket); + NotifyClientRemoved(this); + } +}; + + +CMockSiad::CMockSiad(const SiaHostConfig& hostConfig) : + _hostConfig(hostConfig), + _stopEvent(::CreateEvent(nullptr, FALSE, FALSE, nullptr)) +{ + const WORD ver = MAKEWORD(2, 2); + ::WSAStartup(ver, nullptr); +} + +CMockSiad::~CMockSiad() +{ + Stop(); + CloseHandle(_stopEvent); + ::WSACleanup(); +} + +void CMockSiad::Start() +{ + if (!_serverThread) + { + _serverThread.reset(new std::thread([this]() + { + bool stopRequested = false; + std::mutex clientMutex; + do + { + SOCKET listenSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + struct sockaddr_in sockAddr = { 0 }; + sockAddr.sin_family = AF_INET; + sockAddr.sin_addr.s_addr = inet_addr("localhost"); + sockAddr.sin_port = htons(5150); + bool listening = ((listenSocket != INVALID_SOCKET) && (::bind(listenSocket, reinterpret_cast(&sockAddr), sizeof(sockAddr)) != SOCKET_ERROR)); + while (listening && !(stopRequested = (::WaitForSingleObject(_stopEvent, 1) == WAIT_TIMEOUT))) + { + { + std::lock_guard l(clientMutex); + } + + timeval tv = { 1, 0 }; + FD_SET readFds, exceptFds; + FD_ZERO(&readFds); + FD_ZERO(&exceptFds); + FD_SET(listenSocket, &readFds); + FD_SET(listenSocket, &exceptFds); + int selectResult = ::select(0, &readFds, nullptr, &exceptFds, &tv); + if (selectResult != SOCKET_ERROR) + { + if (FD_ISSET(listenSocket, &readFds)) + { + SOCKET clientSocket = ::accept(listenSocket, nullptr, nullptr); + CMockClient* client = new CMockClient(clientSocket, [this, &clientMutex](CMockClient* removedClient) + { + std::lock_guard l(clientMutex); + }); + + } + else if (FD_ISSET(listenSocket, &exceptFds)) + { + listening = false; + } + } + } + + closesocket(listenSocket); + + } while (!stopRequested); + })); + } +} + +void CMockSiad::Stop() +{ + +} \ No newline at end of file diff --git a/UnitTests/MockSiad.h b/UnitTests/MockSiad.h new file mode 100644 index 0000000..fc37194 --- /dev/null +++ b/UnitTests/MockSiad.h @@ -0,0 +1,22 @@ +#pragma once +#include + +using namespace Sia::Api; + +class CMockSiad +{ +public: + CMockSiad(const SiaHostConfig& hostConfig); + + ~CMockSiad(); + +private: + SiaHostConfig _hostConfig; + HANDLE _stopEvent; + std::unique_ptr _serverThread; + +public: + void Start(); + void Stop(); +}; + diff --git a/UnitTests/UnitTests.vcxproj b/UnitTests/UnitTests.vcxproj index 8c864df..22dce79 100644 --- a/UnitTests/UnitTests.vcxproj +++ b/UnitTests/UnitTests.vcxproj @@ -97,8 +97,7 @@ Windows $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - + Ws2_32.lib @@ -113,6 +112,7 @@ Windows $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + Ws2_32.lib @@ -131,8 +131,7 @@ true true $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - + Ws2_32.lib @@ -151,14 +150,17 @@ true true $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + Ws2_32.lib + + diff --git a/UnitTests/UnitTests.vcxproj.filters b/UnitTests/UnitTests.vcxproj.filters index 17ea9f3..4df9a38 100644 --- a/UnitTests/UnitTests.vcxproj.filters +++ b/UnitTests/UnitTests.vcxproj.filters @@ -24,6 +24,9 @@ Header Files + + Header Files + @@ -47,5 +50,8 @@ Source Files + + Source Files + \ No newline at end of file