add tests for provider ca
This commit is contained in:
@@ -10,10 +10,11 @@ USR_CPPFLAGS += -I$(TOP)/src/remoteClient
|
||||
|
||||
PVACCESS_TEST = $(TOP)/testApp
|
||||
|
||||
PROD_LIBS += pvAccess pvData Com
|
||||
PROD_LIBS += pvAccess pvAccessCA pvData Com
|
||||
|
||||
include $(PVACCESS_TEST)/utils/Makefile
|
||||
include $(PVACCESS_TEST)/remote/Makefile
|
||||
include $(PVACCESS_TEST)/ca/Makefile
|
||||
|
||||
# pvAccessAllTests runs all the test programs in a known working order.
|
||||
testHarness_SRCS += pvAccessAllTests.c
|
||||
|
||||
8
testApp/ca/Makefile
Normal file
8
testApp/ca/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
# This is a Makefile fragment, see ../Makefile
|
||||
|
||||
SRC_DIRS += $(PVACCESS_TEST)/ca
|
||||
|
||||
TESTPROD_HOST += testCaProvider
|
||||
testCaProvider += testCaProvider.cpp
|
||||
testHarness_SRCS += testCaProvider.cpp
|
||||
TESTS += testCaProvider
|
||||
681
testApp/ca/testCaProvider.cpp
Normal file
681
testApp/ca/testCaProvider.cpp
Normal file
@@ -0,0 +1,681 @@
|
||||
/* testCaProvider.cpp */
|
||||
/*
|
||||
* Copyright information and license terms for this software can be
|
||||
* found in the file LICENSE that is included with the distribution
|
||||
*/
|
||||
/* Author: Marty Kraimer Date: 2018.05 */
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/thread.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/convert.h>
|
||||
#include <pv/caProvider.h>
|
||||
#include <pv/requester.h>
|
||||
#include <pv/status.h>
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/alarm.h>
|
||||
#include <pv/control.h>
|
||||
#include <pv/display.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvAlarm.h>
|
||||
#include <pv/pvControl.h>
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvEnumerated.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvAccess::ca;
|
||||
using std::string;
|
||||
|
||||
class TestChannel;
|
||||
typedef std::tr1::shared_ptr<TestChannel> TestChannelPtr;
|
||||
|
||||
class TestChannel:
|
||||
public ChannelRequester,
|
||||
public std::tr1::enable_shared_from_this<TestChannel>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TestChannel);
|
||||
string getRequesterName();
|
||||
void message(
|
||||
string const & message,
|
||||
MessageType messageType);
|
||||
virtual void channelCreated(const Status& status, Channel::shared_pointer const & channel);
|
||||
virtual void channelStateChange(Channel::shared_pointer const & channel, Channel::ConnectionState connectionState);
|
||||
string getChannelName();
|
||||
Channel::shared_pointer getChannel();
|
||||
static TestChannelPtr create(string const & channelName);
|
||||
void connect();
|
||||
void waitConnect(double timeout);
|
||||
private:
|
||||
TestChannel(string const & channelName);
|
||||
string channelName;
|
||||
Event waitForConnect;
|
||||
Channel::shared_pointer channel;
|
||||
};
|
||||
|
||||
string TestChannel::getChannelName() { return channelName;}
|
||||
|
||||
Channel::shared_pointer TestChannel::getChannel() { return channel;}
|
||||
|
||||
TestChannelPtr TestChannel::create(string const & channelName)
|
||||
{
|
||||
TestChannelPtr testChannel(new TestChannel(channelName));
|
||||
testChannel->connect();
|
||||
return testChannel;
|
||||
}
|
||||
|
||||
TestChannel::TestChannel(string const & channelName)
|
||||
: channelName(channelName)
|
||||
{
|
||||
}
|
||||
|
||||
string TestChannel::getRequesterName() { return "testChannel";}
|
||||
void TestChannel::message(string const & message,MessageType messageType) {};
|
||||
|
||||
void TestChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel)
|
||||
{
|
||||
if(channel->isConnected()) waitForConnect.signal();
|
||||
}
|
||||
|
||||
void TestChannel::channelStateChange(Channel::shared_pointer const & channel, Channel::ConnectionState connectionState)
|
||||
{
|
||||
if(connectionState==Channel::CONNECTED) waitForConnect.signal();
|
||||
}
|
||||
|
||||
void TestChannel::connect()
|
||||
{
|
||||
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
|
||||
ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca"));
|
||||
if(!channelProvider) throw std::runtime_error(channelName + " provider ca not registered");
|
||||
channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT);
|
||||
if(!channel) throw std::runtime_error(channelName + " channelCreate failed ");
|
||||
waitConnect(5.0);
|
||||
}
|
||||
|
||||
void TestChannel::waitConnect(double timeout)
|
||||
{
|
||||
if(waitForConnect.wait(timeout)) return;
|
||||
throw std::runtime_error(channelName + " TestChannel::waitConnect failed ");
|
||||
}
|
||||
|
||||
class TestChannelGet;
|
||||
typedef std::tr1::shared_ptr<TestChannelGet> TestChannelGetPtr;
|
||||
|
||||
class TestChannelGetRequester;
|
||||
typedef std::tr1::shared_ptr<TestChannelGetRequester> TestChannelGetRequesterPtr;
|
||||
typedef std::tr1::weak_ptr<TestChannelGetRequester> TestChannelGetRequesterWPtr;
|
||||
|
||||
class TestChannelGetRequester
|
||||
{
|
||||
public:
|
||||
virtual void getDone(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet) = 0;
|
||||
};
|
||||
|
||||
class TestChannelGet:
|
||||
public ChannelGetRequester,
|
||||
public std::tr1::enable_shared_from_this<TestChannelGet>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TestChannelGet);
|
||||
virtual string getRequesterName();
|
||||
virtual void message(string const & message, epics::pvData::MessageType messageType) {}
|
||||
virtual void channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
Structure::const_shared_pointer const & structure);
|
||||
virtual void getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet);
|
||||
static TestChannelGetPtr create(
|
||||
TestChannelGetRequesterPtr const &getRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest);
|
||||
void connect();
|
||||
void waitConnect(double timeout);
|
||||
void get();
|
||||
private:
|
||||
TestChannelGet(
|
||||
TestChannelGetRequesterPtr const &getRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest);
|
||||
|
||||
TestChannelGetRequesterWPtr getRequester;
|
||||
TestChannelPtr testChannel;
|
||||
PVStructurePtr pvRequest;
|
||||
PVStructurePtr pvStructure;
|
||||
Event waitForConnect;
|
||||
ChannelGet::shared_pointer channelGet;
|
||||
};
|
||||
|
||||
TestChannelGetPtr TestChannelGet::create(
|
||||
TestChannelGetRequesterPtr const &getRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest)
|
||||
{
|
||||
TestChannelGetPtr testChannelGet(new TestChannelGet(getRequester,testChannel,pvRequest));
|
||||
testChannelGet->connect();
|
||||
testChannelGet->waitConnect(5.0);
|
||||
return testChannelGet;
|
||||
}
|
||||
|
||||
TestChannelGet::TestChannelGet(
|
||||
TestChannelGetRequesterPtr const &getRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest)
|
||||
: getRequester(getRequester),
|
||||
testChannel(testChannel),
|
||||
pvRequest(pvRequest)
|
||||
{
|
||||
}
|
||||
|
||||
string TestChannelGet::getRequesterName() {return "TestChannelGet";}
|
||||
|
||||
void TestChannelGet::channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
Structure::const_shared_pointer const & structure)
|
||||
{
|
||||
waitForConnect.signal();
|
||||
}
|
||||
|
||||
void TestChannelGet::getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet)
|
||||
{
|
||||
TestChannelGetRequesterPtr req(getRequester.lock());
|
||||
if(!req) return;
|
||||
if(status.isOK()) {
|
||||
req->getDone(pvStructure,bitSet);
|
||||
return;
|
||||
}
|
||||
string message = string("channel ")
|
||||
+ testChannel->getChannelName()
|
||||
+ " TestChannelGet::getDone "
|
||||
+ status.getMessage();
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
void TestChannelGet::connect()
|
||||
{
|
||||
channelGet = testChannel->getChannel()->createChannelGet(shared_from_this(),pvRequest);
|
||||
if(!channelGet) throw std::runtime_error(testChannel->getChannelName() + " channelCreate failed ");
|
||||
}
|
||||
|
||||
void TestChannelGet::waitConnect(double timeout)
|
||||
{
|
||||
if(waitForConnect.wait(timeout)) return;
|
||||
throw std::runtime_error(testChannel->getChannelName() + " TestChannelGet::waitConnect failed ");
|
||||
}
|
||||
|
||||
|
||||
void TestChannelGet::get()
|
||||
{
|
||||
channelGet->get();
|
||||
}
|
||||
|
||||
class TestChannelPut;
|
||||
typedef std::tr1::shared_ptr<TestChannelPut> TestChannelPutPtr;
|
||||
|
||||
class TestChannelPutRequester;
|
||||
typedef std::tr1::shared_ptr<TestChannelPutRequester> TestChannelPutRequesterPtr;
|
||||
typedef std::tr1::weak_ptr<TestChannelPutRequester> TestChannelPutRequesterWPtr;
|
||||
|
||||
class TestChannelPutRequester
|
||||
{
|
||||
public:
|
||||
virtual void putDone() = 0;
|
||||
};
|
||||
|
||||
class TestChannelPut:
|
||||
public ChannelPutRequester,
|
||||
public std::tr1::enable_shared_from_this<TestChannelPut>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TestChannelPut);
|
||||
virtual string getRequesterName();
|
||||
virtual void message(string const & message, MessageType messageType) {}
|
||||
virtual void channelPutConnect(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
Structure::const_shared_pointer const & structure);
|
||||
virtual void putDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut);
|
||||
virtual void getDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet);
|
||||
static TestChannelPutPtr create(
|
||||
TestChannelPutRequesterPtr const &putRequester,
|
||||
TestChannelPtr const &testChannel);
|
||||
void connect();
|
||||
void waitConnect(double timeout);
|
||||
void put(string const & value);
|
||||
private:
|
||||
TestChannelPut(
|
||||
TestChannelPutRequesterPtr const &putRequester,
|
||||
TestChannelPtr const &testChannel);
|
||||
|
||||
TestChannelPutRequesterWPtr putRequester;
|
||||
TestChannelPtr testChannel;
|
||||
PVStructurePtr pvStructure;
|
||||
BitSetPtr bitSet;
|
||||
Event waitForConnect;
|
||||
ChannelPut::shared_pointer channelPut;
|
||||
};
|
||||
|
||||
TestChannelPutPtr TestChannelPut::create(
|
||||
TestChannelPutRequesterPtr const &putRequester,
|
||||
TestChannelPtr const &testChannel)
|
||||
{
|
||||
TestChannelPutPtr testChannelPut(new TestChannelPut(putRequester,testChannel));
|
||||
testChannelPut->connect();
|
||||
testChannelPut->waitConnect(5.0);
|
||||
return testChannelPut;
|
||||
}
|
||||
|
||||
TestChannelPut::TestChannelPut(
|
||||
TestChannelPutRequesterPtr const &putRequester,
|
||||
TestChannelPtr const &testChannel)
|
||||
: putRequester(putRequester),
|
||||
testChannel(testChannel)
|
||||
{
|
||||
}
|
||||
|
||||
string TestChannelPut::getRequesterName() {return "TestChannelPut";}
|
||||
|
||||
void TestChannelPut::channelPutConnect(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
Structure::const_shared_pointer const & structure)
|
||||
{
|
||||
pvStructure = PVDataCreate::getPVDataCreate()->createPVStructure(structure);
|
||||
bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
|
||||
waitForConnect.signal();
|
||||
}
|
||||
|
||||
void TestChannelPut::getDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet)
|
||||
{
|
||||
throw std::runtime_error("TestChannelPut::getDone should not be called");
|
||||
}
|
||||
|
||||
void TestChannelPut::putDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut)
|
||||
{
|
||||
TestChannelPutRequesterPtr req(putRequester.lock());
|
||||
if(!req) return;
|
||||
if(status.isOK()) {
|
||||
req->putDone();
|
||||
return;
|
||||
}
|
||||
string message = string("channel ")
|
||||
+ testChannel->getChannelName()
|
||||
+ " TestChannelPut::putDone "
|
||||
+ status.getMessage();
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
void TestChannelPut::connect()
|
||||
{
|
||||
string request("value");
|
||||
PVStructurePtr pvRequest(createRequest(request));
|
||||
|
||||
channelPut = testChannel->getChannel()->createChannelPut(shared_from_this(),pvRequest);
|
||||
if(!channelPut) throw std::runtime_error(testChannel->getChannelName() + " channelCreate failed ");
|
||||
}
|
||||
|
||||
void TestChannelPut::waitConnect(double timeout)
|
||||
{
|
||||
if(waitForConnect.wait(timeout)) return;
|
||||
throw std::runtime_error(testChannel->getChannelName() + " TestChannelPut::waitConnect failed ");
|
||||
}
|
||||
|
||||
|
||||
void TestChannelPut::put(string const & value)
|
||||
{
|
||||
PVFieldPtr pvField(pvStructure->getSubField("value"));
|
||||
if(!pvField) throw std::runtime_error(testChannel->getChannelName() + " TestChannelPut::put no value ");
|
||||
FieldConstPtr field(pvField->getField());
|
||||
Type type(field->getType());
|
||||
if(type==scalar) {
|
||||
PVScalarPtr pvScalar(std::tr1::static_pointer_cast<PVScalar>(pvField));
|
||||
getConvert()->fromString(pvScalar,value);
|
||||
bitSet->set(pvField->getFieldOffset());
|
||||
channelPut->put(pvStructure,bitSet);
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error(testChannel->getChannelName() + " TestChannelPut::put not supported type");
|
||||
}
|
||||
|
||||
class TestChannelMonitor;
|
||||
typedef std::tr1::shared_ptr<TestChannelMonitor> TestChannelMonitorPtr;
|
||||
|
||||
class TestChannelMonitorRequester;
|
||||
typedef std::tr1::shared_ptr<TestChannelMonitorRequester> TestChannelMonitorRequesterPtr;
|
||||
typedef std::tr1::weak_ptr<TestChannelMonitorRequester> TestChannelMonitorRequesterWPtr;
|
||||
|
||||
class TestChannelMonitorRequester
|
||||
{
|
||||
public:
|
||||
virtual void monitorEvent(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet) = 0;
|
||||
};
|
||||
|
||||
class TestChannelMonitor:
|
||||
public MonitorRequester,
|
||||
public std::tr1::enable_shared_from_this<TestChannelMonitor>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TestChannelMonitor);
|
||||
virtual string getRequesterName();
|
||||
virtual void message(string const & message, MessageType messageType) {}
|
||||
virtual void monitorConnect(
|
||||
Status const & status,
|
||||
MonitorPtr const & monitor,
|
||||
StructureConstPtr const & structure);
|
||||
virtual void monitorEvent(MonitorPtr const & monitor);
|
||||
virtual void unlisten(MonitorPtr const & monitor);
|
||||
static TestChannelMonitorPtr create(
|
||||
TestChannelMonitorRequesterPtr const &putRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest);
|
||||
void connect();
|
||||
void waitConnect(double timeout);
|
||||
void stopEvents();
|
||||
private:
|
||||
TestChannelMonitor(
|
||||
TestChannelMonitorRequesterPtr const &putRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest);
|
||||
|
||||
TestChannelMonitorRequesterWPtr monitorRequester;
|
||||
TestChannelPtr testChannel;
|
||||
PVStructurePtr pvRequest;
|
||||
Event waitForConnect;
|
||||
Monitor::shared_pointer channelMonitor;
|
||||
};
|
||||
|
||||
TestChannelMonitorPtr TestChannelMonitor::create(
|
||||
TestChannelMonitorRequesterPtr const &monitorRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest)
|
||||
{
|
||||
TestChannelMonitorPtr testChannelMonitor(new TestChannelMonitor(monitorRequester,testChannel,pvRequest));
|
||||
testChannelMonitor->connect();
|
||||
testChannelMonitor->waitConnect(5.0);
|
||||
return testChannelMonitor;
|
||||
}
|
||||
|
||||
TestChannelMonitor::TestChannelMonitor(
|
||||
TestChannelMonitorRequesterPtr const &monitorRequester,
|
||||
TestChannelPtr const &testChannel,
|
||||
PVStructurePtr const & pvRequest)
|
||||
: monitorRequester(monitorRequester),
|
||||
testChannel(testChannel),
|
||||
pvRequest(pvRequest)
|
||||
{
|
||||
}
|
||||
|
||||
string TestChannelMonitor::getRequesterName() {return "TestChannelMonitor";}
|
||||
|
||||
void TestChannelMonitor::monitorConnect(
|
||||
Status const & status,
|
||||
MonitorPtr const & monitor,
|
||||
StructureConstPtr const & structure)
|
||||
{
|
||||
waitForConnect.signal();
|
||||
}
|
||||
|
||||
|
||||
void TestChannelMonitor::monitorEvent(MonitorPtr const & monitor)
|
||||
{
|
||||
TestChannelMonitorRequesterPtr req(monitorRequester.lock());
|
||||
if(!req) return;
|
||||
while(true) {
|
||||
MonitorElementPtr monitorElement = monitor->poll();
|
||||
if(!monitorElement) return;
|
||||
req->monitorEvent(monitorElement->pvStructurePtr,monitorElement->changedBitSet);
|
||||
monitor->release(monitorElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TestChannelMonitor::unlisten(MonitorPtr const & monitor)
|
||||
{
|
||||
}
|
||||
|
||||
void TestChannelMonitor::connect()
|
||||
{
|
||||
channelMonitor = testChannel->getChannel()->createMonitor(shared_from_this(),pvRequest);
|
||||
if(!channelMonitor) throw std::runtime_error(testChannel->getChannelName() + " TestChannelMonitor::connect failed ");
|
||||
}
|
||||
|
||||
void TestChannelMonitor::waitConnect(double timeout)
|
||||
{
|
||||
if(waitForConnect.wait(timeout)) {
|
||||
channelMonitor->start();
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error(testChannel->getChannelName() + " TestChannelMonitor::waitConnect failed ");
|
||||
}
|
||||
|
||||
void TestChannelMonitor::stopEvents()
|
||||
{
|
||||
channelMonitor->stop();
|
||||
}
|
||||
|
||||
class TestClient;
|
||||
typedef std::tr1::shared_ptr<TestClient> TestClientPtr;
|
||||
|
||||
class TestClient:
|
||||
public TestChannelGetRequester,
|
||||
public TestChannelPutRequester,
|
||||
public TestChannelMonitorRequester,
|
||||
public std::tr1::enable_shared_from_this<TestClient>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TestClient);
|
||||
virtual void getDone(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet);
|
||||
virtual void putDone();
|
||||
virtual void monitorEvent(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet);
|
||||
static TestClientPtr create(string const &channelName,PVStructurePtr const & pvRequest);
|
||||
void connect();
|
||||
void get();
|
||||
void put(string const & value);
|
||||
void waitGet(double timeout);
|
||||
void waitPut(double timeout);
|
||||
void stopEvents();
|
||||
private:
|
||||
TestClient(string const &channelName,PVStructurePtr const & pvRequest);
|
||||
string channelName;
|
||||
PVStructurePtr pvRequest;
|
||||
TestChannelPtr testChannel;
|
||||
TestChannelGetPtr testChannelGet;
|
||||
TestChannelPutPtr testChannelPut;
|
||||
TestChannelMonitorPtr testChannelMonitor;
|
||||
Event waitForGet;
|
||||
Event waitForPut;
|
||||
};
|
||||
|
||||
TestClientPtr TestClient::create(string const &channelName,PVStructurePtr const & pvRequest)
|
||||
{
|
||||
TestClientPtr testClient(new TestClient(channelName,pvRequest));
|
||||
testClient->connect();
|
||||
return testClient;
|
||||
}
|
||||
|
||||
TestClient::TestClient(string const &channelName,PVStructurePtr const & pvRequest)
|
||||
: channelName(channelName),
|
||||
pvRequest(pvRequest)
|
||||
{
|
||||
}
|
||||
|
||||
void TestClient::connect()
|
||||
{
|
||||
testChannel = TestChannel::create(channelName);
|
||||
testChannelGet = TestChannelGet::create(shared_from_this(),testChannel,pvRequest);
|
||||
testChannelPut = TestChannelPut::create(shared_from_this(),testChannel);
|
||||
testChannelMonitor = TestChannelMonitor::create(shared_from_this(),testChannel,pvRequest);
|
||||
}
|
||||
|
||||
void TestClient::getDone(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet)
|
||||
{
|
||||
testOk(pvStructure!=NULL,"pvStructure not null");
|
||||
testOk(pvStructure->getSubField("value")!=NULL,"value not null");
|
||||
testOk(pvStructure->getSubField("timeStamp")!=NULL,"timeStamp not null");
|
||||
testOk(pvStructure->getSubField("alarm")!=NULL,"alarm not null");
|
||||
waitForGet.signal();
|
||||
}
|
||||
|
||||
void TestClient::putDone()
|
||||
{
|
||||
waitForPut.signal();
|
||||
}
|
||||
|
||||
void TestClient::monitorEvent(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet)
|
||||
{
|
||||
std::cout << testChannel->getChannelName() + " TestClient::monitorEvent"
|
||||
<< " bitSet " << *bitSet
|
||||
<< " pvStructure\n" << pvStructure << "\n";
|
||||
}
|
||||
|
||||
void TestClient::get()
|
||||
{
|
||||
testChannelGet->get();
|
||||
waitGet(5.0);
|
||||
}
|
||||
|
||||
void TestClient::waitGet(double timeout)
|
||||
{
|
||||
if(waitForGet.wait(timeout)) return;
|
||||
throw std::runtime_error(testChannel->getChannelName() + " TestClient::waitGet failed ");
|
||||
}
|
||||
|
||||
void TestClient::put(string const & value)
|
||||
{
|
||||
testChannelPut->put(value);
|
||||
waitPut(5.0);
|
||||
}
|
||||
|
||||
void TestClient::waitPut(double timeout)
|
||||
{
|
||||
if(waitForPut.wait(timeout)) return;
|
||||
throw std::runtime_error(testChannel->getChannelName() + " TestClient::waitPut failed ");
|
||||
}
|
||||
|
||||
void TestClient::stopEvents()
|
||||
{
|
||||
testChannelMonitor->stopEvents();
|
||||
}
|
||||
|
||||
class TestIoc;
|
||||
typedef std::tr1::shared_ptr<TestIoc> TestIocPtr;
|
||||
|
||||
class TestIoc :
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
virtual void run();
|
||||
static TestIocPtr create();
|
||||
void start();
|
||||
private:
|
||||
std::auto_ptr<epicsThread> thread;
|
||||
};
|
||||
|
||||
TestIocPtr TestIoc::create()
|
||||
{
|
||||
return TestIocPtr(new TestIoc());
|
||||
}
|
||||
|
||||
void TestIoc::start()
|
||||
{
|
||||
thread = std::auto_ptr<epicsThread>(new epicsThread(
|
||||
*this,
|
||||
"testIoc",
|
||||
epicsThreadGetStackSize(epicsThreadStackSmall),
|
||||
epicsThreadPriorityLow));
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void TestIoc::run()
|
||||
{
|
||||
system("softIoc -d ../ca/testCaProvider.db");
|
||||
}
|
||||
|
||||
MAIN(testCaProvider)
|
||||
{
|
||||
testPlan(11);
|
||||
testDiag("===Test caProvider===");
|
||||
CAClientFactory::start();
|
||||
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
|
||||
ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca"));
|
||||
try{
|
||||
TestIocPtr testIoc(new TestIoc());
|
||||
testIoc->start();
|
||||
if(!channelProvider) {
|
||||
throw std::runtime_error(" provider ca not registered");
|
||||
}
|
||||
string channelName;
|
||||
channelName = "DBRdoubleout";
|
||||
string request("value,alarm,timeStamp");
|
||||
PVStructurePtr pvRequest(createRequest(request));
|
||||
TestClientPtr scalarout(TestClient::create(channelName,pvRequest));
|
||||
testOk(scalarout!=NULL,"DBRdoubleout not null");
|
||||
scalarout->put("1.5");
|
||||
scalarout->get();
|
||||
scalarout->stopEvents();
|
||||
channelName = "DBRstringout";
|
||||
scalarout = TestClient::create(channelName,pvRequest);
|
||||
testOk(scalarout!=NULL,"DBRstringout not null");
|
||||
scalarout->put("test");
|
||||
scalarout->get();
|
||||
scalarout->stopEvents();
|
||||
// put to record that makes IOC exit
|
||||
channelName = "DBRexit";
|
||||
scalarout = TestClient::create(channelName,pvRequest);
|
||||
testOk(scalarout!=NULL,"DBRexit not null");
|
||||
scalarout->put("1");
|
||||
}catch(std::exception& e){
|
||||
PRINT_EXCEPTION(e);
|
||||
testAbort("Unexpected Exception: %s", e.what());
|
||||
}
|
||||
return testDone();;
|
||||
}
|
||||
|
||||
290
testApp/ca/testCaProvider.db
Normal file
290
testApp/ca/testCaProvider.db
Normal file
@@ -0,0 +1,290 @@
|
||||
|
||||
record(calcout, "DBRcalcout")
|
||||
{
|
||||
field(DESC, "calcout")
|
||||
field(CALC, "(A<B)?(A+C):D")
|
||||
field(INPA, "DBRcalcout.VAL NPP NMS")
|
||||
field(INPB, "9")
|
||||
field(INPC, "1")
|
||||
field(INPD, "0")
|
||||
field(EGU, "Counts")
|
||||
field(HOPR, "10")
|
||||
field(HIHI, "8")
|
||||
field(HIGH, "6")
|
||||
field(LOW, "4")
|
||||
field(LOLO, "2")
|
||||
field(HHSV, "MAJOR")
|
||||
field(HSV, "MINOR")
|
||||
field(LSV, "MINOR")
|
||||
field(LLSV, "MAJOR")
|
||||
}
|
||||
|
||||
record(calc, "DBRcalcin")
|
||||
{
|
||||
field(DESC, "calcin")
|
||||
field(CALC, "(A<B)?(A+C):D")
|
||||
field(INPA, "DBRcalcin.VAL NPP NMS")
|
||||
field(INPB, "9")
|
||||
field(INPC, "1")
|
||||
field(INPD, "0")
|
||||
field(EGU, "Counts")
|
||||
field(HOPR, "10")
|
||||
field(HIHI, "8")
|
||||
field(HIGH, "6")
|
||||
field(LOW, "4")
|
||||
field(LOLO, "2")
|
||||
field(HHSV, "MAJOR")
|
||||
field(HSV, "MINOR")
|
||||
field(LSV, "MINOR")
|
||||
field(LLSV, "MAJOR")
|
||||
}
|
||||
|
||||
record(sub, "DBRexit")
|
||||
{
|
||||
field(DESC, "exit")
|
||||
field(SNAM, "exit")
|
||||
}
|
||||
|
||||
record(longin,"DBRlongin") {
|
||||
field(DESC, "longin")
|
||||
field(EGU, "volts")
|
||||
field(HIHI, "80")
|
||||
field(HIGH, "60")
|
||||
field(LOW, "-60")
|
||||
field(LOLO, "-80")
|
||||
field(HYST, "2")
|
||||
field(HHSV, "MAJOR")
|
||||
field(HSV, "MINOR")
|
||||
field(LSV, "MINOR")
|
||||
field(LLSV, "MAJOR")
|
||||
field(HOPR, "2147483647")
|
||||
field(LOPR, "-2147483648")
|
||||
}
|
||||
|
||||
record(longout,"DBRlongout") {
|
||||
field(DESC, "longout")
|
||||
field(EGU, "volts")
|
||||
field(HIHI, "80")
|
||||
field(HIGH, "60")
|
||||
field(LOW, "-60")
|
||||
field(LOLO, "-80")
|
||||
field(HYST, "2")
|
||||
field(HHSV, "MAJOR")
|
||||
field(HSV, "MINOR")
|
||||
field(LSV, "MINOR")
|
||||
field(LLSV, "MAJOR")
|
||||
field(HOPR, "2147483647")
|
||||
field(LOPR, "-2147483648")
|
||||
field(DRVH, "2147483647")
|
||||
field(DRVL, "-2147483648")
|
||||
}
|
||||
|
||||
record(ao,"DBRdoubleout") {
|
||||
field(DESC, "ao")
|
||||
field(PREC,"2")
|
||||
field(EGUF,"10.0")
|
||||
field(EGUL,"-10.0")
|
||||
field(EGU, "volts")
|
||||
field(HIHI, "8")
|
||||
field(HIGH, "6")
|
||||
field(LOW, "-6")
|
||||
field(LOLO, "-8")
|
||||
field(HYST, ".1")
|
||||
field(HHSV, "MAJOR")
|
||||
field(HSV, "MINOR")
|
||||
field(LSV, "MINOR")
|
||||
field(LLSV, "MAJOR")
|
||||
field(HOPR, "10.0")
|
||||
field(LOPR, "-10.0")
|
||||
field(DRVH, "1e29")
|
||||
field(DRVL, "-1e29")
|
||||
}
|
||||
|
||||
record(ai,"DBRdoublein") {
|
||||
field(DESC, "ai")
|
||||
field(PREC,"2")
|
||||
field(EGUF,"10.0")
|
||||
field(EGUL,"-10.0")
|
||||
field(EGU, "volts")
|
||||
field(HIHI, "8")
|
||||
field(HIGH, "6")
|
||||
field(LOW, "-6")
|
||||
field(LOLO, "-8")
|
||||
field(HYST, ".1")
|
||||
field(HHSV, "MAJOR")
|
||||
field(HSV, "MINOR")
|
||||
field(LSV, "MINOR")
|
||||
field(LLSV, "MAJOR")
|
||||
field(HOPR, "10.0")
|
||||
field(LOPR, "-10.0")
|
||||
}
|
||||
|
||||
|
||||
record(stringout,"DBRstringout") {
|
||||
field(DESC, "stringout")
|
||||
}
|
||||
|
||||
record(stringin,"DBRstringin") {
|
||||
field(DESC, "stringin")
|
||||
}
|
||||
|
||||
|
||||
record(bo,"DBRbinaryout") {
|
||||
field(DESC, "bo")
|
||||
field(OUT, "DBRbi.VAL PP NMS")
|
||||
field(ZNAM,"zero")
|
||||
field(ONAM,"one")
|
||||
}
|
||||
record(bi,"DBRbinaryin") {
|
||||
field(DESC, "bi")
|
||||
field(ZNAM,"zero")
|
||||
field(ONAM,"one")
|
||||
}
|
||||
|
||||
record(mbbo,"DBRmbbout") {
|
||||
field(DESC, "mbbo")
|
||||
field(VAL,"1")
|
||||
field(ZRVL,"0")
|
||||
field(ONVL,"1")
|
||||
field(TWVL,"2")
|
||||
field(THVL,"3")
|
||||
field(FRVL,"4")
|
||||
field(FVVL,"5")
|
||||
field(SXVL,"6")
|
||||
field(SVVL,"7")
|
||||
field(EIVL,"8")
|
||||
field(NIVL,"9")
|
||||
field(TEVL,"10")
|
||||
field(ELVL,"11")
|
||||
field(TVVL,"12")
|
||||
field(TTVL,"13")
|
||||
field(FTVL,"14")
|
||||
field(FFVL,"15")
|
||||
field(ZRST,"zero")
|
||||
field(ONST,"one")
|
||||
field(TWST,"two")
|
||||
field(THST,"three")
|
||||
field(FRST,"four")
|
||||
field(FVST,"five")
|
||||
field(SXST,"six")
|
||||
field(SVST,"seven")
|
||||
field(EIST,"eight")
|
||||
field(NIST,"nine")
|
||||
field(TEST,"ten")
|
||||
field(ELST,"eleven")
|
||||
field(TVST,"twelve")
|
||||
field(TTST,"thirteen")
|
||||
field(FTST,"fourteen")
|
||||
field(FFST,"fifteen")
|
||||
}
|
||||
|
||||
record(mbbi,"DBRmbbin") {
|
||||
field(DESC, "mbbi")
|
||||
field(VAL,"1")
|
||||
field(ZRVL,"0")
|
||||
field(ONVL,"1")
|
||||
field(TWVL,"2")
|
||||
field(THVL,"3")
|
||||
field(FRVL,"4")
|
||||
field(FVVL,"5")
|
||||
field(SXVL,"6")
|
||||
field(SVVL,"7")
|
||||
field(EIVL,"8")
|
||||
field(NIVL,"9")
|
||||
field(TEVL,"10")
|
||||
field(ELVL,"11")
|
||||
field(TVVL,"12")
|
||||
field(TTVL,"13")
|
||||
field(FTVL,"14")
|
||||
field(FFVL,"15")
|
||||
field(ZRST,"zero")
|
||||
field(ONST,"one")
|
||||
field(TWST,"two")
|
||||
field(THST,"three")
|
||||
field(FRST,"four")
|
||||
field(FVST,"five")
|
||||
field(SXST,"six")
|
||||
field(SVST,"seven")
|
||||
field(EIST,"eight")
|
||||
field(NIST,"nine")
|
||||
field(TEST,"ten")
|
||||
field(ELST,"eleven")
|
||||
field(TVST,"twelve")
|
||||
field(TTST,"thirteen")
|
||||
field(FTST,"fourteen")
|
||||
field(FFST,"fifteen")
|
||||
}
|
||||
|
||||
record(waveform,"DBRbyteArray") {
|
||||
field(DESC, "byteArray")
|
||||
field(NELM,"5")
|
||||
field(FTVL,"CHAR")
|
||||
field(HOPR, "127")
|
||||
field(LOPR, "-128")
|
||||
}
|
||||
|
||||
record(waveform,"DBRshortArray") {
|
||||
field(DESC, "shortArray")
|
||||
field(NELM,"5")
|
||||
field(FTVL,"SHORT")
|
||||
field(HOPR, "32767")
|
||||
field(LOPR, "-32768")
|
||||
}
|
||||
|
||||
record(waveform,"DBRintArray") {
|
||||
field(DESC, "intArray")
|
||||
field(NELM,"5")
|
||||
field(FTVL,"LONG")
|
||||
field(HOPR, "2147483647")
|
||||
field(LOPR, "-2147483648")
|
||||
}
|
||||
|
||||
record(waveform,"DBRubyteArray") {
|
||||
field(DESC, "ubyteArray")
|
||||
field(NELM,"5")
|
||||
field(FTVL,"UCHAR")
|
||||
field(HOPR, "255")
|
||||
field(LOPR, "0")
|
||||
}
|
||||
|
||||
|
||||
record(waveform,"DBRushortArray") {
|
||||
field(DESC, "ushortArray")
|
||||
field(NELM,"5")
|
||||
field(FTVL,"USHORT")
|
||||
field(HOPR, "65535")
|
||||
field(LOPR, "0")
|
||||
}
|
||||
|
||||
record(waveform,"DBRuintArray") {
|
||||
field(DESC, "uintArray")
|
||||
field(NELM,"5")
|
||||
field(FTVL,"ULONG")
|
||||
field(HOPR, "2147483647")
|
||||
field(LOPR, "-2147483648")
|
||||
}
|
||||
|
||||
|
||||
record(waveform,"DBRstringArray") {
|
||||
field(DESC, "stringArray")
|
||||
field(NELM,"5")
|
||||
field(FTVL,"STRING")
|
||||
}
|
||||
|
||||
record(waveform,"DBRfloatArray") {
|
||||
field(DESC, "floatArray")
|
||||
field(NELM,"5")
|
||||
field(PREC,"2")
|
||||
field(FTVL,"FLOAT")
|
||||
field(HOPR, "1000")
|
||||
field(LOPR, "-1000")
|
||||
}
|
||||
|
||||
record(waveform,"DBRdoubleArray") {
|
||||
field(DESC, "doubleArray")
|
||||
field(NELM,"5")
|
||||
field(PREC,"2")
|
||||
field(FTVL,"DOUBLE")
|
||||
field(HOPR, "1000")
|
||||
field(LOPR, "-1000")
|
||||
}
|
||||
@@ -19,6 +19,9 @@ int testInetAddressUtils(void);
|
||||
int testCodec(void);
|
||||
int testChannelAccess(void);
|
||||
|
||||
/* ca */
|
||||
int testCaProvider(void);
|
||||
|
||||
void pvAccessAllTests(void)
|
||||
{
|
||||
testHarness();
|
||||
@@ -31,6 +34,8 @@ void pvAccessAllTests(void)
|
||||
/* remote */
|
||||
runTest(testCodec);
|
||||
runTest(testChannelAccess);
|
||||
/* ca */
|
||||
runTest(testCaProvider);
|
||||
|
||||
epicsExit(0); /* Trigger test harness */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user