From 3cd09efa0add7dba4e796b357873ca2d37f41d46 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 29 Jan 2016 15:01:37 -0500 Subject: [PATCH] more test --- testApp/testmon.cpp | 55 ++++++++++++++++++++++--------- testApp/testtest.cpp | 1 + testApp/utilities.cpp | 77 ++++++++++++++++++++++++++++++++++++++++--- testApp/utilities.h | 25 ++++++++++++-- 4 files changed, 135 insertions(+), 23 deletions(-) diff --git a/testApp/testmon.cpp b/testApp/testmon.cpp index 9da37fa..1a36d2a 100644 --- a/testApp/testmon.cpp +++ b/testApp/testmon.cpp @@ -64,6 +64,12 @@ struct TestMonitor { test1_y = 2; } + ~TestMonitor() + { + client->destroy(); + gateway->destroy(); // noop atm. + } + void test_event() { testDiag("Push the initial event through from upstream to downstream"); @@ -82,6 +88,10 @@ struct TestMonitor { testOk1(elem && elem->pvStructurePtr->getSubFieldT("x")->get()==1); if(elem) mon->release(elem); + + testOk1(!!mon->poll()); + + mon->destroy(); } void test_share() @@ -119,24 +129,38 @@ struct TestMonitor { if(elem) mon->release(elem); if(elem2) mon2->release(elem2); + + testOk1(!!mon->poll()); + testOk1(!!mon2->poll()); + + testDiag("explicitly push an update"); + test1_x = 42; + test1_y = 43; + pvd::BitSet changed; + changed.set(1); // only indicate that 'x' changed + test1->post(changed); + + elem = mon->poll(); + elem2 = mon2->poll(); + testOk1(!!elem.get()); + testOk1(!!elem2.get()); + testOk1(elem!=elem2); + testOk1(elem && elem->pvStructurePtr->getSubFieldT("x")->get()==42); + testOk1(elem && elem->pvStructurePtr->getSubFieldT("y")->get()==2); + testOk1(elem2 && elem2->pvStructurePtr->getSubFieldT("x")->get()==42); + testOk1(elem2 && elem2->pvStructurePtr->getSubFieldT("y")->get()==2); + + if(elem) mon->release(elem); + if(elem2) mon2->release(elem2); + + testOk1(!!mon->poll()); + testOk1(!!mon2->poll()); + + mon->destroy(); + mon2->destroy(); } }; -template -void test_method(const char *kname, const char *mname) -{ - try { - testDiag("------- %s::%s --------", kname, mname); - C inst; - (inst.*M)(); - } catch(std::exception& e) { - PRINT_EXCEPTION(e); - testAbort("unexpected exception: %s", e.what()); - } -} - -#define TEST_METHOD(klass, method) test_method(#klass, #method) - } // namespace MAIN(testmon) @@ -144,5 +168,6 @@ MAIN(testmon) testPlan(0); TEST_METHOD(TestMonitor, test_event); TEST_METHOD(TestMonitor, test_share); + TestProvider::testCounts(); return testDone(); } diff --git a/testApp/testtest.cpp b/testApp/testtest.cpp index af0b9f5..fbe12f4 100644 --- a/testApp/testtest.cpp +++ b/testApp/testtest.cpp @@ -157,5 +157,6 @@ MAIN(testtest) { testPlan(0); testmonitor(); + TestProvider::testCounts(); return testDone(); } diff --git a/testApp/utilities.cpp b/testApp/utilities.cpp index 2e979b7..5f9c823 100644 --- a/testApp/utilities.cpp +++ b/testApp/utilities.cpp @@ -1,4 +1,6 @@ +#include + #include #include @@ -12,9 +14,19 @@ namespace { int debugdebug = getenv("TEST_EXTRA_DEBUG")!=NULL; } +static size_t countTestChannelRequester; + TestChannelRequester::TestChannelRequester() :laststate(pva::Channel::NEVER_CONNECTED) -{} +{ + epicsAtomicIncrSizeT(&countTestChannelRequester); +} + + +TestChannelRequester::~TestChannelRequester() +{ + epicsAtomicDecrSizeT(&countTestChannelRequester); +} void TestChannelRequester::channelCreated(const pvd::Status& status, pva::Channel::shared_pointer const & channel) { @@ -58,11 +70,20 @@ bool TestChannelRequester::waitForConnect() } +static size_t countTestChannelMonitorRequester; + TestChannelMonitorRequester::TestChannelMonitorRequester() :connected(false) ,unlistend(false) ,eventCnt(0) -{} +{ + epicsAtomicIncrSizeT(&countTestChannelMonitorRequester); +} + +TestChannelMonitorRequester::~TestChannelMonitorRequester() +{ + epicsAtomicDecrSizeT(&countTestChannelMonitorRequester); +} void TestChannelMonitorRequester::monitorConnect(pvd::Status const & status, pvd::MonitorPtr const & monitor, @@ -106,18 +127,23 @@ bool TestChannelMonitorRequester::waitForEvent() return !unlistend; } +static size_t countTestPVChannel; + TestPVChannel::TestPVChannel(const std::tr1::shared_ptr &pv, const std::tr1::shared_ptr &req) :pv(pv) ,requester(req) ,state(CONNECTED) -{} +{ + epicsAtomicIncrSizeT(&countTestPVChannel); +} TestPVChannel::~TestPVChannel() { Guard G(pv->provider->lock); if(requester) testDiag("Warning: TestPVChannel dropped w/o destroy()"); + epicsAtomicDecrSizeT(&countTestPVChannel); } void TestPVChannel::destroy() @@ -242,6 +268,8 @@ TestPVChannel::createChannelArray( return ret; } +static size_t countTestPVMonitor; + TestPVMonitor::TestPVMonitor(const TestPVChannel::shared_pointer& ch, const pvd::MonitorRequester::shared_pointer& req, size_t bsize) @@ -257,6 +285,7 @@ TestPVMonitor::TestPVMonitor(const TestPVChannel::shared_pointer& ch, pvd::MonitorElementPtr elem(new pvd::MonitorElement(fact->createPVStructure(channel->pv->dtype))); free.push_back(elem); } + epicsAtomicIncrSizeT(&countTestPVMonitor); } TestPVMonitor::~TestPVMonitor() @@ -264,6 +293,7 @@ TestPVMonitor::~TestPVMonitor() Guard G(channel->pv->provider->lock); if(requester) testDiag("Warning: TestPVMonitor dropped w/o destroy()"); + epicsAtomicDecrSizeT(&countTestPVMonitor); } void TestPVMonitor::destroy() @@ -370,6 +400,8 @@ void TestPVMonitor::release(pvd::MonitorElementPtr const & monitorElement) } } +static size_t countTestPV; + TestPV::TestPV(const std::string& name, const std::tr1::shared_ptr& provider, const pvd::StructureConstPtr& dtype) @@ -378,7 +410,14 @@ TestPV::TestPV(const std::string& name, ,factory(pvd::PVDataCreate::getPVDataCreate()) ,dtype(dtype) ,value(factory->createPVStructure(dtype)) -{} +{ + epicsAtomicIncrSizeT(&countTestPV); +} + +TestPV::~TestPV() +{ + epicsAtomicDecrSizeT(&countTestPV); +} void TestPV::post(const pvd::BitSet& changed, bool notify) { @@ -444,7 +483,17 @@ void TestPV::disconnect() } } -TestProvider::TestProvider() {} +static size_t countTestProvider; + +TestProvider::TestProvider() +{ + epicsAtomicIncrSizeT(&countTestProvider); +} + +TestProvider::~TestProvider() +{ + epicsAtomicDecrSizeT(&countTestProvider); +} void TestProvider::destroy() { @@ -556,3 +605,21 @@ void TestProvider::dispatch() } } } + +void TestProvider::testCounts() +{ + int ok = 1; + size_t temp; +#define TESTC(name) temp=epicsAtomicGetSizeT(&count##name); ok &= temp==0; testDiag("num. live " #name " %u", (unsigned)temp) + TESTC(TestChannelMonitorRequester); + TESTC(TestChannelRequester); + TESTC(TestProvider); + TESTC(TestPV); + TESTC(TestPVChannel); + TESTC(TestPVMonitor); +#undef TESTC + if(ok) + testPass("All instances free'd"); + else + testFail("Some instances leaked"); +} diff --git a/testApp/utilities.h b/testApp/utilities.h index bd9fbe9..6eb7d13 100644 --- a/testApp/utilities.h +++ b/testApp/utilities.h @@ -23,6 +23,22 @@ struct TestProvider; testDiag("%s : " #NAME "(%p) : %s", epics::pvData::getMessageTypeName(messageType).c_str(), this, message.c_str()); \ } +template +void test_method(const char *kname, const char *mname) +{ + try { + testDiag("------- %s::%s --------", kname, mname); + C inst; + (inst.*M)(); + } catch(std::exception& e) { + PRINT_EXCEPTION(e); + testAbort("unexpected exception: %s", e.what()); + } +} + +// Construct an instance and run one method +#define TEST_METHOD(klass, method) test_method(#klass, #method) + // Boilerplate reduction for accessing a scalar field template struct ScalarAccessor { @@ -51,7 +67,7 @@ struct TestChannelRequester : public epics::pvAccess::ChannelRequester epics::pvData::Status status; epics::pvAccess::Channel::ConnectionState laststate; TestChannelRequester(); - virtual ~TestChannelRequester() {} + virtual ~TestChannelRequester(); virtual void channelCreated(const epics::pvData::Status& status, epics::pvAccess::Channel::shared_pointer const & channel); virtual void channelStateChange(epics::pvAccess::Channel::shared_pointer const & channel, epics::pvAccess::Channel::ConnectionState connectionState); @@ -73,7 +89,7 @@ struct TestChannelMonitorRequester : public epics::pvData::MonitorRequester epics::pvData::StructureConstPtr dtype; TestChannelMonitorRequester(); - virtual ~TestChannelMonitorRequester() {} + virtual ~TestChannelMonitorRequester(); virtual void monitorConnect(epics::pvData::Status const & status, epics::pvData::MonitorPtr const & monitor, @@ -183,6 +199,7 @@ struct TestPV TestPV(const std::string& name, const std::tr1::shared_ptr& provider, const epics::pvData::StructureConstPtr& dtype); + ~TestPV(); void post(const epics::pvData::BitSet& changed, bool notify = true); @@ -210,7 +227,7 @@ struct TestProvider : public epics::pvAccess::ChannelProvider, std::tr1::enable_ short priority, std::string const & address); TestProvider(); - virtual ~TestProvider() {} + virtual ~TestProvider(); TestPV::shared_pointer addPV(const std::string& name, const epics::pvData::StructureConstPtr& tdef); @@ -219,6 +236,8 @@ struct TestProvider : public epics::pvAccess::ChannelProvider, std::tr1::enable_ epicsMutex lock; typedef weak_value_map pvs_t; pvs_t pvs; + + static void testCounts(); }; #endif // UTILITIES_H