From 134a15ea8d5ef84784dda6e755a144da9f39a268 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Thu, 14 May 2015 18:01:39 +0100 Subject: [PATCH] Modified IpcServer to be mockable #4651 Also started IpcLogOutputterTests --- src/lib/ipc/IpcServer.cpp | 33 ++++++++++++----- src/lib/ipc/IpcServer.h | 23 +++++++++--- src/test/mock/ipc/MockIpcServer.h | 35 ++++++++++++++++++ .../unittests/ipc/IpcLogOutputterTests.cpp | 37 +++++++++++++++++++ 4 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 src/test/mock/ipc/MockIpcServer.h create mode 100644 src/test/unittests/ipc/IpcLogOutputterTests.cpp diff --git a/src/lib/ipc/IpcServer.cpp b/src/lib/ipc/IpcServer.cpp index 618e7df2..ce533107 100644 --- a/src/lib/ipc/IpcServer.cpp +++ b/src/lib/ipc/IpcServer.cpp @@ -33,17 +33,20 @@ // IpcServer::IpcServer(IEventQueue* events, SocketMultiplexer* socketMultiplexer) : - m_socket(events, socketMultiplexer), - m_address(NetworkAddress(IPC_HOST, IPC_PORT)), - m_events(events) + m_mock(false), + m_events(events), + m_socketMultiplexer(socketMultiplexer), + m_socket(nullptr), + m_address(NetworkAddress(IPC_HOST, IPC_PORT)) { init(); } IpcServer::IpcServer(IEventQueue* events, SocketMultiplexer* socketMultiplexer, int port) : - m_socket(events, socketMultiplexer), - m_address(NetworkAddress(IPC_HOST, port)), - m_events(events) + m_mock(false), + m_events(events), + m_socketMultiplexer(socketMultiplexer), + m_address(NetworkAddress(IPC_HOST, port)) { init(); } @@ -51,17 +54,27 @@ IpcServer::IpcServer(IEventQueue* events, SocketMultiplexer* socketMultiplexer, void IpcServer::init() { + m_socket = new TCPListenSocket(m_events, m_socketMultiplexer); + m_clientsMutex = ARCH->newMutex(); m_address.resolve(); m_events->adoptHandler( - m_events->forIListenSocket().connecting(), &m_socket, + m_events->forIListenSocket().connecting(), m_socket, new TMethodEventJob( this, &IpcServer::handleClientConnecting)); } IpcServer::~IpcServer() { + if (m_mock) { + return; + } + + if (m_socket != nullptr) { + delete m_socket; + } + ARCH->lockMutex(m_clientsMutex); ClientList::iterator it; for (it = m_clients.begin(); it != m_clients.end(); it++) { @@ -71,19 +84,19 @@ IpcServer::~IpcServer() ARCH->unlockMutex(m_clientsMutex); ARCH->closeMutex(m_clientsMutex); - m_events->removeHandler(m_events->forIListenSocket().connecting(), &m_socket); + m_events->removeHandler(m_events->forIListenSocket().connecting(), m_socket); } void IpcServer::listen() { - m_socket.bind(m_address); + m_socket->bind(m_address); } void IpcServer::handleClientConnecting(const Event&, void*) { - synergy::IStream* stream = m_socket.accept(); + synergy::IStream* stream = m_socket->accept(); if (stream == NULL) { return; } diff --git a/src/lib/ipc/IpcServer.h b/src/lib/ipc/IpcServer.h index b16b74f0..2c442307 100644 --- a/src/lib/ipc/IpcServer.h +++ b/src/lib/ipc/IpcServer.h @@ -49,17 +49,17 @@ public: //@{ //! Opens a TCP socket only allowing local connections. - void listen(); + virtual void listen(); //! Send a message to all clients matching the filter type. - void send(const IpcMessage& message, EIpcClientType filterType); + virtual void send(const IpcMessage& message, EIpcClientType filterType); //@} //! @name accessors //@{ //! Returns true when there are clients of the specified type connected. - bool hasClients(EIpcClientType clientType) const; + virtual bool hasClients(EIpcClientType clientType) const; //@} @@ -72,10 +72,21 @@ private: private: typedef std::list ClientList; - - TCPListenSocket m_socket; + + bool m_mock; + IEventQueue* m_events; + SocketMultiplexer* m_socketMultiplexer; + TCPListenSocket* m_socket; NetworkAddress m_address; ClientList m_clients; ArchMutex m_clientsMutex; - IEventQueue* m_events; + +#ifdef TEST_ENV +public: + IpcServer() : + m_mock(true), + m_events(nullptr), + m_socketMultiplexer(nullptr), + m_socket(nullptr) { } +#endif }; diff --git a/src/test/mock/ipc/MockIpcServer.h b/src/test/mock/ipc/MockIpcServer.h new file mode 100644 index 00000000..ae63cd34 --- /dev/null +++ b/src/test/mock/ipc/MockIpcServer.h @@ -0,0 +1,35 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2015 Synergy Si Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "ipc/IpcServer.h" +#include "ipc/IpcMessage.h" + +#include "test/global/gmock.h" + +class IEventQueue; + +class MockIpcServer : public IpcServer +{ +public: + MockIpcServer() { } + + MOCK_METHOD0(listen, void()); + MOCK_METHOD2(send, void(const IpcMessage&, EIpcClientType)); + MOCK_CONST_METHOD1(hasClients, bool(EIpcClientType)); +}; diff --git a/src/test/unittests/ipc/IpcLogOutputterTests.cpp b/src/test/unittests/ipc/IpcLogOutputterTests.cpp new file mode 100644 index 00000000..91ce18d9 --- /dev/null +++ b/src/test/unittests/ipc/IpcLogOutputterTests.cpp @@ -0,0 +1,37 @@ +/* + * synergy -- mouse and keyboard sharing utility + * Copyright (C) 2015 Synergy Si Ltd. + * + * This package is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * found in the file LICENSE that should have accompanied this file. + * + * This package 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define TEST_ENV + +#include "ipc/IpcLogOutputter.h" +#include "base/String.h" + +#include "test/mock/ipc/MockIpcServer.h" + +#include "test/global/gtest.h" + +using namespace synergy; + +TEST(IpcLogOutputterTests, write_bufferSizeWrapping) +{ + MockIpcServer mockServer; + IpcLogOutputter outputter(mockServer); + + outputter.write(kNOTE, "hello world", false); + + EXPECT_EQ(true, true); +}