diff --git a/modules/database/test/std/rec/Makefile b/modules/database/test/std/rec/Makefile index d48424f65..e8c546442 100644 --- a/modules/database/test/std/rec/Makefile +++ b/modules/database/test/std/rec/Makefile @@ -159,6 +159,13 @@ asyncproctest_SRCS += asyncproctest_registerRecordDeviceDriver.cpp TESTFILES += $(COMMON_DIR)/asyncproctest.dbd ../asyncproctest.db TESTS += asyncproctest +TESTPROD_HOST += linkFilterTest +linkFilterTest_SRCS += linkFilterTest.c +linkFilterTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp +testHarness_SRCS += linkFilterTest.c +TESTFILES += ../linkFilterTest.db +TESTS += linkFilterTest + # dbHeader* is only a compile test # no need to actually run TESTPROD += dbHeaderTest diff --git a/modules/database/test/std/rec/linkFilterTest.c b/modules/database/test/std/rec/linkFilterTest.c new file mode 100644 index 000000000..a336abc5c --- /dev/null +++ b/modules/database/test/std/rec/linkFilterTest.c @@ -0,0 +1,157 @@ +/*************************************************************************\ +* Copyright (c) 2020 Dirk Zimoch +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include + +#include "dbAccess.h" +#include "devSup.h" +#include "alarm.h" +#include "dbUnitTest.h" +#include "errlog.h" +#include "epicsThread.h" + +#include "longinRecord.h" + +#include "testMain.h" + +void recTestIoc_registerRecordDeviceDriver(struct dbBase *); + +static void startTestIoc(const char *dbfile) +{ + testdbPrepare(); + testdbReadDatabase("recTestIoc.dbd", NULL, NULL); + recTestIoc_registerRecordDeviceDriver(pdbbase); + testdbReadDatabase(dbfile, NULL, NULL); + + eltc(0); + testIocInitOk(); + eltc(1); +} + +static void expectProcSuccess(const char *rec) +{ + char fieldname[20]; + testDiag("expecting success from %s", rec); + sprintf(fieldname, "%s.PROC", rec); + testdbPutFieldOk(fieldname, DBF_LONG, 1); + sprintf(fieldname, "%s.SEVR", rec); + testdbGetFieldEqual(fieldname, DBF_LONG, NO_ALARM); + sprintf(fieldname, "%s.STAT", rec); + testdbGetFieldEqual(fieldname, DBF_LONG, NO_ALARM); +} + +static void expectProcFailure(const char *rec) +{ + char fieldname[20]; + testDiag("expecting failure S_db_badField %#x from %s", S_db_badField, rec); + sprintf(fieldname, "%s.PROC", rec); + testdbPutFieldFail(S_db_badField, fieldname, DBF_LONG, 1); + sprintf(fieldname, "%s.SEVR", rec); + testdbGetFieldEqual(fieldname, DBF_LONG, INVALID_ALARM); + sprintf(fieldname, "%s.STAT", rec); + testdbGetFieldEqual(fieldname, DBF_LONG, LINK_ALARM); +} + +static void changeRange(long start, long stop, long step) +{ + char linkstring[60]; + if (step) + sprintf(linkstring, "src.[%ld:%ld:%ld]", start, step, stop); + else if (stop) + sprintf(linkstring, "src.[%ld:%ld]", start, stop); + else + sprintf(linkstring, "src.[%ld]", start); + testDiag("modifying link: %s", linkstring); + testdbPutFieldOk("ai.INP", DBF_STRING, linkstring); + testdbPutFieldOk("wf.INP", DBF_STRING, linkstring); +} + +static double buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 2, 4, 6}; + +static void expectRange(long start, long end) +{ + long n = end-start+1; + testdbGetFieldEqual("ai.VAL", DBF_DOUBLE, buf[start]); + testdbGetFieldEqual("wf.NORD", DBF_LONG, n); + testdbGetArrFieldEqual("wf.VAL", DBF_DOUBLE, n+2, n, buf+start); +} + +#if 0 +static void expectEmptyArray(void) +{ + /* empty arrays are now allowed at the moment */ + testDiag("expecting empty array"); + testdbGetFieldEqual("wf.NORD", DBF_LONG, 0); +} +#endif + +MAIN(linkFilterTest) +{ + testPlan(0); + startTestIoc("linkFilterTest.db"); + + testDiag("PINI"); + expectRange(2,4); + + testDiag("modify range"); + changeRange(3,6,0); + expectProcSuccess("ai"); + expectProcSuccess("wf"); + expectRange(3,6); + + testDiag("step 2"); + changeRange(1,6,2); + expectProcSuccess("ai"); + expectProcSuccess("wf"); + expectRange(10,12); + + testDiag("single value"); + changeRange(5,0,0); + expectProcSuccess("ai"); + expectProcSuccess("wf"); + expectRange(5,5); + + testDiag("backward range"); + changeRange(5,3,0); + expectProcFailure("ai"); + expectProcFailure("wf"); + + testDiag("range end beyond src.NORD"); + changeRange(3,9,0); + expectProcSuccess("ai"); + expectProcSuccess("wf"); + expectRange(3,7); /* clipped range */ + + testDiag("range end beyond src.NELM"); + changeRange(4,12,0); + expectProcSuccess("ai"); + expectProcSuccess("wf"); + expectRange(4,7); /* clipped range */ + + testDiag("range start beyond src.NORD"); + changeRange(8,9,0); + expectProcFailure("ai"); + expectProcFailure("wf"); + + testDiag("range start beyond src.NELM"); + changeRange(11,12,0); + expectProcFailure("ai"); + expectProcFailure("wf"); + + testDiag("single value beyond src.NORD"); + changeRange(8,0,0); + expectProcFailure("ai"); + expectProcFailure("wf"); + + testDiag("single beyond rec.NELM"); + changeRange(12,0,0); + expectProcFailure("ai"); + expectProcFailure("wf"); + + testIocShutdownOk(); + testdbCleanup(); + return testDone(); +} diff --git a/modules/database/test/std/rec/linkFilterTest.db b/modules/database/test/std/rec/linkFilterTest.db new file mode 100644 index 000000000..5ee371e51 --- /dev/null +++ b/modules/database/test/std/rec/linkFilterTest.db @@ -0,0 +1,16 @@ +record(waveform, "src") { + field(NELM, "10") + field(FTVL, "SHORT") + field(INP, [1, 2, 3, 4, 5, 6, 7, 8]) +} +record(ai, "ai") { + field(INP, "src.[2]") # expect 3 + field(PINI, "YES") +} +record(waveform, "wf") { + field(NELM, "5") + field(FTVL, "DOUBLE") + field(INP, "src.[2:4]") # expect 3,4,5 + field(PINI, "YES") +} +