Merge pull request #1 from anjohnson/master
Changes to your pvAccess/testCa code Andrew, Thanks
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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();;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user