#include <iostream>
#include <memory>
#include <string>
#include <boost/test/minimal.hpp>
#include <boost/thread/thread.hpp>
#include <RCF/Idl.hpp>
#include <RCF/RcfServer.hpp>
#include <RCF/test/TransportFactories.hpp>
#include <RCF/test/ThreadGroup.hpp>
#include <RCF/util/CommandLine.hpp>
RCF_BEGIN(I_X, "I_X")
RCF_METHOD_R1(std::string, echo, std::string)
RCF_END(I_X)
struct X
{
std::string echo(const std::string &s)
{
return s;
}
};
ThreadGroup serverThreads;
void serverThreadTask(RCF::RcfServer &server)
{
server.startInThisThread( RCF::RcfServer::JoinFunctor() );
}
void joinServerThreads()
{
for (unsigned int i=0; i<serverThreads.size(); ++i)
{
serverThreads[i]->join();
}
serverThreads.clear();
}
void clientThreadTask(const RCF::I_ClientTransport &clientTransport, int sets, int reps)
{
try
{
for (int i=0; i<sets; ++i)
{
RcfClient<I_X> client(clientTransport.clone());
for (int j=0; j<reps; ++j)
{
std::string s0 = "just another string";
try
{
std::string s = client.echo(RCF::Twoway, s0);
BOOST_CHECK( s == s0 );
}
catch(const RCF::Exception &e)
{
RCF_TRACE("client call failed")(i)(j)(sets)(reps);
// not necessarily an error, the server might be overloaded
}
}
}
}
catch(const RCF::Exception &e)
{
BOOST_CHECK(0);
}
catch(...)
{
BOOST_CHECK(0);
}
}
int test_main(int argc, char **argv)
{
util::CommandLine::getSingleton().parse(argc, argv);
// disable this test for now
return boost::exit_success;
for (unsigned int i=0; i<RCF::getTransportFactories().size(); ++i)
{
// single server thread
{
RCF::TransportFactoryPtr transportFactoryPtr = RCF::getTransportFactories()[i];
std::pair<RCF::ServerTransportPtr, RCF::ClientTransportAutoPtrPtr> transports = transportFactoryPtr->createTransports();
RCF::ServerTransportPtr serverTransportPtr( transports.first );
RCF::ClientTransportAutoPtr clientTransportAutoPtr( *transports.second );
RCF::RcfServer server(serverTransportPtr);
X x;
server.bind<I_X>(x);
server.start();
int clientThreadCount = 10;
ThreadGroup clients;
for (int j=0; j<clientThreadCount; ++j)
{
clients.push_back( ThreadPtr(new Thread(
boost::bind(&clientThreadTask, boost::ref(*clientTransportAutoPtr), 5, 5))));
}
joinThreadGroup(clients);
server.stop();
}
// multiple dedicated server threads
{
RCF::TransportFactoryPtr transportFactoryPtr = RCF::getTransportFactories()[i];
std::pair<RCF::ServerTransportPtr, RCF::ClientTransportAutoPtrPtr> transports = transportFactoryPtr->createTransports();
RCF::ServerTransportPtr serverTransportPtr( transports.first );
RCF::ClientTransportAutoPtr clientTransportAutoPtr( *transports.second );
RCF::RcfServer server(serverTransportPtr);
X x;
server.bind<I_X>(x);
int serverThreadCount = 5;
server.start(serverThreadCount);
int clientThreadCount = 10;
ThreadGroup clients;
for (int j=0; j<clientThreadCount; ++j)
{
clients.push_back( ThreadPtr(new Thread(
boost::bind(&clientThreadTask, boost::ref(*clientTransportAutoPtr), 5, 100))));
}
joinThreadGroup(clients);
server.stop();
}
// multiple omni server threads
{
RCF::TransportFactoryPtr transportFactoryPtr = RCF::getTransportFactories()[i];
std::pair<RCF::ServerTransportPtr, RCF::ClientTransportAutoPtrPtr> transports = transportFactoryPtr->createTransports();
RCF::ServerTransportPtr serverTransportPtr( transports.first );
RCF::ClientTransportAutoPtr clientTransportAutoPtr( *transports.second );
RCF::RcfServer server(serverTransportPtr);
X x;
server.bind<I_X>(x);
server.open(); // open() is not thread safe, so call it before the server threads do
int serverThreadCount = 1; // TODO: is there ever a need for more than 1 omni thread?
for (int j=0; j<serverThreadCount; ++j)
{
serverThreads.push_back( ThreadPtr(new Thread( boost::bind(serverThreadTask, boost::ref(server)))) );
}
server.addJoinFunctor( joinServerThreads );
int clientThreadCount = 10;
ThreadGroup clients;
for (int j=0; j<clientThreadCount; ++j)
{
clients.push_back( ThreadPtr(new Thread(
boost::bind(&clientThreadTask, boost::ref(*clientTransportAutoPtr), 5, 100))));
}
joinThreadGroup(clients);
server.stop();
joinThreadGroup(serverThreads);
}
/*
// mixed server threads
{
RCF::TransportFactoryPtr transportFactoryPtr = RCF::getTransportFactories()[i];
std::pair<RCF::ServerTransportPtr, RCF::ClientTransportAutoPtrPtr> transports = transportFactoryPtr->createTransports();
RCF::ServerTransportPtr serverTransportPtr( transports.first );
RCF::ClientTransportAutoPtr clientTransportAutoPtr( *transports.second );
RCF::RcfServer server(serverTransportPtr);
X x;
server.bind<I_X>(x);
server.start(5);
int serverThreadCount = 5;
ThreadGroup serverThreads;
for (int j=0; j<serverThreadCount; ++j)
{
serverThreads.push_back( ThreadPtr(new Thread( boost::bind(serverThreadTask, boost::ref(server)))) );
}
int clientThreadCount = 10;
ThreadGroup clients;
for (int j=0; j<clientThreadCount; ++j)
{
clients.push_back( ThreadPtr(new Thread(
boost::bind(&clientThreadTask, boost::ref(*clientTransportAutoPtr), 5, 100))));
}
joinThreadGroup(clients);
server.stop();
joinThreadGroup(serverThreads);
}
*/
}
return boost::exit_success;
}