monitoring test infrastructure
This commit is contained in:
176
testApp/testtest.cpp
Normal file
176
testApp/testtest.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
// Test the testing utilities
|
||||
|
||||
#include <epicsGuard.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
#include <pv/monitor.h>
|
||||
#include <pv/thread.h>
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
typedef epicsGuard<epicsMutex> Guard;
|
||||
typedef epicsGuardRelease<epicsMutex> UnGuard;
|
||||
|
||||
namespace pvd = epics::pvData;
|
||||
namespace pva = epics::pvAccess;
|
||||
|
||||
namespace {
|
||||
template<typename T>
|
||||
struct ScalarAccessor {
|
||||
pvd::PVScalar::shared_pointer field;
|
||||
typedef T value_type;
|
||||
ScalarAccessor(const pvd::PVStructurePtr& s, const char *name)
|
||||
:field(s->getSubFieldT<pvd::PVScalar>(name))
|
||||
{}
|
||||
operator value_type() {
|
||||
return field->getAs<T>();
|
||||
}
|
||||
ScalarAccessor& operator=(T v) {
|
||||
field->putFrom<T>(v);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
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<pvd::int32> 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<pvd::PVInt>("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<pvd::PVInt>("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<pvd::PVInt>("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<pvd::PVInt>("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<pvd::PVInt>("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();
|
||||
return testDone();
|
||||
}
|
||||
Reference in New Issue
Block a user