#include <iostream>
#include <sstream>
#include <string>
#include <boost/thread/xtime.hpp>
#include <RCF/test/TestMinimal.hpp>
#include <RCF/Idl.hpp>
#include <RCF/RcfServer.hpp>
#include <RCF/test/TransportFactories.hpp>
#include <RCF/util/CommandLine.hpp>
#include <RCF/util/PortNumbers.hpp>
#include <RCF/util/Platform/OS/Sleep.hpp>
#include <SF/memory.hpp>
// Need to disable broken pipe signals for OS's like Solaris
#ifdef SIGPIPE
#include <signal.h>
#include <RCF/util/InitDeinit.hpp>
UTIL_ON_INIT( sigignore(SIGPIPE) )
#endif
namespace Test_ClientTimeout {
RCF_BEGIN(I_X, "I_X")
RCF_METHOD_R2(std::string, echo, std::string, unsigned int);
RCF_END(I_X);
class X
{
public:
std::string echo(const std::string &s, unsigned int sec)
{
Platform::OS::Sleep(sec);
return s;
}
};
} // namespace Test_ClientTimeout
int RCF_TEST_MAIN(int argc, char **argv)
{
printTestHeader(__FILE__);
using namespace Test_ClientTimeout;
util::CommandLine::getSingleton().parse(argc, argv);
for (int i=0; i<RCF::getTransportFactories().size(); ++i)
{
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 );
if (!transportFactoryPtr->isConnectionOriented())
{
continue;
}
RCF::writeTransportTypes(std::cout, *serverTransportPtr, *clientTransportAutoPtr);
X x;
RCF::RcfServer server(serverTransportPtr);
server.bind( (I_X *) 0, x);
server.start();
RcfClient<I_X> client(clientTransportAutoPtr);
// this call will timeout
client.getClientStub().setRemoteCallTimeoutMs(1*1000);
try
{
std::string s = client.echo("abc", 2);
BOOST_CHECK(1==0);
}
catch (const RCF::Exception &e)
{
BOOST_CHECK(1==1);
std::cout << e.what();
}
// this one won't
client.getClientStub().setRemoteCallTimeoutMs(10*1000);
std::string s = client.echo("def", 2);
// whether or not this check succeeds depends on the client transport implementation (will fail on UDP for instance)
// OTOH, if the server transport is running several threads, it will probably succeed anyway
// (the second thread gets its response in before the first one)
// TODO: run the server with at least 2 threads
//BOOST_CHECK(s == "def");
// test connection timeout
//server.stop();
server.close();
client.getClientStub().setRemoteCallTimeoutMs(15*1000);
client.getClientStub().setConnectTimeoutMs(2*1000);
unsigned int t0 = RCF::getCurrentTimeMs();
try
{
client.echo("asdf", 10);
BOOST_CHECK(1==0);
}
catch (const RCF::Exception &e)
{
BOOST_CHECK(1==1);
}
unsigned int t1 = RCF::getCurrentTimeMs();
std::cout << "t1-t0 = " << t1-t0 << std::endl;
BOOST_CHECK(t1-t0 < 4*1000);
server.start();
client.getClientStub().setRemoteCallTimeoutMs(15*1000);
client.getClientStub().setConnectTimeoutMs(2*1000);
t0 = RCF::getCurrentTimeMs();
try
{
client.echo("asdf", 5);
BOOST_CHECK(1==1);
}
catch (const RCF::Exception &e)
{
BOOST_CHECK(1==0);
}
t1 = RCF::getCurrentTimeMs();
std::cout << "t1-t0 = " << t1-t0 << std::endl;
BOOST_CHECK(t1-t0 >= 4900); // leave 100ms margin for OS timer discrepancies...
}
return boost::exit_success;
}