From 872004f75ff0aff9997ba21f16ec7e117d7eeeae Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sun, 27 May 2018 00:31:32 -0400 Subject: [PATCH] testCa: Run IOC using dbUnitTest API where possible Essential for VxWorks and RTEMS which don't support system(). Build embedded IOC tests only against Base-3.15 and later. --- testCa/Makefile | 43 ++++++++++++++++++++++------------- testCa/testCaProvider.cpp | 47 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/testCa/Makefile b/testCa/Makefile index 4300613..da17a17 100644 --- a/testCa/Makefile +++ b/testCa/Makefile @@ -3,34 +3,45 @@ TOP = .. include $(TOP)/configure/CONFIG +# Need access to caProviderPvt.h USR_CPPFLAGS += -I$(TOP)/src/ca -CAPROVIDER_TEST = $(TOP)/testCa - -PROD_LIBS += pvAccess pvAccessCA pvData ca Com +PROD_LIBS += pvAccess pvAccessCA pvData $(EPICS_BASE_IOC_LIBS) TESTPROD_HOST += testCaProvider testCaProvider_SRCS += testCaProvider.cpp -testHarness_SRCS += testCaProvider.cpp +caTestHarness_SRCS += testCaProvider.cpp 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 -export EPICS_HOST_ARCH +ifdef BASE_3_15 + # Embedded OSes need dbUnitTest, Base-3.15 and higher only -# Name the application caTestHarness -caTestHarness_SRCS = $(testHarness_SRCS) + # The test collection is caTestHarness + caTestHarness_SRCS += pvCaAllTests.c -# Build for vxWorks -PROD_vxWorks = caTestHarness -TESTSPEC_vxWorks = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests + # Build for vxWorks + PROD_vxWorks = caTestHarness + TESTSPEC_vxWorks = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests -# Build for RTEMS, with harness code & configuration -PROD_RTEMS += caTestHarness -caTestHarness_SRCS_RTEMS += rtemsTestHarness.c -TESTSPEC_RTEMS = caTestHarness.$(MUNCH_SUFFIX); pvCaAllTests + # Build for RTEMS, with harness code & configuration + 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_15 + $(COMMON_DIR)/testIoc.dbd: $(EPICS_BASE)/dbd/softIoc.dbd + $(CP) $< $@ +endif diff --git a/testCa/testCaProvider.cpp b/testCa/testCaProvider.cpp index 52c37ac..abd4822 100644 --- a/testCa/testCaProvider.cpp +++ b/testCa/testCaProvider.cpp @@ -13,7 +13,21 @@ #include #include +#include + #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 + #include + #include + + extern "C" int testIoc_registerRecordDeviceDriver(struct dbBase *pbase); +#else + #define EXIT_TESTS 1 +#endif #include #include @@ -651,8 +665,11 @@ public: virtual void run(); static TestIocPtr create(); void start(); + void shutdown(); private: +#ifndef USE_DBUNITTEST std::auto_ptr thread; +#endif }; TestIocPtr TestIoc::create() @@ -662,16 +679,30 @@ TestIocPtr TestIoc::create() 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(new epicsThread( *this, "testIoc", epicsThreadGetStackSize(epicsThreadStackSmall), epicsThreadPriorityLow)); thread->start(); +#endif } 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; base = getenv("EPICS_BASE"); if(base==NULL) throw std::runtime_error("TestIoc::run $EPICS_BASE not defined"); @@ -685,6 +716,15 @@ void TestIoc::run() message += "/softIoc -d ../testCaProvider.db not started"; throw std::runtime_error(message); } +#endif +} + +void TestIoc::shutdown() +{ +#ifdef USE_DBUNITTEST + testIocShutdownOk(); + testdbCleanup(); +#endif } MAIN(testCaProvider) @@ -692,12 +732,12 @@ MAIN(testCaProvider) TestIocPtr testIoc(new TestIoc()); testIoc->start(); - testPlan(84); + testPlan(84 + EXIT_TESTS); testDiag("===Test caProvider==="); CAClientFactory::start(); ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients()); - ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca")); try{ + ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca")); if(!channelProvider) { throw std::runtime_error(" provider ca not registered"); } @@ -788,15 +828,18 @@ MAIN(testCaProvider) client->put("1"); client->get(); client->stopEvents(); +#ifndef USE_DBUNITTEST // put to record that makes IOC exit channelName = "DBRexit"; client = TestClient::create(channelName,pvRequest); if(!client) throw std::runtime_error(channelName + " client null"); client->put("1"); client->stopEvents(); +#endif }catch(std::exception& e){ testFail("caught un-expected exception: %s", e.what()); } + testIoc->shutdown(); return testDone();; }