diff --git a/src/std/rec/test/Makefile b/src/std/rec/test/Makefile index 91443a2b0..70c5cc224 100644 --- a/src/std/rec/test/Makefile +++ b/src/std/rec/test/Makefile @@ -112,7 +112,7 @@ TESTPROD_HOST += asyncproctest asyncproctest_SRCS += asyncproctest.c asyncproctest_SRCS += asyncproctest_registerRecordDeviceDriver.cpp TESTFILES += $(COMMON_DIR)/asyncproctest.dbd ../asyncproctest.db -#TESTS += asyncproctest # full of races... +TESTS += asyncproctest # epicsRunRecordTests runs all the test programs in a known working order. testHarness_SRCS += epicsRunRecordTests.c diff --git a/src/std/rec/test/asyncproctest.c b/src/std/rec/test/asyncproctest.c index 1987c05f4..bd2ffc41f 100644 --- a/src/std/rec/test/asyncproctest.c +++ b/src/std/rec/test/asyncproctest.c @@ -13,48 +13,87 @@ #include #include #include +#include "registryFunction.h" +#include + +epicsEventId done; +static int waitFor; + +static +long doneSubr(subRecord *prec) +{ + if (--waitFor <= 0) + epicsEventMustTrigger(done); + return 0; +} void asyncproctest_registerRecordDeviceDriver(struct dbBase *); MAIN(asyncproctest) { - testPlan(0); + testPlan(21); + + done = epicsEventMustCreate(epicsEventEmpty); testdbPrepare(); testdbReadDatabase("asyncproctest.dbd", NULL, NULL); asyncproctest_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("asyncproctest.db", NULL, "TPRO=1"); + registryFunctionAdd("doneSubr", (REGISTRYFUNCTION) doneSubr); + testdbReadDatabase("asyncproctest.db", NULL, "TPRO=0"); + + dbAccessDebugPUTF = 1; testIocInitOk(); testDiag("===== Chain 1 ======"); + waitFor = 2; testdbPutFieldOk("chain1.B", DBF_LONG, 6); testdbPutFieldOk("chain1.B", DBF_LONG, 7); - epicsThreadSleep(1.0); + if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK) + testAbort("Processing timed out"); testdbGetFieldEqual("chain1", DBF_LONG, 7); testdbGetFieldEqual("chain1.A", DBF_LONG, 2); testDiag("===== Chain 2 ======"); + waitFor = 2; testdbPutFieldOk("chain2:1.B", DBF_LONG, 6); testdbPutFieldOk("chain2:1.B", DBF_LONG, 7); - epicsThreadSleep(1.0); + if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK) + testAbort("Processing timed out"); testdbGetFieldEqual("chain2:1", DBF_LONG, 7); testdbGetFieldEqual("chain2:2", DBF_LONG, 7); testdbGetFieldEqual("chain2:1.A", DBF_LONG, 2); testdbGetFieldEqual("chain2:2.A", DBF_LONG, 2); + testDiag("===== Chain 2 again ======"); + + waitFor = 2; + testdbPutFieldOk("chain2:1.B", DBF_LONG, 6); + testdbPutFieldOk("chain2:1.B", DBF_LONG, 7); + testdbPutFieldOk("chain2:1.B", DBF_LONG, 8); + + if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK) + testAbort("Processing timed out"); + + testdbGetFieldEqual("chain2:1", DBF_LONG, 8); + testdbGetFieldEqual("chain2:2", DBF_LONG, 8); + testdbGetFieldEqual("chain2:1.A", DBF_LONG, 5); + testdbGetFieldEqual("chain2:2.A", DBF_LONG, 4); + testDiag("===== Chain 3 ======"); + waitFor = 2; testdbPutFieldOk("chain3.B", DBF_LONG, 6); testdbPutFieldOk("chain3.B", DBF_LONG, 7); - epicsThreadSleep(1.0); + if (epicsEventWaitWithTimeout(done, 10.0) != epicsEventOK) + testAbort("Processing timed out"); testdbGetFieldEqual("chain3", DBF_LONG, 7); testdbGetFieldEqual("chain3.A", DBF_LONG, 2); diff --git a/src/std/rec/test/asyncproctest.db b/src/std/rec/test/asyncproctest.db index e2fc946d8..352b6ca56 100644 --- a/src/std/rec/test/asyncproctest.db +++ b/src/std/rec/test/asyncproctest.db @@ -5,6 +5,11 @@ record(calcout, "chain1") { field(CALC, "A:=A+1;B") field(ODLY, "0.1") field(TPRO, "$(TPRO=)") + field(FLNK, "done1") +} +record(sub, "done1") { + field(SNAM, "doneSubr") + field(TPRO, "$(TPRO=)") } @@ -12,22 +17,39 @@ record(calcout, "chain1") { # async record chained after syncronous record record(calcout, "chain2:1") { field(CALC, "A:=A+1;B") - # DOLY=0 synchronous + # ODLY=0 synchronous field(OUT , "chain2:2.B PP") field(TPRO, "$(TPRO=)") } +record(ai, "chain2:3") { + field(INP, "chain2:1 CPP") + field(FLNK, "chain2:2") + field(TPRO, "$(TPRO=)") +} + record(calcout, "chain2:2") { field(CALC, "A:=A+1;B") - field(ODLY, "0.1") + field(ODLY, "0.5") + field(TPRO, "$(TPRO=)") + field(FLNK, "done2") +} +record(sub, "done2") { + field(SNAM, "doneSubr") field(TPRO, "$(TPRO=)") } + # ANJ's error case -# async record FLNK's to itself +# async record FLNK's to itself (via done3) record(calcout, "chain3") { field(CALC, "A:=A+1;B") field(ODLY, "0.1") + field(FLNK, "done3") + field(TPRO, "$(TPRO=)") +} +record(sub, "done3") { + field(SNAM, "doneSubr") field(FLNK, "chain3") field(TPRO, "$(TPRO=)") }