diff --git a/src/ioc/db/dbUnitTest.c b/src/ioc/db/dbUnitTest.c index 432cac852..634993e20 100644 --- a/src/ioc/db/dbUnitTest.c +++ b/src/ioc/db/dbUnitTest.c @@ -65,6 +65,7 @@ void testdbCleanup(void) union anybuf { epicsAny val; + char valStr[MAX_STRING_SIZE]; char bytes[sizeof(epicsAny)]; }; @@ -73,16 +74,17 @@ long testdbVPutField(const char* pv, short dbrType, va_list ap) DBADDR addr; union anybuf pod; - if(dbNameToAddr(pv, &addr)) - testAbort("Missing PV %s", pv); + if(dbNameToAddr(pv, &addr)) { + testFail("Missing PV %s", pv); + return S_dbLib_recNotFound; + } 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); + strncpy(pod.valStr, uarg, sizeof(pod.valStr)); + pod.valStr[sizeof(pod.valStr)-1] = '\0'; + return dbPutField(&addr, dbrType, pod.valStr, 1); } /* The Type parameter takes into consideration @@ -101,8 +103,9 @@ long testdbVPutField(const char* pv, short dbrType, va_list ap) OP(DBR_ENUM, int, enum16); #undef OP default: - testAbort("invalid DBR: dbPutField(%s, %d, ...)", + testFail("invalid DBR: dbPutField(\"%s\", %d, ...)", addr.precord->name, dbrType); + return S_db_badDbrtype; } return dbPutField(&addr, dbrType, pod.bytes, 1); @@ -130,9 +133,61 @@ void testdbPutFieldFail(long status, const char* pv, short dbrType, ...) va_end(ap); if(ret==status) - testPass("dbPutField(%s, %d, ...) == %ld", pv, dbrType, status); + testPass("dbPutField(\"%s\", %d, ...) == %ld", pv, dbrType, status); else - testFail("dbPutField(%s, %d, ...) != %ld (%ld)", pv, dbrType, status, ret); + testFail("dbPutField(\"%s\", %d, ...) != %ld (%ld)", pv, dbrType, status, ret); +} + +void testdbGetFieldEqual(const char* pv, short dbrType, ...) +{ + va_list ap; + + va_start(ap, dbrType); + testdbVGetFieldEqual(pv, dbrType, ap); + va_end(ap); +} + +void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap) +{ + DBADDR addr; + long nReq = 1; + union anybuf pod; + long status; + + if(dbNameToAddr(pv, &addr)) { + testFail("Missing PV %s", pv); + return; + } + + status = dbGetField(&addr, dbrType, pod.bytes, NULL, &nReq, NULL); + if(status) { + testFail("dbGetField(\"%s\",%d,...) returns %ld", pv, dbrType, status); + return; + } + + switch(dbrType) { + case DBR_STRING: { + const char *expect = va_arg(ap, char*); + testOk(strcmp(expect, pod.valStr)==0, + "dbGetField(\"%s\", %d) -> \"%s\" == \"%s\"", + pv, dbrType, expect, pod.valStr); + break; + } +#define OP(DBR,Type,mem,pat) case DBR: {Type expect = va_arg(ap,Type); \ + testOk(expect==pod.val.mem, "dbGetField(\"%s\", %d) -> " pat " == " pat, \ + pv, dbrType, expect, (Type)pod.val.mem); break;} + + OP(DBR_CHAR, int, int8, "%d"); + OP(DBR_UCHAR, int, uInt8, "%d"); + OP(DBR_SHORT, int, int16, "%d"); + OP(DBR_USHORT, int, uInt16, "%d"); + OP(DBR_LONG, int, int32, "%d"); + OP(DBR_ULONG, unsigned int, uInt32, "%u"); + OP(DBR_FLOAT, double, float32, "%e"); + OP(DBR_DOUBLE, double, float64, "%e"); + OP(DBR_ENUM, int, enum16, "%d"); +#undef OP + } } dbCommon* testdbRecordPtr(const char* pv) diff --git a/src/ioc/db/dbUnitTest.h b/src/ioc/db/dbUnitTest.h index e4a76ec2e..80867dc9d 100644 --- a/src/ioc/db/dbUnitTest.h +++ b/src/ioc/db/dbUnitTest.h @@ -33,9 +33,7 @@ epicsShareFunc void testIocInitOk(void); epicsShareFunc void testIocShutdownOk(void); epicsShareFunc void testdbCleanup(void); -/* Scalar only version. - * - * Correct argument types must be used with this var-arg function! +/* Correct argument types must be used with this var-arg function! * Doing otherwise will result in corruption of argument values! * * int for DBR_UCHAR, DBR_CHAR, DBR_USHORT, DBR_SHORT, DBR_LONG @@ -49,11 +47,14 @@ epicsShareFunc void testdbCleanup(void); * testdbPutFieldOk("pvname", DBF_STRING, "hello world"); */ epicsShareFunc void testdbPutFieldOk(const char* pv, short dbrType, ...); -/* the inverse of testdbPutFieldOk(). Tests for put failure */ +/* Tests for put failure */ epicsShareFunc void testdbPutFieldFail(long status, const char* pv, short dbrType, ...); epicsShareFunc long testdbVPutField(const char* pv, short dbrType, va_list ap); +epicsShareFunc void testdbGetFieldEqual(const char* pv, short dbrType, ...); +epicsShareFunc void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap); + epicsShareFunc dbCommon* testdbRecordPtr(const char* pv); #ifdef __cplusplus