dbNotify: honour processRequest in processNotifyCommon (#988)
* dbNotify: honour processRequest in processNotifyCommon
dbNotify.h:132-137 documents that a process request is issued when the
requester asked for one and the record is passive, but 056304409 added
that rule and the enumerator while testing only processGetRequest, so
processRequest has always yielded no put, no process, and notifyOK.
This commit is contained in:
1 parent
93cf13a342
commit
8d044c558a
5 files changed
+162
-1
No files matched your search
@@ -245,7 +245,8 @@ static void processNotifyCommon(processNotify *ppn, dbCommon *precord, int first
|
||||
(dbChannelFldDes(ppn->chan)->process_passive && precord->scan == 0)))
|
||||
doProcess = 1;
|
||||
else
|
||||
if (ppn->requestType == processGetRequest &&
|
||||
if ((ppn->requestType == processRequest ||
|
||||
ppn->requestType == processGetRequest) &&
|
||||
precord->scan == 0)
|
||||
doProcess = 1;
|
||||
|
||||
|
||||
@@ -49,6 +49,13 @@ dbScanTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp
|
||||
testHarness_SRCS += dbScanTest.c
|
||||
TESTS += dbScanTest
|
||||
|
||||
TESTPROD_HOST += dbNotifyTest
|
||||
dbNotifyTest_SRCS += dbNotifyTest.c
|
||||
dbNotifyTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp
|
||||
testHarness_SRCS += dbNotifyTest.c
|
||||
TESTFILES += ../dbNotifyTest.db
|
||||
TESTS += dbNotifyTest
|
||||
|
||||
TESTPROD_HOST += dbShutdownTest
|
||||
dbShutdownTest_SRCS += dbShutdownTest.c
|
||||
dbShutdownTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/*************************************************************************\
|
||||
* SPDX-License-Identifier: EPICS
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* Which requestType leads dbProcessNotify() to process the record, per the
|
||||
* three rules stated in dbNotify.h.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "dbAccess.h"
|
||||
#include "dbChannel.h"
|
||||
#include "dbNotify.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "errlog.h"
|
||||
|
||||
#include "dbUnitTest.h"
|
||||
#include "testMain.h"
|
||||
|
||||
void dbTestIoc_registerRecordDeviceDriver(struct dbBase *);
|
||||
|
||||
typedef struct {
|
||||
processNotify notify;
|
||||
epicsEventId done;
|
||||
int puts; /* putCallback calls */
|
||||
int gets; /* getCallback calls */
|
||||
int didPut; /* what putCallback reports back */
|
||||
/* Read in doneCallback: dbNotifyCancel() overwrites notify.status. */
|
||||
notifyStatus status;
|
||||
int wasProcessed;
|
||||
} request;
|
||||
|
||||
static int putCallback(processNotify *ppn, notifyPutType type)
|
||||
{
|
||||
request *r = (request *) ppn->usrPvt;
|
||||
epicsUInt8 one = 1;
|
||||
|
||||
r->puts++;
|
||||
if (!r->didPut)
|
||||
return 0;
|
||||
if (dbChannelPut(ppn->chan, DBR_UCHAR, &one, 1))
|
||||
ppn->status = notifyError;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
{
|
||||
request *r = (request *) ppn->usrPvt;
|
||||
epicsUInt8 scratch;
|
||||
long count = 1;
|
||||
|
||||
r->gets++;
|
||||
dbChannelGet(ppn->chan, DBR_UCHAR, &scratch, NULL, &count, NULL);
|
||||
}
|
||||
|
||||
static void doneCallback(processNotify *ppn)
|
||||
{
|
||||
request *r = (request *) ppn->usrPvt;
|
||||
|
||||
r->status = ppn->status;
|
||||
r->wasProcessed = ppn->wasProcessed;
|
||||
epicsEventMustTrigger(r->done);
|
||||
}
|
||||
|
||||
/* One complete request against pv, run to its doneCallback. */
|
||||
static void run(request *r, const char *what, const char *pv,
|
||||
notifyRequestType type, int didPut)
|
||||
{
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->didPut = didPut;
|
||||
r->done = epicsEventMustCreate(epicsEventEmpty);
|
||||
r->notify.requestType = type;
|
||||
r->notify.putCallback = putCallback;
|
||||
r->notify.getCallback = getCallback;
|
||||
r->notify.doneCallback = doneCallback;
|
||||
r->notify.usrPvt = r;
|
||||
r->notify.chan = dbChannelCreate(pv);
|
||||
if (!r->notify.chan || dbChannelOpen(r->notify.chan))
|
||||
testAbort("dbChannelCreate(\"%s\") failed", pv);
|
||||
|
||||
testDiag("%s: %s", what, pv);
|
||||
dbProcessNotify(&r->notify);
|
||||
testOk(epicsEventWaitWithTimeout(r->done, 10.0) == epicsEventWaitOK,
|
||||
"doneCallback ran");
|
||||
|
||||
dbNotifyCancel(&r->notify);
|
||||
dbChannelDelete(r->notify.chan);
|
||||
epicsEventDestroy(r->done);
|
||||
}
|
||||
|
||||
MAIN(dbNotifyTest)
|
||||
{
|
||||
request r;
|
||||
|
||||
testPlan(19);
|
||||
|
||||
testdbPrepare();
|
||||
testdbReadDatabase("dbTestIoc.dbd", NULL, NULL);
|
||||
dbTestIoc_registerRecordDeviceDriver(pdbbase);
|
||||
testdbReadDatabase("dbNotifyTest.db", NULL, NULL);
|
||||
|
||||
eltc(0);
|
||||
testIocInitOk();
|
||||
eltc(1);
|
||||
|
||||
run(&r, "rule 1, process request on a passive record",
|
||||
"passive.VAL", processRequest, 0);
|
||||
testOk1(r.wasProcessed == 1);
|
||||
testOk1(r.status == notifyOK);
|
||||
testOk(r.puts == 0 && r.gets == 0,
|
||||
"processRequest calls neither the put nor the get callback");
|
||||
|
||||
run(&r, "rule 1 does not apply when the record is not passive",
|
||||
"scanned.VAL", processRequest, 0);
|
||||
testOk1(r.wasProcessed == 0);
|
||||
testOk1(r.status == notifyOK);
|
||||
|
||||
run(&r, "rule 2, a put through PROC",
|
||||
"passive.PROC", putProcessRequest, 1);
|
||||
testOk1(r.wasProcessed == 1);
|
||||
testOk1(r.puts == 1);
|
||||
|
||||
run(&r, "rule 2 needs the put to have happened",
|
||||
"passive.PROC", putProcessRequest, 0);
|
||||
testOk1(r.wasProcessed == 0);
|
||||
testOk1(r.puts == 1);
|
||||
|
||||
run(&r, "rule 2 needs PROC or a process-passive field",
|
||||
"passive.VAL", putProcessRequest, 1);
|
||||
testOk1(r.wasProcessed == 0);
|
||||
testOk1(r.puts == 1);
|
||||
|
||||
run(&r, "rule 3, processGet on a passive record",
|
||||
"passive.VAL", processGetRequest, 0);
|
||||
testOk1(r.wasProcessed == 1);
|
||||
testOk1(r.gets == 1);
|
||||
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
|
||||
return testDone();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
record(x, "passive") {
|
||||
}
|
||||
|
||||
record(x, "scanned") {
|
||||
field(SCAN, "Event")
|
||||
field(EVNT, "neverTriggered")
|
||||
}
|
||||
@@ -25,6 +25,7 @@ int dbServerTest(void);
|
||||
int dbCaStatsTest(void);
|
||||
int dbShutdownTest(void);
|
||||
int dbScanTest(void);
|
||||
int dbNotifyTest(void);
|
||||
int scanIoTest(void);
|
||||
int dbLockTest(void);
|
||||
int dbPutLinkTest(void);
|
||||
@@ -48,6 +49,7 @@ void epicsRunDbTests(void)
|
||||
runTest(dbCaStatsTest);
|
||||
runTest(dbShutdownTest);
|
||||
runTest(dbScanTest);
|
||||
runTest(dbNotifyTest);
|
||||
runTest(scanIoTest);
|
||||
runTest(dbLockTest);
|
||||
runTest(dbPutLinkTest);
|
||||
|
||||
Reference in new issue
Block a user