Add tests for Async Soft Channel devices
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in the file LICENSE that is included with this distribution.
|
||||
# in the file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
TOP=../../../..
|
||||
|
||||
@@ -60,6 +60,13 @@ testHarness_SRCS += compressTest.c
|
||||
TESTFILES += ../compressTest.db
|
||||
TESTS += compressTest
|
||||
|
||||
TESTPROD_HOST += asyncSoftTest
|
||||
asyncSoftTest_SRCS += asyncSoftTest.c
|
||||
asyncSoftTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp
|
||||
testHarness_SRCS += asyncSoftTest.c
|
||||
TESTFILES += ../asyncSoftTest.db
|
||||
TESTS += asyncSoftTest
|
||||
|
||||
TARGETS += $(COMMON_DIR)/asTestIoc.dbd
|
||||
DBDDEPENDS_FILES += asTestIoc.dbd$(DEP)
|
||||
asTestIoc_DBD += base.dbd
|
||||
|
||||
189
src/std/rec/test/asyncSoftTest.c
Normal file
189
src/std/rec/test/asyncSoftTest.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2017 UChicago Argonne LLC, as operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "dbAccess.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbTest.h"
|
||||
#include "dbUnitTest.h"
|
||||
#include "epicsEvent.h"
|
||||
#include "errlog.h"
|
||||
#include "registryFunction.h"
|
||||
#include "subRecord.h"
|
||||
#include "testMain.h"
|
||||
|
||||
static int startCounter, doneCounter;
|
||||
static epicsEventId asyncEvent, doneEvent;
|
||||
|
||||
static
|
||||
long asyncSubr(subRecord *prec)
|
||||
{
|
||||
testDiag("Processing %s, pact=%d", prec->name, prec->pact);
|
||||
|
||||
if (!prec->pact) {
|
||||
epicsEventTrigger(asyncEvent);
|
||||
prec->pact = 1; /* Make asynchronous */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
long doneSubr(subRecord *prec)
|
||||
{
|
||||
epicsEventTrigger(doneEvent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void checkAsyncInput(const char *rec, int init, dbCommon *async)
|
||||
{
|
||||
char inp[16], proc[16];
|
||||
|
||||
testDiag("Checking record '%s'", rec);
|
||||
|
||||
strcpy(inp, rec);
|
||||
strcat(inp, ".INP");
|
||||
strcpy(proc, rec);
|
||||
strcat(proc, ".PROC");
|
||||
|
||||
if (init) {
|
||||
testdbGetFieldEqual(rec, DBF_LONG, init);
|
||||
|
||||
testdbPutFieldOk(inp, DBF_STRING, "async");
|
||||
}
|
||||
|
||||
testdbPutFieldOk(proc, DBF_CHAR, 1);
|
||||
|
||||
epicsEventWait(asyncEvent);
|
||||
testdbGetFieldEqual("startCounter", DBF_LONG, ++startCounter);
|
||||
testdbGetFieldEqual("doneCounter", DBF_LONG, doneCounter);
|
||||
|
||||
dbScanLock(async);
|
||||
async->rset->process(async);
|
||||
dbScanUnlock(async);
|
||||
|
||||
epicsEventWait(doneEvent);
|
||||
testdbGetFieldEqual("startCounter", DBF_LONG, startCounter);
|
||||
testdbGetFieldEqual("doneCounter", DBF_LONG, ++doneCounter);
|
||||
}
|
||||
|
||||
static
|
||||
void testAsynInputs(dbCommon *async)
|
||||
{
|
||||
const char * records[] = {
|
||||
"ai0", "bi0", "di0", "ii0", "li0", "mi0", "si0", NULL,
|
||||
"bi1", /* bi1 must be first in this group */
|
||||
"ai1", "di1", "ii1", "li1", "mi1", "si1", NULL,
|
||||
};
|
||||
const char ** rec = &records[0];
|
||||
int init = 1; /* bi1 initializes to 1 */
|
||||
|
||||
testDiag("============ Starting %s ============", EPICS_FUNCTION);
|
||||
|
||||
startCounter = doneCounter = 0;
|
||||
testdbPutFieldOk("startCounter", DBF_LONG, startCounter);
|
||||
testdbPutFieldOk("doneCounter", DBF_LONG, doneCounter);
|
||||
|
||||
epicsEventTryWait(asyncEvent);
|
||||
epicsEventTryWait(doneEvent);
|
||||
|
||||
while (*rec) { /* 1st group don't need initializing */
|
||||
checkAsyncInput(*rec++, 0, async);
|
||||
}
|
||||
rec++;
|
||||
while (*rec) {
|
||||
checkAsyncInput(*rec++, init, async);
|
||||
init = 9; /* remainder initialize to 9 */
|
||||
}
|
||||
|
||||
testDiag("============= Ending %s =============", EPICS_FUNCTION);
|
||||
}
|
||||
|
||||
static
|
||||
void checkAsyncOutput(const char *rec, dbCommon *async)
|
||||
{
|
||||
char proc[16];
|
||||
|
||||
testDiag("Checking record '%s'", rec);
|
||||
|
||||
strcpy(proc, rec);
|
||||
strcat(proc, ".PROC");
|
||||
|
||||
testdbPutFieldOk(proc, DBF_CHAR, 1);
|
||||
|
||||
epicsEventWait(asyncEvent);
|
||||
testdbGetFieldEqual("startCounter", DBF_LONG, ++startCounter);
|
||||
testdbGetFieldEqual("doneCounter", DBF_LONG, doneCounter);
|
||||
|
||||
dbScanLock(async);
|
||||
async->rset->process(async);
|
||||
dbScanUnlock(async);
|
||||
|
||||
epicsEventWait(doneEvent);
|
||||
testdbGetFieldEqual("startCounter", DBF_LONG, startCounter);
|
||||
testdbGetFieldEqual("doneCounter", DBF_LONG, ++doneCounter);
|
||||
}
|
||||
|
||||
static
|
||||
void testAsyncOutputs(dbCommon *async)
|
||||
{
|
||||
const char * records[] = {
|
||||
"ao1", "bo1", "do1", "io1", "lo1", "lso1", "mo1", "so1", NULL,
|
||||
};
|
||||
const char ** rec = &records[0];
|
||||
|
||||
testDiag("============ Starting %s ============", EPICS_FUNCTION);
|
||||
|
||||
startCounter = doneCounter = 0;
|
||||
testdbPutFieldOk("startCounter", DBF_LONG, startCounter);
|
||||
testdbPutFieldOk("doneCounter", DBF_LONG, doneCounter);
|
||||
|
||||
epicsEventTryWait(asyncEvent);
|
||||
epicsEventTryWait(doneEvent);
|
||||
|
||||
while (*rec) {
|
||||
checkAsyncOutput(*rec++, async);
|
||||
}
|
||||
|
||||
testDiag("============= Ending %s =============", EPICS_FUNCTION);
|
||||
}
|
||||
|
||||
void recTestIoc_registerRecordDeviceDriver(struct dbBase *);
|
||||
|
||||
MAIN(recMiscTest)
|
||||
{
|
||||
dbCommon *async;
|
||||
|
||||
testPlan(0);
|
||||
|
||||
testdbPrepare();
|
||||
testdbReadDatabase("recTestIoc.dbd", NULL, NULL);
|
||||
|
||||
recTestIoc_registerRecordDeviceDriver(pdbbase);
|
||||
registryFunctionAdd("asyncSubr", (REGISTRYFUNCTION) asyncSubr);
|
||||
registryFunctionAdd("doneSubr", (REGISTRYFUNCTION) doneSubr);
|
||||
|
||||
testdbReadDatabase("asyncSoftTest.db", NULL, NULL);
|
||||
|
||||
eltc(0);
|
||||
testIocInitOk();
|
||||
eltc(1);
|
||||
|
||||
async = testdbRecordPtr("async");
|
||||
asyncEvent = epicsEventCreate(epicsEventEmpty);
|
||||
doneEvent = epicsEventCreate(epicsEventEmpty);
|
||||
|
||||
testAsynInputs(async);
|
||||
testAsyncOutputs(async);
|
||||
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
|
||||
return testDone();
|
||||
}
|
||||
188
src/std/rec/test/asyncSoftTest.db
Normal file
188
src/std/rec/test/asyncSoftTest.db
Normal file
@@ -0,0 +1,188 @@
|
||||
record(ai, "ai0") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, "async")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(bi, "bi0") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, "async")
|
||||
field(FLNK, "done")
|
||||
field(ZNAM, "Zero")
|
||||
field(ONAM, "One")
|
||||
}
|
||||
record(int64in, "ii0") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, "async")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(longin, "li0") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, "async")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(mbbiDirect, "di0") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, "async")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(mbbi, "mi0") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, "async")
|
||||
field(FLNK, "done")
|
||||
field(ZRST, "Zero")
|
||||
field(ONST, "One")
|
||||
field(TWST, "Two")
|
||||
field(THST, "Three")
|
||||
field(FRST, "Four")
|
||||
field(FVST, "Five")
|
||||
field(SXST, "Six")
|
||||
field(SVST, "Seven")
|
||||
field(EIST, "Eight")
|
||||
field(NIST, "Nine")
|
||||
field(TEST, "Ten")
|
||||
field(ELST, "Eleven")
|
||||
field(TWST, "Twelve")
|
||||
field(TTST, "Thirteen")
|
||||
field(FTST, "Fourteen")
|
||||
field(FFST, "Fifteen")
|
||||
}
|
||||
record(stringin, "si0") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, "async")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
|
||||
record(ai, "ai1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, {const:9})
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(bi, "bi1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, {const:1})
|
||||
field(FLNK, "done")
|
||||
field(ZNAM, "Zero")
|
||||
field(ONAM, "One")
|
||||
}
|
||||
record(int64in, "ii1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, {const:9})
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(longin, "li1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, {const:9})
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(mbbiDirect, "di1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, {const:9})
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(mbbi, "mi1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(INP, {const:9})
|
||||
field(FLNK, "done")
|
||||
field(ZRST, "Zero")
|
||||
field(ONST, "One")
|
||||
field(TWST, "Two")
|
||||
field(THST, "Three")
|
||||
field(FRST, "Four")
|
||||
field(FVST, "Five")
|
||||
field(SXST, "Six")
|
||||
field(SVST, "Seven")
|
||||
field(EIST, "Eight")
|
||||
field(NIST, "Nine")
|
||||
field(TEST, "Ten")
|
||||
field(ELST, "Eleven")
|
||||
field(TWST, "Twelve")
|
||||
field(TTST, "Thirteen")
|
||||
field(FTST, "Fourteen")
|
||||
field(FFST, "Fifteen")
|
||||
}
|
||||
record(stringin, "si1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(INP, {const:"9"})
|
||||
field(FLNK, "done")
|
||||
}
|
||||
|
||||
record(sub, "async") {
|
||||
field(INPA, "startCounter PP")
|
||||
field(SNAM, "asyncSubr")
|
||||
}
|
||||
record(calc, "startCounter") {
|
||||
field(CALC, "VAL+1")
|
||||
}
|
||||
record(sub, "done") {
|
||||
field(INPA, "doneCounter PP")
|
||||
field(SNAM, "doneSubr")
|
||||
}
|
||||
record(calc, "doneCounter") {
|
||||
field(CALC, "VAL+1")
|
||||
}
|
||||
|
||||
record(ao, "ao1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(bo, "bo1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
field(ZNAM, "Zero")
|
||||
field(ONAM, "One")
|
||||
}
|
||||
record(int64out, "io1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(longout, "lo1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(mbboDirect, "do1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
record(mbbo, "mo1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(NOBT, 4)
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
field(ZRST, "Zero")
|
||||
field(ONST, "One")
|
||||
field(TWST, "Two")
|
||||
field(THST, "Three")
|
||||
field(FRST, "Four")
|
||||
field(FVST, "Five")
|
||||
field(SXST, "Six")
|
||||
field(SVST, "Seven")
|
||||
field(EIST, "Eight")
|
||||
field(NIST, "Nine")
|
||||
field(TEST, "Ten")
|
||||
field(ELST, "Eleven")
|
||||
field(TWST, "Twelve")
|
||||
field(TTST, "Thirteen")
|
||||
field(FTST, "Fourteen")
|
||||
field(FFST, "Fifteen")
|
||||
}
|
||||
record(lso, "lso1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
field(SIZV, 40)
|
||||
}
|
||||
record(stringout, "so1") {
|
||||
field(DTYP, "Async Soft Channel")
|
||||
field(OUT, "async.PROC CA")
|
||||
field(FLNK, "done")
|
||||
}
|
||||
Reference in New Issue
Block a user