Merge pull request #1 from anjohnson/master

Changes to your pvAccess/testCa code

Andrew,

Thanks
This commit is contained in:
Marty Kraimer
2018-05-27 06:31:48 -04:00
committed by GitHub
3 changed files with 131 additions and 134 deletions

View File

@@ -3,34 +3,45 @@
TOP = .. TOP = ..
include $(TOP)/configure/CONFIG include $(TOP)/configure/CONFIG
# Need access to caProviderPvt.h
USR_CPPFLAGS += -I$(TOP)/src/ca USR_CPPFLAGS += -I$(TOP)/src/ca
CAPROVIDER_TEST = $(TOP)/testCa PROD_LIBS += pvAccess pvAccessCA pvData $(EPICS_BASE_IOC_LIBS)
PROD_LIBS += pvAccess pvAccessCA pvData ca Com
TESTPROD_HOST += testCaProvider TESTPROD_HOST += testCaProvider
testCaProvider_SRCS += testCaProvider.cpp testCaProvider_SRCS += testCaProvider.cpp
testHarness_SRCS += testCaProvider.cpp caTestHarness_SRCS += testCaProvider.cpp
TESTS += testCaProvider TESTS += testCaProvider
testHarness_SRCS += pvCaAllTests.c ifdef BASE_3_15
testCaProvider_SRCS += testIoc_registerRecordDeviceDriver.cpp
REGRDDFLAGS = -l
else
# testCaProvider needs EPICS_HOST_ARCH set in the environment
export EPICS_HOST_ARCH
endif
# testCaProvider needs EPICS_HOST_ARCH set in the environment ifdef BASE_3_15
export EPICS_HOST_ARCH # Embedded OSes need dbUnitTest, Base-3.15 and higher only
# Name the application caTestHarness # The test collection is caTestHarness
caTestHarness_SRCS = $(testHarness_SRCS) caTestHarness_SRCS += pvCaAllTests.c
# Build for vxWorks # Build for vxWorks
PROD_vxWorks = caTestHarness PROD_vxWorks = caTestHarness
TESTSPEC_vxWorks = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests TESTSPEC_vxWorks = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests
# Build for RTEMS, with harness code & configuration # Build for RTEMS, with harness code & configuration
PROD_RTEMS += caTestHarness PROD_RTEMS += caTestHarness
caTestHarness_SRCS_RTEMS += rtemsTestHarness.c caTestHarness_SRCS_RTEMS += rtemsTestHarness.c
TESTSPEC_RTEMS = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests TESTSPEC_RTEMS = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests
endif
# Build test scripts for hosts # Build test scripts for hosts
TESTSCRIPTS_HOST += $(TESTS:%=%.t) TESTSCRIPTS_HOST += $(TESTS:%=%.t)
include $(TOP)/configure/RULES include $(TOP)/configure/RULES
ifdef BASE_3_15
$(COMMON_DIR)/testIoc.dbd: $(EPICS_BASE)/dbd/softIoc.dbd
$(CP) $< $@
endif

View File

@@ -13,7 +13,21 @@
#include <epicsUnitTest.h> #include <epicsUnitTest.h>
#include <testMain.h> #include <testMain.h>
#include <epicsVersion.h>
#if defined(VERSION_INT) && EPICS_VERSION_INT >= VERSION_INT(3,15,0,1)
#define USE_DBUNITTEST
// USE_TYPED_RSET prevents deprecation warnings
#define USE_TYPED_RSET
#define EXIT_TESTS 0
#include <dbAccess.h>
#include <errlog.h>
#include <dbUnitTest.h>
extern "C" int testIoc_registerRecordDeviceDriver(struct dbBase *pbase);
#else
#define EXIT_TESTS 1
#endif
#include <pv/thread.h> #include <pv/thread.h>
#include <pv/pvAccess.h> #include <pv/pvAccess.h>
@@ -26,6 +40,9 @@
#include <pv/pvIntrospect.h> #include <pv/pvIntrospect.h>
#include <pv/pvData.h> #include <pv/pvData.h>
// DEBUG must be 0 to run under the automated test harness
#define DEBUG 0
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::pvAccess::ca; using namespace epics::pvAccess::ca;
@@ -584,7 +601,7 @@ void TestClient::getDone(
testOk(pvStructure->getSubField("value")!=NULL,"value not null"); testOk(pvStructure->getSubField("value")!=NULL,"value not null");
testOk(pvStructure->getSubField("timeStamp")!=NULL,"timeStamp not null"); testOk(pvStructure->getSubField("timeStamp")!=NULL,"timeStamp not null");
testOk(pvStructure->getSubField("alarm")!=NULL,"alarm not null"); testOk(pvStructure->getSubField("alarm")!=NULL,"alarm not null");
std::cout << testChannel->getChannelName() + " TestClient::getDone" if (DEBUG) std::cout << testChannel->getChannelName() + " TestClient::getDone"
<< " bitSet " << *bitSet << " bitSet " << *bitSet
<< " pvStructure\n" << pvStructure << "\n"; << " pvStructure\n" << pvStructure << "\n";
waitForGet.signal(); waitForGet.signal();
@@ -599,35 +616,38 @@ void TestClient::monitorEvent(
PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvStructure,
BitSet::shared_pointer const & bitSet) BitSet::shared_pointer const & bitSet)
{ {
std::cout << testChannel->getChannelName() + " TestClient::monitorEvent" if (DEBUG) std::cout << testChannel->getChannelName() + " TestClient::monitorEvent"
<< " bitSet " << *bitSet << " bitSet " << *bitSet
<< " pvStructure\n" << pvStructure << "\n"; << " pvStructure\n" << pvStructure << "\n";
} }
void TestClient::get() void TestClient::get()
{ {
cout << "TestClient::get() calling get\n"; testDiag("TestClient::get %s",
testChannel->getChannelName().c_str());
testChannelGet->get(); testChannelGet->get();
cout << "TestClient::get() calling waitGet\n"; if (DEBUG) cout << "TestClient::get() calling waitGet\n";
waitGet(5.0); waitGet(5.0);
} }
void TestClient::waitGet(double timeout) void TestClient::waitGet(double timeout)
{ {
if(waitForGet.wait(timeout)) return; testOk(waitForGet.wait(timeout),
throw std::runtime_error(testChannel->getChannelName() + " TestClient::waitGet failed "); "waitGet(%s) succeeded", testChannel->getChannelName().c_str());
} }
void TestClient::put(string const & value) void TestClient::put(string const & value)
{ {
testDiag("TestClient::put %s := %s",
testChannel->getChannelName().c_str(), value.c_str());
testChannelPut->put(value); testChannelPut->put(value);
waitPut(5.0); waitPut(5.0);
} }
void TestClient::waitPut(double timeout) void TestClient::waitPut(double timeout)
{ {
if(waitForPut.wait(timeout)) return; testOk(waitForPut.wait(timeout),
throw std::runtime_error(testChannel->getChannelName() + " TestClient::waitPut failed "); "waitPut(%s) succeeded", testChannel->getChannelName().c_str());
} }
void TestClient::stopEvents() void TestClient::stopEvents()
@@ -645,8 +665,11 @@ public:
virtual void run(); virtual void run();
static TestIocPtr create(); static TestIocPtr create();
void start(); void start();
void shutdown();
private: private:
#ifndef USE_DBUNITTEST
std::auto_ptr<epicsThread> thread; std::auto_ptr<epicsThread> thread;
#endif
}; };
TestIocPtr TestIoc::create() TestIocPtr TestIoc::create()
@@ -656,141 +679,116 @@ TestIocPtr TestIoc::create()
void TestIoc::start() void TestIoc::start()
{ {
#ifdef USE_DBUNITTEST
testdbPrepare();
testdbReadDatabase("testIoc.dbd", NULL, NULL);
testIoc_registerRecordDeviceDriver(pdbbase);
testdbReadDatabase("testCaProvider.db", NULL, NULL);
eltc(0);
testIocInitOk();
eltc(1);
#else
thread = std::auto_ptr<epicsThread>(new epicsThread( thread = std::auto_ptr<epicsThread>(new epicsThread(
*this, *this,
"testIoc", "testIoc",
epicsThreadGetStackSize(epicsThreadStackSmall), epicsThreadGetStackSize(epicsThreadStackSmall),
epicsThreadPriorityLow)); epicsThreadPriorityLow));
thread->start(); thread->start();
#endif
} }
void TestIoc::run() void TestIoc::run()
{ {
#ifndef USE_DBUNITTEST
// Base-3.14 doesn't provide the dbUnitTest APIs.
// This code only works on workstation targets, it runs the
// softIoc from Base as a separate process, using system().
char * base; char * base;
base = getenv("EPICS_BASE"); base = getenv("EPICS_BASE");
if(base==NULL) throw std::runtime_error("TestIoc::run $EPICS_BASE not defined"); if(base==NULL) throw std::runtime_error("TestIoc::run $EPICS_BASE not defined");
char * arch; char * arch;
arch = getenv("EPICS_HOST_ARCH"); arch = getenv("EPICS_HOST_ARCH");
if(arch==NULL) throw std::runtime_error("TestIoc::run $$EPICS_HOST_ARCH not defined"); if(arch==NULL) throw std::runtime_error("TestIoc::run $$EPICS_HOST_ARCH not defined");
if(system("$EPICS_BASE/bin/$EPICS_HOST_ARCH/softIoc -d ../testCaProvider.db")!=0) { setenv("EPICS_CA_ADDR_LIST", "localhost", 1);
setenv("EPICS_CA_AUTO_ADDR_LIST", "NO", 1);
if(system("$EPICS_BASE/bin/$EPICS_HOST_ARCH/softIoc -x test -d ../testCaProvider.db")!=0) {
string message(base); string message(base);
message += "/bin/"; message += "/bin/";
message += arch; message += arch;
message += "/softIoc -d ../testCaProvider.db not started"; message += "/softIoc -d ../testCaProvider.db not started";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
#endif
}
void TestIoc::shutdown()
{
#ifdef USE_DBUNITTEST
testIocShutdownOk();
testdbCleanup();
#endif
}
void checkClient(const string &channelName, const string &putValue)
{
string request("value,alarm,timeStamp");
PVStructurePtr pvRequest(createRequest(request));
TestClientPtr client = TestClient::create(channelName,pvRequest);
if (!client)
testAbort("NULL client for %s", channelName.c_str());
client->put(putValue);
client->get();
client->stopEvents();
} }
MAIN(testCaProvider) MAIN(testCaProvider)
{ {
testPlan(84 + EXIT_TESTS);
TestIocPtr testIoc(new TestIoc()); TestIocPtr testIoc(new TestIoc());
testIoc->start(); testIoc->start();
testPlan(56);
testDiag("===Test caProvider==="); testDiag("===Test caProvider===");
CAClientFactory::start(); CAClientFactory::start();
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients()); ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca")); try {
try{ ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca"));
if(!channelProvider) { if (!channelProvider)
throw std::runtime_error(" provider ca not registered"); testAbort("Channel provider 'ca' not registered");
}
string channelName;
string request("value,alarm,timeStamp");
PVStructurePtr pvRequest(createRequest(request));
TestClientPtr client;
channelName = "DBRlongout"; checkClient("DBRlongout", "5");
client = TestClient::create(channelName,pvRequest); checkClient("DBRdoubleout", "1.5");
if(!client) throw std::runtime_error(channelName + " client null"); checkClient("DBRstringout", "test");
client->put("5"); checkClient("DBRbyteArray", "1 2 3");
client->get(); checkClient("DBRshortArray", "1 2 3");
client->stopEvents(); checkClient("DBRintArray", "1 2 3");
channelName = "DBRdoubleout"; checkClient("DBRubyteArray", "1 2 3");
client = TestClient::create(channelName,pvRequest); checkClient("DBRushortArray", "1 2 3");
if(!client) throw std::runtime_error(channelName + " client null"); checkClient("DBRuintArray", "1 2 3");
client->put("1.5"); checkClient("DBRfloatArray", "1 2 3");
client->get(); checkClient("DBRdoubleArray", "1 2 3");
client->stopEvents(); checkClient("DBRstringArray", "aa bb cc");
channelName = "DBRstringout"; checkClient("DBRmbbout", "2");
client = TestClient::create(channelName,pvRequest); checkClient("DBRbinaryout", "1");
if(!client) throw std::runtime_error(channelName + " client null");
client->put("test"); #ifndef USE_DBUNITTEST
client->get();
client->stopEvents();
channelName = "DBRbyteArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
client->stopEvents();
channelName = "DBRshortArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
client->stopEvents();
channelName = "DBRintArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
channelName = "DBRubyteArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
client->stopEvents();
channelName = "DBRushortArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
client->stopEvents();
channelName = "DBRuintArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
channelName = "DBRfloatArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
client->stopEvents();
channelName = "DBRdoubleArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1 2 3");
client->get();
client->stopEvents();
channelName = "DBRstringArray";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("aa bb cc");
client->get();
client->stopEvents();
channelName = "DBRmbbout";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("2");
client->get();
client->stopEvents();
channelName = "DBRbinaryout";
client = TestClient::create(channelName,pvRequest);
if(!client) throw std::runtime_error(channelName + " client null");
client->put("1");
client->get();
client->stopEvents();
// put to record that makes IOC exit // put to record that makes IOC exit
channelName = "DBRexit"; string channelName = "test:exit";
client = TestClient::create(channelName,pvRequest); string request("value");
if(!client) throw std::runtime_error(channelName + " client null"); PVStructurePtr pvRequest(createRequest(request));
TestClientPtr client = TestClient::create(channelName,pvRequest);
if (!client)
testAbort("NULL client for %s", channelName.c_str());
client->put("1"); client->put("1");
client->stopEvents(); client->stopEvents();
}catch(std::exception& e){ #endif
testFail("caught un-expected exception: %s", e.what());
} }
catch (std::exception& e) {
testAbort("caught un-expected exception: %s", e.what());
}
testIoc->shutdown();
return testDone();; return testDone();;
} }

View File

@@ -39,12 +39,6 @@ record(calc, "DBRcalcin")
field(LLSV, "MAJOR") field(LLSV, "MAJOR")
} }
record(sub, "DBRexit")
{
field(DESC, "exit")
field(SNAM, "exit")
}
record(longin,"DBRlongin") { record(longin,"DBRlongin") {
field(DESC, "longin") field(DESC, "longin")
field(EGU, "volts") field(EGU, "volts")
@@ -131,12 +125,6 @@ record(stringin,"DBRstringin") {
record(bo,"DBRbinaryout") { record(bo,"DBRbinaryout") {
field(DESC, "bo") 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(ZNAM,"zero")
field(ONAM,"one") field(ONAM,"one")
} }