From f814398d775e8f55076519b73ec1a995ff3ae555 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 13 Jan 2016 20:58:58 -0500 Subject: [PATCH] std/rec/test: add compressTest test circular buffer mode for FIFO and LIFO --- src/std/rec/test/Makefile | 7 + src/std/rec/test/compressTest.c | 351 +++++++++++++++++++++++++ src/std/rec/test/compressTest.db | 7 + src/std/rec/test/epicsRunRecordTests.c | 3 + 4 files changed, 368 insertions(+) create mode 100644 src/std/rec/test/compressTest.c create mode 100644 src/std/rec/test/compressTest.db diff --git a/src/std/rec/test/Makefile b/src/std/rec/test/Makefile index 5e7a8fb29..f5a60a751 100644 --- a/src/std/rec/test/Makefile +++ b/src/std/rec/test/Makefile @@ -38,6 +38,13 @@ testHarness_SRCS += linkRetargetLinkTest.c TESTFILES += ../linkRetargetLink.db TESTS += linkRetargetLinkTest +TESTPROD_HOST += compressTest +compressTest_SRCS += compressTest.c +compressTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp +testHarness_SRCS += compressTest.c +TESTFILES += ../compressTest.db +TESTS += compressTest + TARGETS += $(COMMON_DIR)/asTestIoc.dbd asTestIoc_DBD += base.dbd asTestIoc_DBD += asTest.dbd diff --git a/src/std/rec/test/compressTest.c b/src/std/rec/test/compressTest.c new file mode 100644 index 000000000..e9085c68b --- /dev/null +++ b/src/std/rec/test/compressTest.c @@ -0,0 +1,351 @@ +/*************************************************************************\ +* 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. +\*************************************************************************/ + +#include "dbUnitTest.h" +#include "testMain.h" +#include "dbLock.h" +#include "errlog.h" +#include "dbAccess.h" +#include "epicsMath.h" + +#include "aiRecord.h" +#include "compressRecord.h" + +#define testDEq(A,B,D) testOk(fabs((A)-(B))<(D), #A " (%f) ~= " #B " (%f)", A, B) + +void recTestIoc_registerRecordDeviceDriver(struct dbBase *); + +static +void checkArrD(const char *pv, long elen, double a, double b, double c, double d) +{ + double buf[4]; + double expect[4]; + long nReq = NELEMENTS(buf), i; + unsigned match; + DBADDR addr; + + expect[0] = a; + expect[1] = b; + expect[2] = c; + expect[3] = d; + + if(dbNameToAddr(pv, &addr)) + testAbort("Unknown PV '%s'", pv); + + if(dbGet(&addr, DBR_DOUBLE, buf, NULL, &nReq, NULL)) + testAbort("Failed to get '%s'", pv); + + match = elen==nReq; + for(i=0; i=0.01) + testDiag("[%ld] -> %f != %f", i, expect[i], buf[i]); + } +} + +static +void checkArrI(const char *pv, long elen, epicsInt32 a, epicsInt32 b, epicsInt32 c, epicsInt32 d) +{ + epicsInt32 buf[4]; + epicsInt32 expect[4]; + long nReq = NELEMENTS(buf), i; + unsigned match; + DBADDR addr; + + expect[0] = a; + expect[1] = b; + expect[2] = c; + expect[3] = d; + + if(dbNameToAddr(pv, &addr)) + testAbort("Unknown PV '%s'", pv); + + if(dbGet(&addr, DBR_LONG, buf, NULL, &nReq, NULL)) + testAbort("Failed to get '%s'", pv); + + match = elen==nReq; + for(i=0; i %d != %d", i, (int)expect[i], (int)buf[i]); + } +} + +static +void testFIFOCirc(void) +{ + aiRecord *vrec; + compressRecord *crec; + double *cbuf; + + testDiag("Test FIFO"); + + testdbPrepare(); + + testdbReadDatabase("recTestIoc.dbd", NULL, NULL); + + recTestIoc_registerRecordDeviceDriver(pdbbase); + + testdbReadDatabase("compressTest.db", NULL, "ALG=Circular Buffer,BALG=FIFO Buffer,NSAM=4"); + + vrec = (aiRecord*)testdbRecordPtr("val"); + crec = (compressRecord*)testdbRecordPtr("comp"); + + eltc(0); + testIocInitOk(); + eltc(1); + + dbScanLock((dbCommon*)crec); + cbuf = crec->bptr; + + testOk1(crec->off==0); + testOk1(crec->inx==0); + testOk1(crec->nuse==0); + + testDiag("Push 1.1"); + vrec->val = 1.1; + dbProcess((dbCommon*)crec); + + /* In FIFO mode the valid elements a cbuf[(off-nuse-1)%size] through cbuf[(off-1)%size] */ + testOk1(crec->off==1); + testOk1(crec->inx==0); + testOk1(crec->nuse==1); + testDEq(cbuf[0], 1.1, 0.1); + testDEq(cbuf[1], 0.0, 0.1); + testDEq(cbuf[2], 0.0, 0.1); + testDEq(cbuf[3], 0.0, 0.1); + checkArrD("comp", 1, 1.1, 0, 0, 0); + + testDiag("Push 2.1"); + vrec->val = 2.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==2); + testOk1(crec->inx==0); + testOk1(crec->nuse==2); + testDEq(cbuf[0], 1.1, 0.1); + testDEq(cbuf[1], 2.1, 0.1); + testDEq(cbuf[2], 0.0, 0.1); + testDEq(cbuf[3], 0.0, 0.1); + checkArrD("comp", 2, 1.1, 2.1, 0, 0); + + testDiag("Push 3.1"); + vrec->val = 3.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==3); + testOk1(crec->inx==0); + testOk1(crec->nuse==3); + testDEq(cbuf[0], 1.1, 0.1); + testDEq(cbuf[1], 2.1, 0.1); + testDEq(cbuf[2], 3.1, 0.1); + testDEq(cbuf[3], 0.0, 0.1); + checkArrD("comp", 3, 1.1, 2.1, 3.1, 0); + + testDiag("Push 4.1"); + vrec->val = 4.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==0); + testOk1(crec->inx==0); + testOk1(crec->nuse==4); + testDEq(cbuf[0], 1.1, 0.1); + testDEq(cbuf[1], 2.1, 0.1); + testDEq(cbuf[2], 3.1, 0.1); + testDEq(cbuf[3], 4.1, 0.1); + checkArrD("comp", 4, 1.1, 2.1, 3.1, 4.1); + + testDiag("Push 5.1"); + vrec->val = 5.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==1); + testOk1(crec->inx==0); + testOk1(crec->nuse==4); + testDEq(cbuf[0], 5.1, 0.1); + testDEq(cbuf[1], 2.1, 0.1); + testDEq(cbuf[2], 3.1, 0.1); + testDEq(cbuf[3], 4.1, 0.1); + checkArrD("comp", 4, 2.1, 3.1, 4.1, 5.1); + + testDiag("Push 6.1"); + vrec->val = 6.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==2); + testOk1(crec->inx==0); + testOk1(crec->nuse==4); + testDEq(cbuf[0], 5.1, 0.1); + testDEq(cbuf[1], 6.1, 0.1); + testDEq(cbuf[2], 3.1, 0.1); + testDEq(cbuf[3], 4.1, 0.1); + checkArrD("comp", 4, 3.1, 4.1, 5.1, 6.1); + + dbScanUnlock((dbCommon*)crec); + + testDiag("Reset"); + testdbPutFieldOk("comp.RES", DBF_LONG, 0); + + dbScanLock((dbCommon*)crec); + testOk1(crec->off==0); + testOk1(crec->inx==0); + testOk1(crec->nuse==0); + checkArrD("comp", 0, 0, 0, 0, 0); + dbScanUnlock((dbCommon*)crec); + + testIocShutdownOk(); + + testdbCleanup(); +} + +static +void testLIFOCirc(void) +{ + aiRecord *vrec; + compressRecord *crec; + double *cbuf; + + testDiag("Test LIFO"); + + testdbPrepare(); + + testdbReadDatabase("recTestIoc.dbd", NULL, NULL); + + recTestIoc_registerRecordDeviceDriver(pdbbase); + + testdbReadDatabase("compressTest.db", NULL, "ALG=Circular Buffer,BALG=LIFO Buffer,NSAM=4"); + + vrec = (aiRecord*)testdbRecordPtr("val"); + crec = (compressRecord*)testdbRecordPtr("comp"); + + eltc(0); + testIocInitOk(); + eltc(1); + + dbScanLock((dbCommon*)crec); + cbuf = crec->bptr; + + testOk1(crec->off==0); + testOk1(crec->inx==0); + testOk1(crec->nuse==0); + + testDiag("Push 1.1"); + vrec->val = 1.1; + dbProcess((dbCommon*)crec); + + testDiag("off %u", crec->off); + testOk1(crec->off==3); + testOk1(crec->inx==0); + testOk1(crec->nuse==1); + testDEq(cbuf[0], 0.0, 0.1); + testDEq(cbuf[1], 0.0, 0.1); + testDEq(cbuf[2], 0.0, 0.1); + testDEq(cbuf[3], 1.1, 0.1); + checkArrD("comp", 1, 1.1, 0, 0, 0); + + testDiag("Push 2.1"); + vrec->val = 2.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==2); + testOk1(crec->inx==0); + testOk1(crec->nuse==2); + testDEq(cbuf[0], 0.0, 0.1); + testDEq(cbuf[1], 0.0, 0.1); + testDEq(cbuf[2], 2.1, 0.1); + testDEq(cbuf[3], 1.1, 0.1); + checkArrD("comp", 2, 2.1, 1.1, 0, 0); + checkArrI("comp", 2, 2, 1, 0, 0); + + testDiag("Push 3.1"); + vrec->val = 3.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==1); + testOk1(crec->inx==0); + testOk1(crec->nuse==3); + testDEq(cbuf[0], 0.0, 0.1); + testDEq(cbuf[1], 3.1, 0.1); + testDEq(cbuf[2], 2.1, 0.1); + testDEq(cbuf[3], 1.1, 0.1); + checkArrD("comp", 3, 3.1, 2.1, 1.1, 0); + checkArrI("comp", 3, 3, 2, 1, 0); + + testDiag("Push 4.1"); + vrec->val = 4.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==0); + testOk1(crec->inx==0); + testOk1(crec->nuse==4); + testDEq(cbuf[0], 4.1, 0.1); + testDEq(cbuf[1], 3.1, 0.1); + testDEq(cbuf[2], 2.1, 0.1); + testDEq(cbuf[3], 1.1, 0.1); + checkArrD("comp", 4, 4.1, 3.1, 2.1, 1.1); + checkArrI("comp", 4, 4, 3, 2, 1); + + testDiag("Push 5.1"); + vrec->val = 5.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==3); + testOk1(crec->inx==0); + testOk1(crec->nuse==4); + testDEq(cbuf[0], 4.1, 0.1); + testDEq(cbuf[1], 3.1, 0.1); + testDEq(cbuf[2], 2.1, 0.1); + testDEq(cbuf[3], 5.1, 0.1); + checkArrD("comp", 4, 5.1, 4.1, 3.1, 2.1); + checkArrI("comp", 4, 5, 4, 3, 2); + + testDiag("Push 6.1"); + vrec->val = 6.1; + dbProcess((dbCommon*)crec); + + testOk1(crec->off==2); + testOk1(crec->inx==0); + testOk1(crec->nuse==4); + testDEq(cbuf[0], 4.1, 0.1); + testDEq(cbuf[1], 3.1, 0.1); + testDEq(cbuf[2], 6.1, 0.1); + testDEq(cbuf[3], 5.1, 0.1); + checkArrD("comp", 4, 6.1, 5.1, 4.1, 3.1); + + dbScanUnlock((dbCommon*)crec); + + testDiag("Reset"); + testdbPutFieldOk("comp.RES", DBF_LONG, 0); + + dbScanLock((dbCommon*)crec); + testOk1(crec->off==0); + testOk1(crec->inx==0); + testOk1(crec->nuse==0); + checkArrD("comp", 0, 0, 0, 0, 0); + dbScanUnlock((dbCommon*)crec); + + testIocShutdownOk(); + + testdbCleanup(); +} + +MAIN(compressTest) +{ + testPlan(116); + testFIFOCirc(); + testLIFOCirc(); + return testDone(); +} diff --git a/src/std/rec/test/compressTest.db b/src/std/rec/test/compressTest.db new file mode 100644 index 000000000..59fc620ba --- /dev/null +++ b/src/std/rec/test/compressTest.db @@ -0,0 +1,7 @@ +record(ai, "val") {} +record(compress, "comp") { + field(INP, "val NPP") + field(ALG, "$(ALG)") + field(BALG,"$(BALG)") + field(NSAM,"$(NSAM)") +} diff --git a/src/std/rec/test/epicsRunRecordTests.c b/src/std/rec/test/epicsRunRecordTests.c index 3476d2138..5612917cc 100644 --- a/src/std/rec/test/epicsRunRecordTests.c +++ b/src/std/rec/test/epicsRunRecordTests.c @@ -13,6 +13,7 @@ #include "epicsExit.h" int analogMonitorTest(void); +int compressTest(void); int arrayOpTest(void); int asTest(void); int linkRetargetLinkTest(void); @@ -23,6 +24,8 @@ void epicsRunRecordTests(void) runTest(analogMonitorTest); + runTest(compressTest); + runTest(arrayOpTest); runTest(asTest);