Major updates in testCa, run on RTEMS under QEMU
This commit is contained in:

committed by
mdavidsaver

parent
92002b6ba2
commit
964a6bc33a
@ -3,49 +3,51 @@
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
# Need access to caProviderPvt.h
|
||||
# Access to caProviderPvt.h
|
||||
USR_CPPFLAGS += -I$(TOP)/src/ca
|
||||
|
||||
TESTPROD_HOST += testCaProvider
|
||||
|
||||
testCaProvider_SRCS += testCaProvider.cpp
|
||||
|
||||
PROD_LIBS += pvAccess pvAccessCA pvData $(EPICS_BASE_IOC_LIBS)
|
||||
PROD_SYS_LIBS_WIN32 += netapi32 ws2_32
|
||||
|
||||
TESTPROD_HOST += testCaProvider
|
||||
testCaProvider_SRCS += testCaProvider.cpp
|
||||
ifdef BASE_3_16
|
||||
TESTS += testCaProvider
|
||||
endif
|
||||
ifdef BASE_3_16
|
||||
testCaProvider_SRCS_RTEMS += rtemsTestData.c
|
||||
testCaProvider_SRCS += testIoc_registerRecordDeviceDriver.cpp
|
||||
REGRDDFLAGS = -l
|
||||
endif
|
||||
caTestHarness_SRCS += $(testCaProvider_SRCS)
|
||||
|
||||
# Ensure EPICS_HOST_ARCH is set in the environment
|
||||
export EPICS_HOST_ARCH
|
||||
TESTS += testCaProvider
|
||||
TESTFILES += ../testCaProvider.db $(COMMON_DIR)/testIoc.dbd
|
||||
|
||||
ifdef BASE_3_16
|
||||
# Embedded OSes need Base-3.16.2 or higher to pass tests
|
||||
# Build test scripts for hosts
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
# Code that runs all tests in the collection
|
||||
ifneq ($(filter $(T_A),$(CROSS_COMPILER_RUNTEST_ARCHS)),)
|
||||
TESTPROD = $(TESTPROD_HOST)
|
||||
TESTSCRIPTS = $(TESTSCRIPTS_HOST)
|
||||
endif
|
||||
|
||||
# Ensure EPICS_HOST_ARCH is set in the environment
|
||||
export EPICS_HOST_ARCH
|
||||
|
||||
caTestHarness_SRCS += $(testCaProvider_SRCS)
|
||||
caTestHarness_SRCS += pvCaAllTests.c
|
||||
|
||||
# Build for vxWorks
|
||||
# Build harness for vxWorks and RTEMS
|
||||
PROD_vxWorks = caTestHarness
|
||||
TESTSPEC_vxWorks = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests
|
||||
|
||||
# Build for RTEMS, with harness code & configuration
|
||||
PROD_RTEMS += caTestHarness
|
||||
PROD_RTEMS = caTestHarness
|
||||
caTestHarness_SRCS_RTEMS += rtemsTestHarness.c
|
||||
TESTSPEC_RTEMS = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests
|
||||
endif
|
||||
|
||||
# Build test scripts for hosts
|
||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
ifdef BASE_3_16
|
||||
$(COMMON_DIR)/testIoc.dbd: $(EPICS_BASE)/dbd/softIoc.dbd
|
||||
$(RM) $@
|
||||
$(CP) $< $@
|
||||
|
||||
rtemsTestData.c : $(TESTFILES) $(TOOLS)/epicsMakeMemFs.pl
|
||||
$(PERL) $(TOOLS)/epicsMakeMemFs.pl $@ epicsRtemsFSImage $(TESTFILES)
|
||||
endif
|
||||
|
@ -15,25 +15,25 @@
|
||||
#include <testMain.h>
|
||||
#include <epicsVersion.h>
|
||||
#include <envDefs.h>
|
||||
#include <osiFileName.h>
|
||||
|
||||
#ifdef EPICS_VERSION_INT
|
||||
#if !defined(USE_SOFTIOC) && EPICS_VERSION_INT >= VERSION_INT(3,16,2,0)
|
||||
#define USE_DBUNITTEST
|
||||
// USE_TYPED_RSET prevents deprecation warnings
|
||||
#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT >= VERSION_INT(3,16,2,0)
|
||||
#define HAS_DBUNITTEST 1
|
||||
// Prevent 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
|
||||
#include <osiFileName.h>
|
||||
#endif
|
||||
#else
|
||||
#define HAS_DBUNITTEST 0
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_TESTS
|
||||
#define EXIT_TESTS 1
|
||||
#if defined(vxWorks) || defined(__rtems__)
|
||||
#define HAS_SYSTEM 0
|
||||
#else
|
||||
#define HAS_SYSTEM 1
|
||||
#endif
|
||||
|
||||
#include <pv/thread.h>
|
||||
@ -47,17 +47,21 @@
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
|
||||
// DEBUG must be 0 to run under the automated test harness
|
||||
#define DEBUG 0
|
||||
// DEBUG output is disabled when run under an automated test harness
|
||||
int DEBUG = 0;
|
||||
|
||||
// These need to be longer than you might expect for Jenkins
|
||||
// These need to be longer than you might expect for CI runs
|
||||
#define CONNECTION_TIMEOUT 10.0
|
||||
#define OPERATION_TIMEOUT 10.0
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvAccess::ca;
|
||||
using namespace std;
|
||||
using std::string;
|
||||
|
||||
|
||||
ChannelProvider::shared_pointer testChannelProvider;
|
||||
|
||||
// -------------------- TestChannel --------------------
|
||||
|
||||
class TestChannel;
|
||||
typedef std::tr1::shared_ptr<TestChannel> TestChannelPtr;
|
||||
@ -68,69 +72,58 @@ class TestChannel:
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TestChannel);
|
||||
string getRequesterName();
|
||||
void message(
|
||||
string const & message,
|
||||
MessageType messageType);
|
||||
virtual void channelCreated(const Status& status, Channel::shared_pointer const & channel);
|
||||
virtual void channelStateChange(Channel::shared_pointer const & channel, Channel::ConnectionState connectionState);
|
||||
string getChannelName();
|
||||
Channel::shared_pointer getChannel();
|
||||
static TestChannelPtr create(string const & channelName);
|
||||
void connect();
|
||||
void waitConnect(double timeout);
|
||||
string getRequesterName() { return "testChannel"; }
|
||||
void message(string const & message, MessageType messageType) {}
|
||||
|
||||
virtual void channelCreated(const Status& status,
|
||||
Channel::shared_pointer const & channel)
|
||||
{
|
||||
if (channel->isConnected())
|
||||
waitForConnect.signal();
|
||||
}
|
||||
|
||||
virtual void channelStateChange(Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{
|
||||
if (connectionState == Channel::CONNECTED)
|
||||
waitForConnect.signal();
|
||||
}
|
||||
|
||||
string getChannelName() { return channelName; }
|
||||
Channel::shared_pointer getChannel() { return channel;}
|
||||
|
||||
static TestChannelPtr create(string const & channelName)
|
||||
{
|
||||
TestChannelPtr testChannel(new TestChannel(channelName));
|
||||
testChannel->connect();
|
||||
return testChannel;
|
||||
}
|
||||
|
||||
void connect()
|
||||
{
|
||||
if (!testChannelProvider)
|
||||
testAbort("No channel provider");
|
||||
channel = testChannelProvider->createChannel(channelName,
|
||||
shared_from_this(), ChannelProvider::PRIORITY_DEFAULT);
|
||||
if (!channel)
|
||||
throw std::runtime_error(channelName + " channelCreate failed ");
|
||||
waitConnect(CONNECTION_TIMEOUT);
|
||||
}
|
||||
|
||||
void waitConnect(double timeout)
|
||||
{
|
||||
if (waitForConnect.wait(timeout)) return;
|
||||
throw std::runtime_error(channelName +
|
||||
" TestChannel::waitConnect failed ");
|
||||
}
|
||||
private:
|
||||
TestChannel(string const & channelName);
|
||||
TestChannel(string const & channelName) :
|
||||
channelName(channelName) {}
|
||||
string channelName;
|
||||
Event waitForConnect;
|
||||
Channel::shared_pointer channel;
|
||||
};
|
||||
|
||||
string TestChannel::getChannelName() { return channelName;}
|
||||
|
||||
Channel::shared_pointer TestChannel::getChannel() { return channel;}
|
||||
|
||||
TestChannelPtr TestChannel::create(string const & channelName)
|
||||
{
|
||||
TestChannelPtr testChannel(new TestChannel(channelName));
|
||||
testChannel->connect();
|
||||
return testChannel;
|
||||
}
|
||||
|
||||
TestChannel::TestChannel(string const & channelName)
|
||||
: channelName(channelName)
|
||||
{
|
||||
}
|
||||
|
||||
string TestChannel::getRequesterName() { return "testChannel";}
|
||||
void TestChannel::message(string const & message,MessageType messageType) {};
|
||||
|
||||
void TestChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel)
|
||||
{
|
||||
if(channel->isConnected()) waitForConnect.signal();
|
||||
}
|
||||
|
||||
void TestChannel::channelStateChange(Channel::shared_pointer const & channel, Channel::ConnectionState connectionState)
|
||||
{
|
||||
if(connectionState==Channel::CONNECTED) waitForConnect.signal();
|
||||
}
|
||||
|
||||
void TestChannel::connect()
|
||||
{
|
||||
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
|
||||
ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca"));
|
||||
if(!channelProvider) throw std::runtime_error(channelName + " provider ca not registered");
|
||||
channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT);
|
||||
if(!channel) throw std::runtime_error(channelName + " channelCreate failed ");
|
||||
waitConnect(CONNECTION_TIMEOUT);
|
||||
}
|
||||
|
||||
void TestChannel::waitConnect(double timeout)
|
||||
{
|
||||
if(waitForConnect.wait(timeout)) return;
|
||||
throw std::runtime_error(channelName + " TestChannel::waitConnect failed ");
|
||||
}
|
||||
|
||||
class TestChannelGet;
|
||||
typedef std::tr1::shared_ptr<TestChannelGet> TestChannelGetPtr;
|
||||
|
||||
@ -546,6 +539,7 @@ void TestChannelMonitor::stopEvents()
|
||||
channelMonitor->stop();
|
||||
}
|
||||
|
||||
|
||||
class TestClient;
|
||||
typedef std::tr1::shared_ptr<TestClient> TestClientPtr;
|
||||
|
||||
@ -585,7 +579,7 @@ private:
|
||||
Event waitForPut;
|
||||
};
|
||||
|
||||
TestClientPtr TestClient::create(string const &channelName,PVStructurePtr const & pvRequest)
|
||||
TestClientPtr TestClient::create(string const &channelName,PVStructurePtr const & pvRequest)
|
||||
{
|
||||
TestClientPtr testClient(new TestClient(channelName,pvRequest));
|
||||
testClient->connect();
|
||||
@ -610,20 +604,20 @@ void TestClient::getDone(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet)
|
||||
{
|
||||
testOk(pvStructure.get() != 0,"pvStructure not null");
|
||||
testOk(pvStructure->getSubField("value").get() != 0,"value not null");
|
||||
testOk(pvStructure->getSubField("timeStamp").get() != 0,"timeStamp not null");
|
||||
testOk(pvStructure->getSubField("alarm").get() != 0,"alarm not null");
|
||||
if (DEBUG) std::cout << testChannel->getChannelName() + " TestClient::getDone"
|
||||
<< " putValue " << putValue
|
||||
<< " bitSet " << *bitSet
|
||||
<< " pvStructure\n" << pvStructure << "\n";
|
||||
PVScalarPtr pvScalar = pvStructure->getSubField<PVScalar>("value");
|
||||
if(pvScalar) {
|
||||
testOk(pvStructure.get() != 0,"pvStructure not null");
|
||||
testOk(pvStructure->getSubField("value").get() != 0,"value not null");
|
||||
testOk(pvStructure->getSubField("timeStamp").get() != 0,"timeStamp not null");
|
||||
testOk(pvStructure->getSubField("alarm").get() != 0,"alarm not null");
|
||||
if (DEBUG) std::cout << testChannel->getChannelName() + " TestClient::getDone"
|
||||
<< " putValue " << putValue
|
||||
<< " bitSet " << *bitSet
|
||||
<< " pvStructure\n" << pvStructure << "\n";
|
||||
PVScalarPtr pvScalar = pvStructure->getSubField<PVScalar>("value");
|
||||
if(pvScalar) {
|
||||
string getValue = getConvert()->toString(pvScalar);
|
||||
testOk(getValue.compare(putValue)==0,"getValue==putValue");
|
||||
}
|
||||
waitForGet.signal();
|
||||
}
|
||||
waitForGet.signal();
|
||||
}
|
||||
|
||||
void TestClient::putDone()
|
||||
@ -635,9 +629,9 @@ void TestClient::monitorEvent(
|
||||
PVStructure::shared_pointer const & pvStructure,
|
||||
BitSet::shared_pointer const & bitSet)
|
||||
{
|
||||
if (DEBUG) std::cout << testChannel->getChannelName() + " TestClient::monitorEvent"
|
||||
<< " bitSet " << *bitSet
|
||||
<< " pvStructure\n" << pvStructure << "\n";
|
||||
if (DEBUG) std::cout << testChannel->getChannelName() + " TestClient::monitorEvent"
|
||||
<< " bitSet " << *bitSet
|
||||
<< " pvStructure\n" << pvStructure << "\n";
|
||||
}
|
||||
|
||||
void TestClient::get()
|
||||
@ -645,7 +639,7 @@ void TestClient::get()
|
||||
testDiag("TestClient::get %s",
|
||||
testChannel->getChannelName().c_str());
|
||||
testChannelGet->get();
|
||||
if (DEBUG) cout << "TestClient::get() calling waitGet\n";
|
||||
if (DEBUG) std::cout << "TestClient::get() calling waitGet\n";
|
||||
waitGet(OPERATION_TIMEOUT);
|
||||
}
|
||||
|
||||
@ -675,33 +669,39 @@ void TestClient::stopEvents()
|
||||
testChannelMonitor->stopEvents();
|
||||
}
|
||||
|
||||
|
||||
// --------------------- TestIoc ---------------------
|
||||
|
||||
class TestIoc;
|
||||
typedef std::tr1::shared_ptr<TestIoc> TestIocPtr;
|
||||
|
||||
class TestIoc :
|
||||
public epicsThreadRunable
|
||||
class TestIoc
|
||||
{
|
||||
public:
|
||||
virtual void run();
|
||||
static TestIocPtr create();
|
||||
void start();
|
||||
void shutdown();
|
||||
private:
|
||||
#ifndef USE_DBUNITTEST
|
||||
std::auto_ptr<epicsThread> thread;
|
||||
const char *base;
|
||||
const char *arch;
|
||||
#endif
|
||||
virtual ~TestIoc() {};
|
||||
virtual void start() = 0;
|
||||
virtual void shutdown() = 0;
|
||||
};
|
||||
|
||||
TestIocPtr TestIoc::create()
|
||||
{
|
||||
return TestIocPtr(new TestIoc());
|
||||
}
|
||||
#if HAS_DBUNITTEST
|
||||
// This implementation uses the dbUnitTest API added to Base-3.16.2
|
||||
|
||||
void TestIoc::start()
|
||||
class TestIocUnit :
|
||||
public TestIoc
|
||||
{
|
||||
public:
|
||||
TestIocUnit() {
|
||||
testDiag("IOC using dbUnitTest");
|
||||
}
|
||||
|
||||
// public TestIoc
|
||||
virtual ~TestIocUnit() {}
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
};
|
||||
|
||||
void TestIocUnit::start()
|
||||
{
|
||||
#ifdef USE_DBUNITTEST
|
||||
testdbPrepare();
|
||||
testdbReadDatabase("testIoc.dbd", NULL, NULL);
|
||||
testIoc_registerRecordDeviceDriver(pdbbase);
|
||||
@ -709,67 +709,89 @@ void TestIoc::start()
|
||||
eltc(0);
|
||||
testIocInitOk();
|
||||
eltc(1);
|
||||
#else
|
||||
base = getenv("EPICS_BASE");
|
||||
}
|
||||
|
||||
void TestIocUnit::shutdown()
|
||||
{
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
}
|
||||
#endif // HAS_DBUNITTEST
|
||||
|
||||
|
||||
// This implementation starts a caRepeater and runs a softIoc from
|
||||
// Base, both as separate processes, so only works on workstation
|
||||
// targets. Unfortunately it isn't very reliable on some CI systems.
|
||||
|
||||
class TestIocSoft :
|
||||
public TestIoc,
|
||||
public epicsThreadRunable
|
||||
{
|
||||
public:
|
||||
TestIocSoft() {
|
||||
testDiag("IOC using system('softIoc')");
|
||||
}
|
||||
|
||||
// public TestIoc
|
||||
virtual ~TestIocSoft() {}
|
||||
virtual void start();
|
||||
virtual void shutdown();
|
||||
|
||||
// public epicsThreadRunable
|
||||
virtual void run();
|
||||
|
||||
private:
|
||||
std::tr1::shared_ptr<epicsThread> thread;
|
||||
string path;
|
||||
};
|
||||
|
||||
void TestIocSoft::start()
|
||||
{
|
||||
const char *base = getenv("EPICS_BASE");
|
||||
if (!base)
|
||||
testAbort("Environment variable $EPICS_BASE not defined");
|
||||
arch = getenv("EPICS_HOST_ARCH");
|
||||
const char *arch = getenv("EPICS_HOST_ARCH");
|
||||
if (!arch)
|
||||
testAbort("Environment variable $EPICS_HOST_ARCH not defined");
|
||||
path = string(base) + OSI_PATH_SEPARATOR "bin" OSI_PATH_SEPARATOR +
|
||||
arch + OSI_PATH_SEPARATOR;
|
||||
epicsEnvSet("EPICS_CA_ADDR_LIST", "localhost");
|
||||
epicsEnvSet("EPICS_CA_AUTO_ADDR_LIST", "NO");
|
||||
|
||||
thread = std::auto_ptr<epicsThread>(new epicsThread(
|
||||
*this,
|
||||
string repeater = path + "caRepeater &";
|
||||
if (system(repeater.c_str()) != 0) {
|
||||
throw std::runtime_error("caRepeater wasn't started");
|
||||
}
|
||||
|
||||
thread = std::tr1::shared_ptr<epicsThread>(new epicsThread(*this,
|
||||
"testIoc",
|
||||
epicsThreadGetStackSize(epicsThreadStackBig),
|
||||
epicsThreadPriorityLow));
|
||||
thread->start();
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestIoc::run()
|
||||
void TestIocSoft::run()
|
||||
{
|
||||
#ifndef USE_DBUNITTEST
|
||||
// Base-3.14 doesn't provide the dbUnitTest APIs, and the CA
|
||||
// tests with an embedded IOC fail with a Base before 3.16.2.
|
||||
// This version only works on workstation targets, it runs the
|
||||
// softIoc from Base as a separate process, using system().
|
||||
string cmd(base);
|
||||
cmd += OSI_PATH_SEPARATOR "bin" OSI_PATH_SEPARATOR;
|
||||
cmd += arch;
|
||||
cmd += OSI_PATH_SEPARATOR "softIoc -x test -d ../testCaProvider.db";
|
||||
if (system(cmd.c_str()) != 0) {
|
||||
string message(cmd);
|
||||
cmd += " not started";
|
||||
throw std::runtime_error(cmd);
|
||||
}
|
||||
#endif
|
||||
string ioc = path + "softIoc -x test -d ../testCaProvider.db";
|
||||
if (system(ioc.c_str()) != 0)
|
||||
throw std::runtime_error("IOC wasn't started");
|
||||
}
|
||||
|
||||
void TestIoc::shutdown()
|
||||
void TestIocSoft::shutdown()
|
||||
{
|
||||
testDiag("Shutting down the IOC");
|
||||
#ifdef USE_DBUNITTEST
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
#else
|
||||
// put to record that makes IOC exit
|
||||
string channelName = "test:exit";
|
||||
string request("value");
|
||||
PVStructurePtr pvRequest(createRequest(request));
|
||||
testDiag("created request");
|
||||
TestClientPtr client = TestClient::create(channelName,pvRequest);
|
||||
TestClientPtr client = TestClient::create(channelName, pvRequest);
|
||||
if (!client)
|
||||
testAbort("NULL client for %s", channelName.c_str());
|
||||
testDiag("got client");
|
||||
client->put("1");
|
||||
testDiag("sent put");
|
||||
client->stopEvents();
|
||||
#endif
|
||||
testDiag("IOC shutdown complete");
|
||||
testOk(thread->exitWait(10), "IOC shutdown");
|
||||
}
|
||||
|
||||
|
||||
void checkClient(const string &channelName, const string &putValue)
|
||||
{
|
||||
string request("value,alarm,timeStamp");
|
||||
@ -782,62 +804,68 @@ void checkClient(const string &channelName, const string &putValue)
|
||||
client->stopEvents();
|
||||
}
|
||||
|
||||
#define TEST_LOOPS 2
|
||||
void testClientTypes(void)
|
||||
{
|
||||
// When using dbUnitTest, the channel provider must be created
|
||||
// *after* the IOC has been started. That's why this is here...
|
||||
testChannelProvider = ChannelProviderRegistry::clients()->getProvider("ca");
|
||||
|
||||
checkClient("DBRlongout", "0");
|
||||
checkClient("DBRlongout", "1");
|
||||
checkClient("DBRlongout", "-1");
|
||||
checkClient("DBRlongout", "32767");
|
||||
checkClient("DBRlongout", "32768");
|
||||
checkClient("DBRlongout", "-32768");
|
||||
checkClient("DBRlongout", "-32769");
|
||||
checkClient("DBRlongout", "2147483647");
|
||||
checkClient("DBRlongout", "-2147483648");
|
||||
checkClient("DBRdoubleout", "1.5");
|
||||
checkClient("DBRstringout", "test");
|
||||
checkClient("DBRbyteArray", "1 2 3");
|
||||
checkClient("DBRshortArray", "1 2 3");
|
||||
checkClient("DBRintArray", "1 2 3");
|
||||
checkClient("DBRubyteArray", "1 2 3");
|
||||
checkClient("DBRushortArray", "1 2 3");
|
||||
checkClient("DBRuintArray", "1 2 3");
|
||||
checkClient("DBRfloatArray", "1 2 3");
|
||||
checkClient("DBRdoubleArray", "1 2 3");
|
||||
checkClient("DBRstringArray", "aa bb cc");
|
||||
checkClient("DBRmbbout", "2");
|
||||
checkClient("DBRbinaryout", "1");
|
||||
}
|
||||
|
||||
#define TEST_CLIENT_TYPES(TestIocType) { \
|
||||
testDiag("=== " #TestIocType " ==="); \
|
||||
TestIocPtr testIoc = TestIocPtr(new TestIocType()); \
|
||||
testIoc->start(); \
|
||||
testClientTypes(); \
|
||||
testIoc->shutdown(); \
|
||||
}
|
||||
|
||||
|
||||
MAIN(testCaProvider)
|
||||
{
|
||||
testPlan(143 * TEST_LOOPS + EXIT_TESTS);
|
||||
DEBUG = (getenv("HARNESS_ACTIVE") == NULL);
|
||||
|
||||
#ifdef USE_DBUNITTEST
|
||||
testDiag("Running IOC using dbUnitTest");
|
||||
#else
|
||||
testDiag("Running IOC using system()");
|
||||
#endif
|
||||
epics::pvAccess::ca::CAClientFactory::start();
|
||||
|
||||
TestIocPtr testIoc(new TestIoc());
|
||||
testIoc->start();
|
||||
|
||||
testDiag("===Test caProvider===");
|
||||
CAClientFactory::start();
|
||||
testDiag("factory started");
|
||||
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
|
||||
testDiag("registered as a client");
|
||||
try {
|
||||
for (int i = 0; i < TEST_LOOPS; ++i) {
|
||||
testDiag("== Loop #%d ==", i+1);
|
||||
ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca"));
|
||||
|
||||
if (!channelProvider)
|
||||
testAbort("Channel provider 'ca' not registered");
|
||||
testDiag("ChannelProvider: %p", channelProvider.get());
|
||||
|
||||
checkClient("DBRlongout", "0");
|
||||
checkClient("DBRlongout", "1");
|
||||
checkClient("DBRlongout", "-1");
|
||||
checkClient("DBRlongout", "32767");
|
||||
checkClient("DBRlongout", "32768");
|
||||
checkClient("DBRlongout", "-32768");
|
||||
checkClient("DBRlongout", "-32769");
|
||||
checkClient("DBRlongout", "2147483647");
|
||||
checkClient("DBRlongout", "-2147483648");
|
||||
checkClient("DBRdoubleout", "1.5");
|
||||
checkClient("DBRstringout", "test");
|
||||
checkClient("DBRbyteArray", "1 2 3");
|
||||
checkClient("DBRshortArray", "1 2 3");
|
||||
checkClient("DBRintArray", "1 2 3");
|
||||
checkClient("DBRubyteArray", "1 2 3");
|
||||
checkClient("DBRushortArray", "1 2 3");
|
||||
checkClient("DBRuintArray", "1 2 3");
|
||||
checkClient("DBRfloatArray", "1 2 3");
|
||||
checkClient("DBRdoubleArray", "1 2 3");
|
||||
checkClient("DBRstringArray", "aa bb cc");
|
||||
checkClient("DBRmbbout", "2");
|
||||
checkClient("DBRbinaryout", "1");
|
||||
// Set TESTCAP_USE_SYSTEM in environment to use other impl.
|
||||
if (HAS_DBUNITTEST && !getenv("TESTCAP_USE_SYSTEM")) {
|
||||
testPlan(143);
|
||||
TEST_CLIENT_TYPES(TestIocUnit)
|
||||
}
|
||||
else if (HAS_SYSTEM) {
|
||||
testPlan(145);
|
||||
TEST_CLIENT_TYPES(TestIocSoft)
|
||||
}
|
||||
else {
|
||||
testPlan(1);
|
||||
testSkip(1, "Neither TestIoc implementation available.");
|
||||
}
|
||||
testIoc->shutdown();
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
testAbort("caught un-expected exception: %s", e.what());
|
||||
testAbort("Caught unexpected exception: %s", e.what());
|
||||
}
|
||||
|
||||
return testDone();
|
||||
|
Reference in New Issue
Block a user