add check_consist demo/test

This commit is contained in:
Michael Davidsaver
2016-03-20 13:31:38 -04:00
parent 045a3d94b3
commit 160d29e7b0
5 changed files with 155 additions and 0 deletions

View File

@ -50,6 +50,9 @@ testpdb_SRCS += p2pTestIoc_registerRecordDeviceDriver.cpp
testpdb_LIBS += testutils pdbcore pvAccess pvData $(EPICS_BASE_IOC_LIBS)
TESTS += testpdb
PROD_HOST += check_consist
check_consist_SRCS += check_consist.cpp
check_consist_LIBS += testutils pvAccess pvData Com
TESTSCRIPTS_HOST += $(TESTS:%=%.t)

101
testApp/check_consist.cpp Normal file
View File

@ -0,0 +1,101 @@
#include <pv/clientFactory.h>
#include "utilities.h"
namespace pvd = epics::pvData;
namespace pva = epics::pvAccess;
namespace {
struct Destroyer {
pvd::Destroyable::shared_pointer D;
Destroyer(const pvd::Destroyable::shared_pointer& d) : D(d) {}
~Destroyer() { if(D) D->destroy(); }
};
struct Releaser {
pva::Monitor::shared_pointer& mon;
pva::MonitorElementPtr& elem;
Releaser(pva::Monitor::shared_pointer& m, pva::MonitorElementPtr& e)
:mon(m), elem(e)
{}
~Releaser() { mon->release(elem); }
};
} // namespace
int main(int argc, char *argv[])
{
testPlan(0);
try {
if(argc<4) {
std::cerr<<"Usage: "<<argv[0]<<" <channel> <fld1> <fld2> ...";
return 1;
}
pvd::StructureConstPtr reqdesc(pvd::getFieldCreate()->createFieldBuilder()
->add("unused", pvd::pvBoolean)
->createStructure());
pvd::PVStructurePtr pvreq(pvd::getPVDataCreate()->createPVStructure(reqdesc));
pva::ClientFactory::start();
pva::ChannelProvider::shared_pointer prov(pva::getChannelProviderRegistry()->getProvider("pva"));
if(!prov) throw std::runtime_error("No pva provider?!?");
Destroyer prov_d(prov);
TestChannelRequester::shared_pointer chreq(new TestChannelRequester);
pva::Channel::shared_pointer chan(prov->createChannel(argv[1], chreq));
Destroyer chan_d(chan);
if(!chan) throw std::runtime_error("Failed to create channel");
std::cout<<"Connecting...\n";
if(!chreq->waitForConnect())
throw std::runtime_error("Failed to connect channel");
TestChannelMonitorRequester::shared_pointer monreq(new TestChannelMonitorRequester);
pva::Monitor::shared_pointer mon(chan->createMonitor(monreq, pvreq));
Destroyer mon_d(mon);
if(!mon) throw std::runtime_error("Failed to create monitor");
if(!monreq->waitForConnect())
throw std::runtime_error("failed to connect monitor");
if(!mon->start().isSuccess())
throw std::runtime_error("failed to start monitor");
std::cout<<"Wait for initial event...\n";
while(monreq->waitForEvent()) {
pva::MonitorElementPtr elem;
while(!!(elem=mon->poll())) {
Releaser R(mon, elem);
pvd::PVStructurePtr A, B;
A = elem->pvStructurePtr->getSubField<pvd::PVStructure>("a");
B = elem->pvStructurePtr->getSubField<pvd::PVStructure>("b");
if(!A || !B)
throw std::runtime_error("unexpected types");
epicsUInt32 vA = A->getSubFieldT<pvd::PVScalar>("value")->getAs<pvd::uint32>(),
vB = B->getSubFieldT<pvd::PVScalar>("value")->getAs<pvd::uint32>();
epicsUInt64 tsA = A->getSubFieldT<pvd::PVScalar>("timeStamp.secondsPastEpoch")->getAs<pvd::uint64>(),
tsB = B->getSubFieldT<pvd::PVScalar>("timeStamp.secondsPastEpoch")->getAs<pvd::uint64>();
epicsUInt32 tnA = A->getSubFieldT<pvd::PVScalar>("timeStamp.nanoseconds")->getAs<pvd::uint32>(),
tnB = B->getSubFieldT<pvd::PVScalar>("timeStamp.nanoseconds")->getAs<pvd::uint32>();
if(vA==vB && tsA==tsB && tnA==tnB) {
std::cout<<".";
continue;
}
std::cout<<"\nMismatch:\nA:\n"<<*A<<"B:\n"<<*B<<"\n";
}
}
std::cout<<"Done\n";
return 0;
}catch(std::exception&e){
PRINT_EXCEPTION(e);
std::cerr<<"Error: "<<e.what()<<"\n";
return 1;
}
}

40
testApp/check_consist.db Normal file
View File

@ -0,0 +1,40 @@
record(calc, "cnt:x") {
field(INPA, "cnt:x NPP")
field(INPB, "999999")
field(CALC, "A<B?A+1:0")
field(SCAN, "1 second")
# field(PINI, "RUNNING")
field(HOPR, "1000000")
field(HIGH, "5")
field(HSV , "MINOR")
field(EGU , "arb.")
field(PREC, "1")
field(FLNK, "cnt:y")
info(pdbGroup, "grp|a=VAL")
# field(TPRO, "1")
}
record(calc, "cnt:y") {
field(INPA, "cnt:y NPP")
field(INPB, "cnt:x.B NPP")
field(CALC, "A<B?A+1:0")
field(HOPR, "10000")
field(HIGH, "5")
field(HSV , "MINOR")
field(EGU , "arb.")
field(PREC, "1")
field(TSEL, "cnt:x.TIME")
field(FLNK, "cnt:x.PROC CA")
info(pdbGroup, "grp|b=VAL")
info(pdbTrigger, "grp|b>*")
}
record(calc, "cnt:rate") {
field(INPA, "cnt:x NPP")
field(CALC, "C:=A-B;B:=A;C/10")
field(SCAN, ".1 second")
field(EGU , "cnt/s")
}

View File

@ -186,6 +186,16 @@ void TestChannelMonitorRequester::unlisten(pvd::MonitorPtr const & monitor)
wait.trigger();
}
bool TestChannelMonitorRequester::waitForConnect()
{
Guard G(lock);
while(!connected) {
UnGuard U(G);
wait.wait();
}
return true;
}
bool TestChannelMonitorRequester::waitForEvent()
{
Guard G(lock);

View File

@ -218,6 +218,7 @@ struct TestChannelMonitorRequester : public epics::pvData::MonitorRequester
virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor);
virtual void unlisten(epics::pvData::MonitorPtr const & monitor);
bool waitForConnect();
bool waitForEvent();
};