add RPC loopback test

This commit is contained in:
Michael Davidsaver
2017-07-03 19:19:16 +02:00
parent 3eb601c210
commit 4fe837c9a0
7 changed files with 118 additions and 7 deletions
+1
View File
@@ -14,6 +14,7 @@
# undef epicsExportSharedSymbols
#endif
#include <pv/pvData.h>
#include <pv/valueBuilder.h>
#ifdef rpcClientEpicsExportSharedSymbols
# define epicsExportSharedSymbols
# undef rpcClientEpicsExportSharedSymbols
+1 -1
View File
@@ -36,7 +36,7 @@ struct RPCClient::RPCRequester : public pva::ChannelRPCRequester
POINTER_DEFINITIONS(RPCRequester);
pvd::Mutex mutex;
ChannelRPC::weak_pointer op;
ChannelRPC::shared_pointer op;
pvd::Status conn_status, resp_status;
epics::pvData::PVStructure::shared_pointer next_args, last_data;
epicsEvent event;
+2 -3
View File
@@ -38,12 +38,10 @@ private:
std::tr1::shared_ptr<ServerContext> m_serverContext;
ChannelProvider::shared_pointer m_channelProviderImpl;
// TODO no thread poll implementation
public:
POINTER_DEFINITIONS(RPCServer);
RPCServer();
explicit RPCServer(const Configuration::const_shared_pointer& conf = Configuration::const_shared_pointer());
virtual ~RPCServer();
@@ -66,6 +64,7 @@ public:
*/
void printInfo();
const std::tr1::shared_ptr<ServerContext>& getServer() const { return m_serverContext; }
};
epicsShareFunc Channel::shared_pointer createRPCChannel(ChannelProvider::shared_pointer const & provider,
+5 -2
View File
@@ -32,10 +32,13 @@ namespace pvAccess {
class epicsShareClass RPCRequestException : public std::runtime_error {
public:
explicit RPCRequestException(std::string const & message) :
std::runtime_error(message), m_status(epics::pvData::Status::STATUSTYPE_ERROR)
{}
RPCRequestException(epics::pvData::Status::StatusType status, std::string const & message) :
std::runtime_error(message), m_status(status)
{
}
{}
epics::pvData::Status::StatusType getStatus() const {
return m_status;
+2 -1
View File
@@ -477,11 +477,12 @@ string RPCChannelProvider::PROVIDER_NAME("rpcService");
Status RPCChannelProvider::noSuchChannelStatus(Status::STATUSTYPE_ERROR, "no such channel");
RPCServer::RPCServer()
RPCServer::RPCServer(const Configuration::const_shared_pointer &conf)
:m_channelProviderImpl(new RPCChannelProvider)
{
ChannelProvider::shared_pointer prov(new RPCChannelProvider);
m_serverContext = ServerContext::create(ServerContext::Config()
.config(conf)
.provider(m_channelProviderImpl));
}
+3
View File
@@ -12,6 +12,9 @@ testCodec_SRCS = testCodec
testHarness_SRCS += testCodec.cpp
TESTS += testCodec
TESTPROD_HOST += testRPC
testRPC_SRCS += testRPC.cpp
TESTS += testRPC
TESTPROD_HOST += testRemoteClientImpl
testRemoteClientImpl_SRCS += testRemoteClientImpl.cpp
+104
View File
@@ -0,0 +1,104 @@
#include <pv/epicsException.h>
#include <pv/valueBuilder.h>
#include <pv/clientFactory.h>
#include <pv/rpcClient.h>
#include <pv/rpcServer.h>
#include <pv/rpcService.h>
#include <epicsUnitTest.h>
#include <testMain.h>
namespace pvd = epics::pvData;
namespace pva = epics::pvAccess;
namespace {
pvd::StructureConstPtr reply_type(pvd::getFieldCreate()->createFieldBuilder()
->add("value", pvd::pvDouble)
->createStructure());
struct SumService : public pva::RPCService
{
virtual epics::pvData::PVStructure::shared_pointer request(
epics::pvData::PVStructure::shared_pointer const & args
) OVERRIDE FINAL
{
testDiag("request()");
pvd::PVScalarPtr lhs(args->getSubField<pvd::PVScalar>("query.lhs")),
rhs(args->getSubField<pvd::PVScalar>("query.rhs"));
if(!lhs || !rhs)
throw pva::RPCRequestException("Missing query.lhs and/or query.rhs");
double a = lhs->getAs<double>(),
b = rhs->getAs<double>();
testDiag("Add %f + %f", a, b);
pvd::PVStructure::shared_pointer reply(pvd::getPVDataCreate()->createPVStructure(reply_type));
reply->getSubFieldT<pvd::PVDouble>("value")->put(a+b);
return reply;
}
};
} // namespace
MAIN(testRPC)
{
testPlan(2);
try {
pva::Configuration::shared_pointer conf(pva::ConfigurationBuilder()
//.push_env()
//.add("EPICS_PVA_DEBUG", "3")
.add("EPICS_PVAS_INTF_ADDR_LIST", "127.0.0.1")
.add("EPICS_PVA_ADDR_LIST", "127.0.0.1")
.add("EPICS_PVA_AUTO_ADDR_LIST","0")
.add("EPICS_PVA_SERVER_PORT", "0")
.add("EPICS_PVA_BROADCAST_PORT", "0")
.push_map()
.build());
testDiag("Server Setup");
pva::RPCServer serv(conf);
testDiag("TestServer on ports TCP=%u UDP=%u",
serv.getServer()->getServerPort(),
serv.getServer()->getBroadcastPort());
std::tr1::shared_ptr<pva::RPCService> service(new SumService);
serv.registerService("sum", service);
testDiag("Client Setup");
pva::ClientFactory::start();
pva::ChannelProvider::shared_pointer cli_prov(pva::ChannelProviderRegistry::clients()->createProvider("pva",
serv.getServer()->getCurrentConfig()));
if(!cli_prov)
testAbort("No pva provider");
testDiag("Client Ready");
pva::RPCClient client("sum", pvd::createRequest("field()"), cli_prov);
pvd::ValueBuilder args("epics:nt/NTURI:1.0");
args.add<pvd::pvString>("scheme", "pva")
.add<pvd::pvString>("path", "sum");
pvd::PVStructurePtr reply;
testDiag("Request");
reply = client.request(args.addNested("query")
.add<pvd::pvDouble>("lhs", 5.0)
.add<pvd::pvDouble>("rhs", 3.0)
.endNested()
.buildPVStructure());
pvd::int32 value = reply->getSubFieldT<pvd::PVScalar>("value")->getAs<pvd::int32>();
testOk(value==8, "Reply value = %d", (unsigned)value);
testDiag("Wait for connect (already connected)");
testOk1(client.waitConnect());
}catch(std::exception& e){
PRINT_EXCEPTION(e);
testAbort("Unexpected exception: %s", e.what());
}
return testDone();
}