// Test the testing utilities #include #include #include #include #include #include "utilities.h" typedef epicsGuard Guard; typedef epicsGuardRelease UnGuard; namespace pvd = epics::pvData; namespace pva = epics::pvAccess; namespace { void testmonitor() { testDiag("Test Test* monitoring"); pvd::FieldCreatePtr fieldCreate(pvd::getFieldCreate()); pvd::PVDataCreatePtr create(pvd::getPVDataCreate()); testDiag("Setup TestProvider with \"test\""); TestProvider::shared_pointer prov(new TestProvider); TestPV::shared_pointer pv(prov->addPV("test", fieldCreate->createFieldBuilder() ->add("x", pvd::pvInt) ->add("y", pvd::pvInt) ->createStructure())); ScalarAccessor x(pv->value, "x"); x = 42; testDiag("Create channel"); TestChannelRequester::shared_pointer creq(new TestChannelRequester); pva::Channel::shared_pointer chan(prov->createChannel("test", creq)); testOk1(!!chan.get()); testOk1(creq->waitForConnect()); testOk1(chan==creq->chan); if(!chan) testAbort("Create channel failed"); testDiag("Create monitor"); TestChannelMonitorRequester::shared_pointer mreq(new TestChannelMonitorRequester); pvd::Monitor::shared_pointer mon; { pvd::PVStructurePtr pvreq(create->createPVStructure(fieldCreate->createFieldBuilder() ->add("junk", pvd::pvInt) ->createStructure())); mon = chan->createMonitor(mreq, pvreq); } testOk1(!!mon.get()); testOk1(mreq->connectStatus.isSuccess()); testOk1(!!mreq->dtype.get()); testOk1(mreq->eventCnt==0); if(!mon) testAbort("Create monitor failed"); testDiag("ensure queue is initially empty"); testOk1(!mon->poll()); testDiag("Start monitor and check initial update"); testOk1(mon->start().isSuccess()); pvd::MonitorElementPtr elem(mon->poll()); testOk1(!!elem.get()); testOk1(elem && elem->pvStructurePtr->getSubFieldT("x")->get()==42); testOk1(elem && elem->changedBitSet->nextSetBit(0)==0); // initial update shows all changed testOk1(elem && elem->changedBitSet->nextSetBit(1)==-1); testOk1(elem && elem->overrunBitSet->isEmpty()); if(elem) mon->release(elem); testDiag("ensure start() queues only one"); testOk1(!mon->poll()); testDiag("Change a field"); x = 43; pvd::BitSet changed; changed.set(1); pv->post(changed); testOk1(mreq->eventCnt==1); elem = mon->poll(); testOk1(!!elem.get()); testOk1(elem && elem->pvStructurePtr->getSubFieldT("x")->get()==43); testOk1(elem && elem->changedBitSet->nextSetBit(0)==1); testOk1(elem && elem->changedBitSet->nextSetBit(2)==-1); testOk1(elem && elem->overrunBitSet->isEmpty()); if(elem) mon->release(elem); testDiag("ensure queues are empty"); testOk1(!mon->poll()); testDiag("overflow queue"); x = 44; pv->post(changed, false); x = 45; pv->post(changed, false); x = 46; pv->post(changed, false); testOk1(mreq->eventCnt==1); x = 47; pv->post(changed); testOk1(mreq->eventCnt==2); elem = mon->poll(); testOk1(!!elem.get()); testOk1(elem && elem->pvStructurePtr->getSubFieldT("x")->get()==44); testOk1(elem && elem->changedBitSet->nextSetBit(0)==1); testOk1(elem && elem->overrunBitSet->isEmpty()); if(elem) mon->release(elem); // overflow element is queued here elem = mon->poll(); testOk1(!!elem.get()); testOk1(elem && elem->pvStructurePtr->getSubFieldT("x")->get()==45); testOk1(elem && elem->changedBitSet->nextSetBit(0)==1); testOk1(elem && elem->overrunBitSet->isEmpty()); if(elem) mon->release(elem); elem = mon->poll(); testOk1(!!elem.get()); testOk1(elem && elem->pvStructurePtr->getSubFieldT("x")->get()==47); testOk1(elem && elem->changedBitSet->nextSetBit(0)==1); testOk1(elem && elem->overrunBitSet->nextSetBit(0)==1); testOk1(elem && elem->overrunBitSet->nextSetBit(2)==-1); if(elem) mon->release(elem); testDiag("ensure queues are empty"); testOk1(!mon->poll()); testOk1(mreq->eventCnt==2); mon->destroy(); chan->destroy(); } } // namespace MAIN(testtest) { testPlan(0); testmonitor(); TestProvider::testCounts(); return testDone(); }