diff --git a/src/ioc/db/test/Makefile b/src/ioc/db/test/Makefile index 4fe389cbf..6c9f3e9c1 100644 --- a/src/ioc/db/test/Makefile +++ b/src/ioc/db/test/Makefile @@ -57,7 +57,7 @@ dbPutLinkTest_SRCS += dbPutLinkTest.c dbPutLinkTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp testHarness_SRCS += dbPutLinkTest.c TESTS += dbPutLinkTest -TESTFILES += ../dbPutLinkTest.db ../dbBadLink.db +TESTFILES += ../dbPutLinkTest.db ../dbPutLinkTestJ.db ../dbBadLink.db TESTPROD_HOST += dbLockTest dbLockTest_SRCS += dbLockTest.c diff --git a/src/ioc/db/test/dbPutLinkTest.c b/src/ioc/db/test/dbPutLinkTest.c index e46d2c4d9..d8024c82a 100644 --- a/src/ioc/db/test/dbPutLinkTest.c +++ b/src/ioc/db/test/dbPutLinkTest.c @@ -24,8 +24,10 @@ #include "osiFileName.h" #include "dbmf.h" #include "errlog.h" +#include #include "xRecord.h" +#include "jlinkz.h" #include "testMain.h" @@ -533,9 +535,73 @@ static void testLinkFail(void) testdbCleanup(); } +static +void testNumZ(int expect) +{ + int numz = epicsAtomicGetIntT(&numzalloc); + testOk(numz==expect, "numzalloc==%d (%d)", expect, numz); +} + +static +void testJLink(void) +{ + testDiag("Test json link setup/retarget"); + + testNumZ(0); + + testDiag("Link parsing failures"); + testdbPrepare(); + + testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); + + dbTestIoc_registerRecordDeviceDriver(pdbbase); + + testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); + testdbReadDatabase("dbPutLinkTestJ.db", NULL, NULL); + + testNumZ(0); + + eltc(0); + testIocInitOk(); + eltc(1); + + testNumZ(3); + + testdbPutFieldOk("j1.PROC", DBF_LONG, 1); + testdbPutFieldOk("j2.PROC", DBF_LONG, 1); + testdbPutFieldOk("j3.PROC", DBF_LONG, 1); + + testdbGetFieldEqual("j1.INP", DBF_STRING, "{\"z\":{\"good\":1}}"); + testdbGetFieldEqual("j1.VAL", DBF_LONG, 1); + testdbGetFieldEqual("j2.VAL", DBF_LONG, 2); + testdbGetFieldEqual("j3.VAL", DBF_LONG, 3); + + testNumZ(3); + + testdbPutFieldOk("j1.INP", DBF_STRING, "{\"z\":{\"good\":4}}"); + testdbPutFieldOk("j1.PROC", DBF_LONG, 1); + testdbGetFieldEqual("j1.VAL", DBF_LONG, 4); + + testNumZ(3); + + testdbPutFieldFail(S_dbLib_badField, "j1.INP", DBF_STRING, "{\"z\":{\"fail\":5}}"); + testdbPutFieldOk("j1.PROC", DBF_LONG, 1); + testdbGetFieldEqual("j1.VAL", DBF_LONG, 4); + /* put failure in parsing stage doesn't modify link */ + testdbGetFieldEqual("j1.INP", DBF_STRING, "{\"z\":{\"good\":4}}"); + + testNumZ(3); + + testIocShutdownOk(); + + testNumZ(0); + + testdbCleanup(); +} + MAIN(dbPutLinkTest) { - testPlan(280); + testPlan(301); testLinkParse(); testLinkFailParse(); testCADBSet(); @@ -543,5 +609,6 @@ MAIN(dbPutLinkTest) testHWMod(); testLinkInitFail(); testLinkFail(); + testJLink(); return testDone(); } diff --git a/src/ioc/db/test/dbPutLinkTestJ.db b/src/ioc/db/test/dbPutLinkTestJ.db new file mode 100644 index 000000000..25cf4c822 --- /dev/null +++ b/src/ioc/db/test/dbPutLinkTestJ.db @@ -0,0 +1,12 @@ + +record(x, "j1") { + field(INP, {z:{good:1}}) +} + +record(x, "j2") { + field(INP, {z:{good:2}}) +} + +record(x, "j3") { + field(INP, {z:{good:3}}) +} diff --git a/src/ioc/db/test/devx.c b/src/ioc/db/test/devx.c index 6cd01202a..c5527f14e 100644 --- a/src/ioc/db/test/devx.c +++ b/src/ioc/db/test/devx.c @@ -147,8 +147,7 @@ static long xsoft_init_record(xRecord *prec) static long xsoft_read(xRecord *prec) { - dbGetLink(&prec->inp, DBR_DOUBLE, &prec->val, NULL, NULL); - return 0; + return dbGetLink(&prec->inp, DBR_LONG, &prec->val, NULL, NULL); } static struct xdset devxSoft = { diff --git a/src/ioc/db/test/jlinkz.c b/src/ioc/db/test/jlinkz.c index 79b642ebd..6602a22b0 100644 --- a/src/ioc/db/test/jlinkz.c +++ b/src/ioc/db/test/jlinkz.c @@ -14,19 +14,15 @@ #include #include #include -#include #include +#include #include -int numzalloc; +#define epicsExportSharedSymbols -typedef struct { - jlink base; - epicsMutexId lock; - unsigned isset:1; - unsigned isopen:1; - epicsInt32 value; -} zpriv; +#include "jlinkz.h" + +int numzalloc; static @@ -37,6 +33,7 @@ void z_open(struct link *plink) if(priv->isopen) testDiag("lsetZ re-open"); priv->isopen = 1; + testDiag("Open jlinkz %p", priv); } static @@ -51,8 +48,11 @@ void z_remove(struct dbLocker *locker, struct link *plink) epicsMutexUnlock(priv->lock); + testDiag("Remove/free jlinkz %p", priv); + epicsAtomicDecrIntT(&numzalloc); + epicsMutexDestroy(priv->lock); free(priv); plink->value.json.jlink = NULL; /* paranoia */ } @@ -153,11 +153,20 @@ jlink* z_alloc(short dbfType) { zpriv *priv; priv = calloc(1, sizeof(*priv)); - if(!priv) return NULL; + if(!priv) goto fail; + + priv->lock = epicsMutexCreate(); + if(!priv->lock) goto fail; epicsAtomicIncrIntT(&numzalloc); + testDiag("Alloc jlinkz %p", priv); + return &priv->base; +fail: + if(priv && priv->lock) epicsMutexDestroy(priv->lock); + free(priv); + return NULL; } static @@ -166,10 +175,13 @@ void z_free(jlink *pj) zpriv *priv = CONTAINER(pj, zpriv, base); if(priv->isopen) - testDiag("lsetZ jlink free after open()\n"); + testDiag("lsetZ jlink free after open()"); + + testDiag("Free jlinkz %p", priv); epicsAtomicDecrIntT(&numzalloc); + epicsMutexDestroy(priv->lock); free(priv); } @@ -193,8 +205,14 @@ jlif_key_result z_start(jlink *pj) static jlif_result z_key(jlink *pj, const char *key, size_t len) { - if(strcmp(key,"fail")==0) return jlif_stop; - else return jlif_continue; + zpriv *priv = CONTAINER(pj, zpriv, base); + + if(len==4 && strncmp(key,"fail", len)==0) { + testDiag("Found fail key jlinkz %p", priv); + return jlif_stop; + } else { + return jlif_continue; + } } static diff --git a/src/ioc/db/test/jlinkz.h b/src/ioc/db/test/jlinkz.h new file mode 100644 index 000000000..5c34d2eec --- /dev/null +++ b/src/ioc/db/test/jlinkz.h @@ -0,0 +1,27 @@ +/*************************************************************************\ +* Copyright (c) 2016 Michael Davidsaver +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. + \*************************************************************************/ + +#ifndef JLINKZ_H +#define JLINKZ_H + +#include +#include +#include + +#include + +epicsShareExtern +int numzalloc; + +typedef struct { + jlink base; + epicsMutexId lock; + unsigned isset:1; + unsigned isopen:1; + epicsInt32 value; +} zpriv; + +#endif /* JLINKZ_H */