add dbUnitTest.h

hide boilerplate of tests using the PDB
This commit is contained in:
Michael Davidsaver
2014-06-23 16:28:25 -04:00
committed by Michael Davidsaver
parent 1ae2ab1de6
commit 80dd66a58d
4 changed files with 189 additions and 15 deletions
+2 -1
View File
@@ -37,6 +37,7 @@ INC += chfPlugin.h
INC += dbState.h
INC += db_access_routines.h
INC += db_convert.h
INC += dbUnitTest.h
# Generate menuGlobal.dbd automatically
DBD += menuGlobal.dbd
@@ -86,4 +87,4 @@ dbCore_SRCS += templateInstances.cpp
dbCore_SRCS += dbIocRegister.c
dbCore_SRCS += chfPlugin.c
dbCore_SRCS += dbState.c
dbCore_SRCS += dbUnitTest.c
+123
View File
@@ -0,0 +1,123 @@
/*************************************************************************\
* Copyright (c) 2013 Brookhaven National Laboratory.
* Copyright (c) 2013 ITER Organization.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author: Michael Davidsaver <mdavidsaver@bnl.gov>
* Ralph Lange <Ralph.Lange@gmx.de>
*/
#include <string.h>
#include "epicsUnitTest.h"
#include "osiFileName.h"
#include "dbmf.h"
#include "registry.h"
#define epicsExportSharedSymbols
#include "iocInit.h"
#include "initHooks.h"
#include "dbBase.h"
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbUnitTest.h"
void testdbPrepare(void)
{
/* No-op at the moment */
}
void testdbReadDatabase(const char* file,
const char* path,
const char* substitutions)
{
if(!path)
path = "." OSI_PATH_LIST_SEPARATOR ".." OSI_PATH_LIST_SEPARATOR
"../O.Common" OSI_PATH_LIST_SEPARATOR "O.Common";
if(dbReadDatabase(&pdbbase, file, path, substitutions))
testAbort("Failed to load test database\ndbReadDatabase(%s,%s,%s)",
file, path, substitutions);
}
int testiocInit(void)
{
return iocBuildNoCA() || iocRun();
}
int testiocShutdown(void)
{
return iocShutdown();
}
void testdbCleanup(void)
{
dbFreeBase(pdbbase);
initHookFree();
registryFree();
pdbbase = NULL;
dbmfFreeChunks();
}
long testdbPutField(const char* pv, short dbrType, ...)
{
long ret;
va_list ap;
va_start(ap, dbrType);
ret = testVdbPutField(pv, dbrType, ap);
va_end(ap);
return ret;
}
union anybuf {
epicsAny val;
char bytes[sizeof(epicsAny)];
};
long testVdbPutField(const char* pv, short dbrType, va_list ap)
{
DBADDR addr;
union anybuf pod;
if(dbNameToAddr(pv, &addr))
testAbort("Missing PV %s", pv);
switch(dbrType) {
case DBR_STRING: {
const char *uarg = va_arg(ap,char*);
epicsOldString buffer;
strncpy(buffer, uarg, sizeof(buffer));
buffer[sizeof(buffer)-1] = '\0';
return dbPutField(&addr, dbrType, buffer, 1);
}
#define OP(DBR,Type,mem) case DBR: {pod.val.mem = va_arg(ap,Type); break;}
OP(DBR_CHAR, int, int8);
OP(DBR_UCHAR, int, uInt8);
OP(DBR_SHORT, int, int16);
OP(DBR_USHORT, int, uInt16);
OP(DBR_LONG, int, int32);
OP(DBR_ULONG, unsigned int, uInt32);
OP(DBR_FLOAT, double, float32);
OP(DBR_DOUBLE, double, float64);
OP(DBR_ENUM, int, enum16);
#undef OP
default:
testAbort("invalid DBR: dbPutField(%s, %d, ...)",
addr.precord->name, dbrType);
}
return dbPutField(&addr, dbrType, pod.bytes, 1);
}
dbCommon* testGetRecord(const char* pv)
{
DBADDR addr;
if(dbNameToAddr(pv, &addr))
testAbort("Missing PV %s", pv);
return addr.precord;
}
+54
View File
@@ -0,0 +1,54 @@
/*************************************************************************\
* Copyright (c) 2013 Brookhaven National Laboratory.
* Copyright (c) 2013 ITER Organization.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author: Michael Davidsaver <mdavidsaver@bnl.gov>
* Ralph Lange <Ralph.Lange@gmx.de>
*/
#ifndef EPICSUNITTESTDB_H
#define EPICSUNITTESTDB_H
#include <stdarg.h>
#include "epicsUnitTest.h"
#include "dbAddr.h"
#include "dbCommon.h"
#include "shareLib.h"
#ifdef __cplusplus
extern "C" {
#endif
epicsShareFunc void testdbPrepare(void);
epicsShareFunc void testdbReadDatabase(const char* file,
const char* path,
const char* substitutions);
epicsShareFunc int testiocInit(void);
epicsShareFunc int testiocShutdown(void);
epicsShareFunc void testdbCleanup(void);
/* Scalar only version.
*
* Remember to use the correct argument type!s
*
* int for DBR_UCHAR, DBR_CHAR, DBR_USHORT, DBR_SHORT, DBR_LONG
* unsigned int for DBR_ULONG
* double for DBR_FLOAT and DBR_DOUBLE
* const char* for DBR_STRING
*/
epicsShareFunc long testdbPutField(const char* pv, short dbrType, ...);
epicsShareFunc long testVdbPutField(const char* pv, short dbrType, va_list ap);
epicsShareFunc dbCommon* testGetRecord(const char* pv);
#ifdef __cplusplus
}
#endif
#endif // EPICSUNITTESTDB_H
+10 -14
View File
@@ -12,7 +12,7 @@
#include <string.h>
#include "epicsUnitTest.h"
#include "dbUnitTest.h"
#include "epicsThread.h"
#include "iocInit.h"
#include "dbBase.h"
@@ -64,27 +64,23 @@ void checkCommonThreads (void) {
static
void cycle(void) {
if (dbReadDatabase(&pdbbase, "dbShutdownTest.dbd",
"." OSI_PATH_LIST_SEPARATOR ".." OSI_PATH_LIST_SEPARATOR
"../O.Common" OSI_PATH_LIST_SEPARATOR "O.Common", NULL))
testAbort("Database description 'dbShutdownTest.dbd' not found");
testdbPrepare();
testdbReadDatabase("dbShutdownTest.dbd", NULL, NULL);
dbShutdownTest_registerRecordDeviceDriver(pdbbase);
if (dbReadDatabase(&pdbbase, "sRecord.db",
"." OSI_PATH_LIST_SEPARATOR "..", NULL))
testAbort("Test database 'sRecord.db' not found");
testOk1(!(iocBuildNoCA() || iocRun()));
testdbReadDatabase("sRecord.db", NULL, NULL);
testOk1(!testiocInit());
epicsThreadMap(findCommonThread);
checkCommonThreads();
testOk1(iocShutdown()==0);
testOk1(testiocShutdown()==0);
dbFreeBase(pdbbase);
registryFree();
pdbbase = NULL;
dbmfFreeChunks();
testdbCleanup();
}
MAIN(dbShutdownTest)