зеркало из https://github.com/microsoft/IPC.Bond.git
205 строки
5.7 KiB
C++
205 строки
5.7 KiB
C++
#include "stdafx.h"
|
|
#include "IPC/Bond/Server.h"
|
|
#include "IPC/Bond/Client.h"
|
|
#include "IPC/Bond/Acceptor.h"
|
|
#include "IPC/Bond/Connector.h"
|
|
#include "IPC/detail/RandomString.h"
|
|
#include <bond/core/tuple.h>
|
|
|
|
using namespace IPC::Bond;
|
|
using IPC::detail::GenerateRandomString;
|
|
using IPC::SharedMemory;
|
|
using IPC::create_only;
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE(ClientServerTests)
|
|
|
|
using Request = std::tuple<int>;
|
|
using Response = std::tuple<int, int>;
|
|
|
|
class SerializerMock
|
|
{
|
|
public:
|
|
template <typename T>
|
|
DefaultBufferPool::ConstBuffer Serialize(const T& value);
|
|
|
|
template <>
|
|
DefaultBufferPool::ConstBuffer Serialize(const Request& /*value*/)
|
|
{
|
|
++m_counters->m_requestSerialized;
|
|
return{};
|
|
}
|
|
|
|
template <>
|
|
DefaultBufferPool::ConstBuffer Serialize(const Response& /*value*/)
|
|
{
|
|
++m_counters->m_responseSerialized;
|
|
return{};
|
|
}
|
|
|
|
template <typename T>
|
|
void Deserialize(DefaultBufferPool::ConstBuffer&& buffer, T& value);
|
|
|
|
template <>
|
|
void Deserialize(DefaultBufferPool::ConstBuffer&& /*buffer*/, Response& /*value*/)
|
|
{
|
|
++m_counters->m_responseDeserialized;
|
|
}
|
|
|
|
template <typename T>
|
|
std::future<T> Deserialize(DefaultBufferPool::ConstBuffer buffer);
|
|
|
|
template <>
|
|
std::future<Request> Deserialize(DefaultBufferPool::ConstBuffer /*buffer*/)
|
|
{
|
|
++m_counters->m_requestDeserialized;
|
|
return Deserialize<Request>();
|
|
}
|
|
|
|
template <>
|
|
std::future<Response> Deserialize(DefaultBufferPool::ConstBuffer /*buffer*/)
|
|
{
|
|
++m_counters->m_responseDeserialized;
|
|
return Deserialize<Response>();
|
|
}
|
|
|
|
bool CheckClientUsage() const
|
|
{
|
|
return m_counters->m_requestSerialized == 1
|
|
&& m_counters->m_requestDeserialized == 0
|
|
&& m_counters->m_responseSerialized == 0
|
|
&& m_counters->m_responseDeserialized == 1;
|
|
}
|
|
|
|
bool CheckServerUsage() const
|
|
{
|
|
return m_counters->m_requestSerialized == 0
|
|
&& m_counters->m_requestDeserialized == 1
|
|
&& m_counters->m_responseSerialized == 1
|
|
&& m_counters->m_responseDeserialized == 0;
|
|
}
|
|
|
|
void ResetCounters()
|
|
{
|
|
m_counters->Reset();
|
|
}
|
|
|
|
private:
|
|
template <typename T>
|
|
std::future<T> Deserialize()
|
|
{
|
|
std::promise<T> promise;
|
|
promise.set_value({});
|
|
return promise.get_future();
|
|
}
|
|
|
|
struct Counters
|
|
{
|
|
void Reset()
|
|
{
|
|
*this = {};
|
|
}
|
|
|
|
std::size_t m_requestSerialized{ 0 };
|
|
std::size_t m_requestDeserialized{ 0 };
|
|
std::size_t m_responseSerialized{ 0 };
|
|
std::size_t m_responseDeserialized{ 0 };
|
|
};
|
|
|
|
std::shared_ptr<Counters> m_counters{ std::make_shared<Counters>() };
|
|
};
|
|
|
|
struct MockTraits : DefaultTraits
|
|
{
|
|
using Serializer = SerializerMock;
|
|
};
|
|
|
|
using Server = Server<Request, Response, MockTraits>;
|
|
using Client = Client<Request, Response, MockTraits>;
|
|
using Acceptor = ServerAcceptor<Request, Response, MockTraits>;
|
|
using Connector = ClientConnector<Request, Response, MockTraits>;
|
|
|
|
BOOST_AUTO_TEST_CASE(SerializerTest)
|
|
{
|
|
auto name = GenerateRandomString();
|
|
|
|
std::unique_ptr<Server> server;
|
|
|
|
Acceptor acceptor{
|
|
name.c_str(),
|
|
[&](auto&& futureConnection)
|
|
{
|
|
server = std::make_unique<Server>(
|
|
detail::BufferPoolHolder<DefaultBufferPool>{ nullptr, nullptr },
|
|
SerializerMock{},
|
|
futureConnection.get(),
|
|
[](auto futureRequest, auto&& callback)
|
|
{
|
|
auto request = futureRequest.get();
|
|
callback(std::tuple_cat(request, request));
|
|
},
|
|
[] {});
|
|
} };
|
|
|
|
Client client{
|
|
detail::BufferPoolHolder<DefaultBufferPool>{ nullptr, nullptr },
|
|
SerializerMock{},
|
|
Connector{}.Connect(name.c_str()).get(),
|
|
[] {},
|
|
{} };
|
|
|
|
std::promise<Response> result;
|
|
client(Request{}, [&](std::future<Response>&& response) { result.set_value(response.get()); });
|
|
BOOST_TEST((result.get_future().get() == Response{}));
|
|
BOOST_TEST(client.CheckClientUsage());
|
|
BOOST_TEST(server->CheckServerUsage());
|
|
|
|
client.ResetCounters();
|
|
server->ResetCounters();
|
|
BOOST_TEST((client(Request{}).get() == Response{}));
|
|
BOOST_TEST(client.CheckClientUsage());
|
|
BOOST_TEST(server->CheckServerUsage());
|
|
|
|
client.ResetCounters();
|
|
server->ResetCounters();
|
|
BOOST_TEST((client(Request{}, std::chrono::milliseconds{ 1 }).get() == Response{}));
|
|
BOOST_TEST(client.CheckClientUsage());
|
|
BOOST_TEST(server->CheckServerUsage());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(BufferPoolTest)
|
|
{
|
|
auto memory = std::make_shared<SharedMemory>(create_only, GenerateRandomString().c_str(), 1024 * 1024);
|
|
auto inPool = std::make_shared<DefaultBufferPool>(memory);
|
|
auto outPool = std::make_shared<DefaultBufferPool>(memory);
|
|
|
|
auto name = GenerateRandomString();
|
|
|
|
std::unique_ptr<Server> server;
|
|
|
|
Acceptor acceptor{
|
|
name.c_str(),
|
|
[&](auto&& futureConnection)
|
|
{
|
|
server = std::make_unique<Server>(
|
|
detail::BufferPoolHolder<DefaultBufferPool>{ inPool, outPool },
|
|
SerializerMock{},
|
|
futureConnection.get(),
|
|
[](auto&&...) {},
|
|
[] {});
|
|
} };
|
|
|
|
Client client{
|
|
detail::BufferPoolHolder<DefaultBufferPool>{ inPool, outPool },
|
|
SerializerMock{},
|
|
Connector{}.Connect(name.c_str()).get(),
|
|
[] {} };
|
|
|
|
BOOST_TEST(client.GetInputPool() == inPool);
|
|
BOOST_TEST(client.GetOutputPool() == outPool);
|
|
BOOST_TEST(server->GetInputPool() == inPool);
|
|
BOOST_TEST(server->GetOutputPool() == outPool);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|