rec: add tests for simulation mode
This commit is contained in:
@@ -104,6 +104,19 @@ regressTest_SRCS += regressTest_registerRecordDeviceDriver.cpp
|
||||
TESTFILES += $(COMMON_DIR)/regressTest.dbd ../regressArray1.db ../regressHex.db ../regressLinkMS.db
|
||||
TESTS += regressTest
|
||||
|
||||
TARGETS += $(COMMON_DIR)/simmTest.dbd
|
||||
TARGETS += $(COMMON_DIR)/simmTest.db
|
||||
DBDDEPENDS_FILES += simmTest.dbd$(DEP)
|
||||
DBDDEPENDS_FILES += simmTest.db$(DEP)
|
||||
simmTest_DBD += base.dbd
|
||||
TESTPROD_HOST += simmTest
|
||||
simmTest_SRCS += simmTest.c
|
||||
simmTest_SRCS += simmTest_registerRecordDeviceDriver.cpp
|
||||
testHarness_SRCS += simmTest.c
|
||||
testHarness_SRCS += simmTest_registerRecordDeviceDriver.cpp
|
||||
TESTFILES += $(COMMON_DIR)/simmTest.dbd $(COMMON_DIR)/simmTest.db
|
||||
TESTS += simmTest
|
||||
|
||||
# epicsRunRecordTests runs all the test programs in a known working order.
|
||||
testHarness_SRCS += epicsRunRecordTests.c
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ int asTest(void);
|
||||
int linkRetargetLinkTest(void);
|
||||
int linkInitTest(void);
|
||||
int asyncSoftTest(void);
|
||||
int simmTest(void);
|
||||
|
||||
void epicsRunRecordTests(void)
|
||||
{
|
||||
@@ -41,5 +42,7 @@ void epicsRunRecordTests(void)
|
||||
|
||||
runTest(asyncSoftTest);
|
||||
|
||||
runTest(simmTest);
|
||||
|
||||
epicsExit(0); /* Trigger test harness */
|
||||
}
|
||||
|
||||
16
src/std/rec/test/simmSetup.db
Normal file
16
src/std/rec/test/simmSetup.db
Normal file
@@ -0,0 +1,16 @@
|
||||
# no info
|
||||
record(ai, "ai-0") {
|
||||
}
|
||||
# only scan
|
||||
record(ai, "ai-1") {
|
||||
field(SSCN,"2 second")
|
||||
}
|
||||
# only delay
|
||||
record(ai, "ai-2") {
|
||||
field(SDLY,".234")
|
||||
}
|
||||
# scan and delay
|
||||
record(ai, "ai-3") {
|
||||
field(SSCN,"5 second")
|
||||
field(SDLY,".345")
|
||||
}
|
||||
468
src/std/rec/test/simmTest.c
Normal file
468
src/std/rec/test/simmTest.c
Normal file
@@ -0,0 +1,468 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2017 ITER Organization
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dbUnitTest.h>
|
||||
#include <testMain.h>
|
||||
#include <dbAccess.h>
|
||||
#include <epicsTime.h>
|
||||
#include <epicsThread.h>
|
||||
#include <errlog.h>
|
||||
|
||||
#include "recSup.h"
|
||||
#include "aiRecord.h"
|
||||
#include "aoRecord.h"
|
||||
#include "aaiRecord.h"
|
||||
#include "aaoRecord.h"
|
||||
#include "biRecord.h"
|
||||
#include "boRecord.h"
|
||||
#include "mbbiRecord.h"
|
||||
#include "mbboRecord.h"
|
||||
#include "mbbiDirectRecord.h"
|
||||
#include "mbboDirectRecord.h"
|
||||
#include "longinRecord.h"
|
||||
#include "longoutRecord.h"
|
||||
#include "int64inRecord.h"
|
||||
#include "int64outRecord.h"
|
||||
#include "stringinRecord.h"
|
||||
#include "stringoutRecord.h"
|
||||
#include "lsiRecord.h"
|
||||
#include "lsoRecord.h"
|
||||
#include "eventRecord.h"
|
||||
#include "histogramRecord.h"
|
||||
#include "waveformRecord.h"
|
||||
|
||||
/*
|
||||
* Tests for simulation mode
|
||||
*/
|
||||
|
||||
void simmTest_registerRecordDeviceDriver(struct dbBase *);
|
||||
|
||||
static
|
||||
void startSimmTestIoc(const char *dbfile)
|
||||
{
|
||||
testdbPrepare();
|
||||
testdbReadDatabase("simmTest.dbd", NULL, NULL);
|
||||
simmTest_registerRecordDeviceDriver(pdbbase);
|
||||
testdbReadDatabase(dbfile, NULL, NULL);
|
||||
|
||||
eltc(0);
|
||||
testIocInitOk();
|
||||
eltc(1);
|
||||
}
|
||||
|
||||
static char *rawSupp[] = {
|
||||
"ai",
|
||||
"bi",
|
||||
"mbbi",
|
||||
"mbbiDirect",
|
||||
};
|
||||
|
||||
static
|
||||
int hasRawSimmSupport(const char *rectype) {
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(rawSupp)/sizeof(rawSupp[0])); i++)
|
||||
if (strcmp(rectype, rawSupp[i]) == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PVNAMELENGTH 60
|
||||
static char nameVAL[PVNAMELENGTH];
|
||||
static char nameB0[PVNAMELENGTH];
|
||||
static char nameRVAL[PVNAMELENGTH];
|
||||
static char nameSGNL[PVNAMELENGTH];
|
||||
static char nameSIMM[PVNAMELENGTH];
|
||||
static char nameSIML[PVNAMELENGTH];
|
||||
static char nameSVAL[PVNAMELENGTH];
|
||||
static char nameSIOL[PVNAMELENGTH];
|
||||
static char nameSCAN[PVNAMELENGTH];
|
||||
static char namePROC[PVNAMELENGTH];
|
||||
static char namePACT[PVNAMELENGTH];
|
||||
static char nameSTAT[PVNAMELENGTH];
|
||||
static char nameSEVR[PVNAMELENGTH];
|
||||
static char nameSIMS[PVNAMELENGTH];
|
||||
static char nameTSE[PVNAMELENGTH];
|
||||
static char nameSimmode[PVNAMELENGTH];
|
||||
static char nameSimval[PVNAMELENGTH];
|
||||
static char nameSimvalNORD[PVNAMELENGTH];
|
||||
static char nameSimvalLEN[PVNAMELENGTH];
|
||||
|
||||
#define SETNAME(field) strcpy(name ## field, name); strcat(name ## field, "." #field)
|
||||
static
|
||||
void setNames(const char *name)
|
||||
{
|
||||
SETNAME(VAL); SETNAME(B0); SETNAME(RVAL); SETNAME(SGNL);
|
||||
SETNAME(SVAL); SETNAME(SIMM); SETNAME(SIML); SETNAME(SIOL); SETNAME(SIMS);
|
||||
SETNAME(SCAN); SETNAME(PROC); SETNAME(PACT);
|
||||
SETNAME(STAT); SETNAME(SEVR); SETNAME(TSE);
|
||||
strcpy(nameSimmode, name); strcat(nameSimmode, ":simmode");
|
||||
strcpy(nameSimval, name); strcat(nameSimval, ":simval");
|
||||
strcpy(nameSimvalNORD, name); strcat(nameSimvalNORD, ":simval.NORD");
|
||||
strcpy(nameSimvalLEN, name); strcat(nameSimvalLEN, ":simval.LEN");
|
||||
}
|
||||
|
||||
/*
|
||||
* Parsing of info items and xsimm structure setting
|
||||
*/
|
||||
static
|
||||
void testSimmSetup(void)
|
||||
{
|
||||
aiRecord *precai;
|
||||
|
||||
testDiag("##### Simm initialization #####");
|
||||
|
||||
/* no config */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-0");
|
||||
testOk(precai->simpvt == NULL, "ai-0.SIMPVT = %p == NULL [no callback]", precai->simpvt);
|
||||
testOk(precai->sscn == USHRT_MAX, "ai-0.SSCN = %u == USHRT_MAX (not set)", precai->sscn);
|
||||
testOk(precai->sdly < 0., "ai-0.SDLY = %g < 0.0 (not set)", precai->sdly);
|
||||
|
||||
/* with SCAN */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-1");
|
||||
testOk(precai->sscn == 5, "ai-1.SSCN = %u == 5 (2 second)", precai->sscn);
|
||||
testOk(precai->sdly < 0., "ai-1.SDLY = %g < 0.0 (not set)", precai->sdly);
|
||||
|
||||
/* with DELAY */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-2");
|
||||
testOk(precai->sscn == USHRT_MAX, "ai-2.SSCN = %u == USHRT_MAX (not set)", precai->sscn);
|
||||
testOk(precai->sdly == 0.234, "ai-2.SDLY = %g == 0.234", precai->sdly);
|
||||
|
||||
/* with SCAN and DELAY */
|
||||
precai = (aiRecord*)testdbRecordPtr("ai-3");
|
||||
testOk(precai->sscn == 4, "ai-3.SSCN = %u == 4 (5 second)", precai->sscn);
|
||||
testOk(precai->sdly == 0.345, "ai-3.SDLY = %g == 0.345", precai->sdly);
|
||||
}
|
||||
|
||||
/*
|
||||
* SIMM triggered SCAN swapping, by writing to SIMM and through SIML
|
||||
*/
|
||||
|
||||
static
|
||||
void testSimmToggle(const char *name, epicsEnum16 *psscn)
|
||||
{
|
||||
testDiag("## SIMM toggle and SCAN swapping ##");
|
||||
|
||||
/* SIMM mode by setting the field */
|
||||
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
|
||||
testDiag("set SIMM to YES");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "YES");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
/* Change simm:SCAN when simmYES */
|
||||
testdbPutFieldOk(nameSCAN, DBR_USHORT, 3);
|
||||
|
||||
testDiag("set SIMM to NO");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "NO");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 3, "SSCN = %u == 3 (10 second)", *psscn);
|
||||
*psscn = 1;
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("set SIMM to RAW");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "RAW");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
testDiag("set SIMM to NO");
|
||||
testdbPutFieldOk(nameSIMM, DBR_STRING, "NO");
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
|
||||
/* SIMM mode through SIML */
|
||||
|
||||
testdbPutFieldOk(nameSIML, DBR_STRING, nameSimmode);
|
||||
|
||||
testDiag("set SIMM (via SIML -> simmode) to YES");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 1);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
testDiag("set SIMM (via SIML -> simmode) to NO");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 0);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("set SIMM (via SIML -> simmode) to RAW");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 2);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 1);
|
||||
testOk(*psscn == 0, "SSCN = %u == 0 (Passive)", *psscn);
|
||||
|
||||
testDiag("set SIMM (via SIML -> simmode) to NO");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
|
||||
testdbGetFieldEqual(nameSIMM, DBR_USHORT, 0);
|
||||
testdbGetFieldEqual(nameSCAN, DBR_USHORT, 0);
|
||||
testOk(*psscn == 1, "SSCN = %u == 1 (Event)", *psscn);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading from SVAL (direct write or through SIOL link)
|
||||
*/
|
||||
|
||||
static
|
||||
void testSvalRead(const char *name,
|
||||
const epicsTimeStamp *mytime,
|
||||
const epicsTimeStamp *svtime)
|
||||
{
|
||||
epicsTimeStamp last;
|
||||
|
||||
if (strcmp(name, "histogram") == 0)
|
||||
strcpy(nameVAL, nameSGNL);
|
||||
|
||||
if (strcmp(name, "aai") != 0 &&
|
||||
strcmp(name, "waveform") != 0 &&
|
||||
strcmp(name, "lsi") != 0) {
|
||||
|
||||
testDiag("## Reading from SVAL ##");
|
||||
|
||||
testDiag("in simmNO, SVAL must be ignored");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 0);
|
||||
if (strcmp(name, "stringin") == 0)
|
||||
testdbPutFieldOk(nameSVAL, DBR_STRING, "1");
|
||||
else
|
||||
testdbPutFieldOk(nameSVAL, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 0);
|
||||
|
||||
testDiag("in simmYES, SVAL is used for VAL");
|
||||
testdbPutFieldOk(nameSIMS, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 1);
|
||||
testDiag("No SIMS setting: STAT/SEVR == NO_ALARM");
|
||||
testdbGetFieldEqual(nameSTAT, DBR_STRING, "NO_ALARM");
|
||||
testdbGetFieldEqual(nameSEVR, DBR_USHORT, 0);
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("in simmRAW, SVAL is used for RVAL");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameRVAL, DBR_USHORT, 1);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
}
|
||||
|
||||
testDiag("## Reading from SIOL->SVAL ##");
|
||||
|
||||
/* Set SIOL link to simval */
|
||||
testdbPutFieldOk(nameSIOL, DBR_STRING, nameSimval);
|
||||
|
||||
testDiag("in simmNO, SIOL->SVAL must be ignored");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 0);
|
||||
testdbPutFieldOk(nameSimval, DBR_LONG, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 0);
|
||||
|
||||
testDiag("in simmYES, SIOL->SVAL is used for VAL");
|
||||
testdbPutFieldOk(nameSIMS, DBR_USHORT, 3);
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameVAL, DBR_USHORT, 1);
|
||||
testDiag("SIMS is INVALID: STAT/SEVR == SIMM/INVALID");
|
||||
testdbGetFieldEqual(nameSTAT, DBR_STRING, "SIMM");
|
||||
testdbGetFieldEqual(nameSEVR, DBR_USHORT, 3);
|
||||
testdbPutFieldOk(nameSIMS, DBR_USHORT, 0);
|
||||
|
||||
if (hasRawSimmSupport(name)) {
|
||||
testDiag("in simmRAW, SIOL->SVAL is used for RVAL");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(nameRVAL, DBR_USHORT, 1);
|
||||
} else {
|
||||
testDiag("Record type %s has no support for simmRAW", name);
|
||||
}
|
||||
|
||||
/* My timestamp must be later than simval's */
|
||||
testOk(epicsTimeLessThan(svtime, mytime), "simval time < my time [TSE = 0]");
|
||||
|
||||
testDiag("for TSE=-2 (from device) and simmYES, take time stamp from IOC or input link");
|
||||
|
||||
/* Set simmYES */
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
|
||||
/* Set TSE to -2 (from device) and reprocess: timestamps is taken through SIOL from simval */
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, -2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testOk(epicsTimeEqual(svtime, mytime), "simval time == my time [TSE = -2]");
|
||||
last = *mytime;
|
||||
|
||||
/* With TSE=-2 and no SIOL, timestamp is taken from IOC */
|
||||
testdbPutFieldOk(nameSIOL, DBR_STRING, "");
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testOk(epicsTimeLessThan(&last, mytime), "new time stamp from IOC [TSE = -2, no SIOL]");
|
||||
|
||||
/* Reset TSE */
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Writing through SIOL link
|
||||
*/
|
||||
|
||||
static
|
||||
void testSiolWrite(const char *name,
|
||||
const epicsTimeStamp *mytime)
|
||||
{
|
||||
epicsTimeStamp now;
|
||||
|
||||
testDiag("## Writing through SIOL ##");
|
||||
|
||||
/* Set SIOL link to simval */
|
||||
testdbPutFieldOk(nameSIOL, DBR_STRING, nameSimval);
|
||||
|
||||
testDiag("in simmNO, SIOL must be ignored");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
if (strcmp(name, "mbboDirect") == 0)
|
||||
testdbPutFieldOk(nameB0, DBR_LONG, 1);
|
||||
else
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 1);
|
||||
|
||||
if (strcmp(name, "aao") == 0)
|
||||
testdbGetFieldEqual(nameSimvalNORD, DBR_USHORT, 0);
|
||||
else if (strcmp(name, "lso") == 0)
|
||||
testdbGetFieldEqual(nameSimvalLEN, DBR_USHORT, 0);
|
||||
else
|
||||
testdbGetFieldEqual(nameSimval, DBR_USHORT, 0);
|
||||
|
||||
testDiag("in simmYES, SIOL is used to write VAL");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
if (strcmp(name, "mbboDirect") == 0)
|
||||
testdbPutFieldOk(nameB0, DBR_LONG, 1);
|
||||
else
|
||||
testdbPutFieldOk(nameVAL, DBR_LONG, 1);
|
||||
testdbGetFieldEqual(nameSimval, DBR_USHORT, 1);
|
||||
|
||||
/* Set TSE to -2 (from device) and reprocess: timestamp is taken from IOC */
|
||||
epicsTimeGetCurrent(&now);
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, -2);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testOk(epicsTimeLessThan(&now, mytime), "new time stamp from IOC [TSE = -2]");
|
||||
|
||||
/* Reset TSE */
|
||||
testdbPutFieldOk(nameTSE, DBR_SHORT, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Asynchronous processing using simm:DELAY
|
||||
*/
|
||||
|
||||
static
|
||||
void testSimmDelay(const char *name,
|
||||
epicsFloat64 *psdly,
|
||||
const epicsTimeStamp *mytime)
|
||||
{
|
||||
epicsTimeStamp now;
|
||||
const double delay = 0.01; /* 10 ms */
|
||||
|
||||
testDiag("## Asynchronous processing with simm:DELAY ##");
|
||||
|
||||
/* Set delay to something just long enough */
|
||||
*psdly = delay;
|
||||
|
||||
/* Process in simmNO: synchronous */
|
||||
testDiag("simm:DELAY and simmNO processes synchronously");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 0);
|
||||
epicsTimeGetCurrent(&now);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 0);
|
||||
testOk(epicsTimeLessThan(&now, mytime), "time stamp is recent");
|
||||
|
||||
/* Process in simmYES: asynchronous */
|
||||
testDiag("simm:DELAY and simmYES processes asynchronously");
|
||||
testdbPutFieldOk(nameSimmode, DBR_USHORT, 1);
|
||||
testdbPutFieldOk(namePROC, DBR_LONG, 0);
|
||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 1);
|
||||
epicsTimeGetCurrent(&now);
|
||||
epicsThreadSleep(1.5*delay);
|
||||
testdbGetFieldEqual(namePACT, DBR_USHORT, 0);
|
||||
testOk(epicsTimeLessThan(&now, mytime), "time stamp taken from second pass processing");
|
||||
|
||||
/* Reset delay */
|
||||
*psdly = -1.;
|
||||
}
|
||||
|
||||
#define RUNALLTESTSREAD(type) \
|
||||
testDiag("################################################### Record Type " #type); \
|
||||
setNames(#type); \
|
||||
testSimmToggle(#type, &((type ## Record*)testdbRecordPtr(#type))->sscn); \
|
||||
testSvalRead(#type, &((type ## Record*)testdbRecordPtr(#type))->time, \
|
||||
&((type ## Record*)testdbRecordPtr(#type ":simval"))->time); \
|
||||
testSimmDelay(#type, &((type ## Record*)testdbRecordPtr(#type))->sdly, \
|
||||
&((type ## Record*)testdbRecordPtr(#type))->time)
|
||||
|
||||
#define RUNALLTESTSWRITE(type) \
|
||||
testDiag("################################################### Record Type " #type); \
|
||||
setNames(#type); \
|
||||
testSimmToggle(#type, &((type ## Record*)testdbRecordPtr(#type))->sscn); \
|
||||
testSiolWrite(#type, &((type ## Record*)testdbRecordPtr(#type))->time); \
|
||||
testSimmDelay(#type, &((type ## Record*)testdbRecordPtr(#type))->sdly, \
|
||||
&((type ## Record*)testdbRecordPtr(#type))->time)
|
||||
|
||||
static
|
||||
void testAllRecTypes(void)
|
||||
{
|
||||
RUNALLTESTSREAD(ai);
|
||||
RUNALLTESTSWRITE(ao);
|
||||
RUNALLTESTSREAD(aai);
|
||||
RUNALLTESTSWRITE(aao);
|
||||
RUNALLTESTSREAD(bi);
|
||||
RUNALLTESTSWRITE(bo);
|
||||
RUNALLTESTSREAD(mbbi);
|
||||
RUNALLTESTSWRITE(mbbo);
|
||||
RUNALLTESTSREAD(mbbiDirect);
|
||||
RUNALLTESTSWRITE(mbboDirect);
|
||||
RUNALLTESTSREAD(longin);
|
||||
RUNALLTESTSWRITE(longout);
|
||||
RUNALLTESTSREAD(int64in);
|
||||
RUNALLTESTSWRITE(int64out);
|
||||
RUNALLTESTSREAD(stringin);
|
||||
RUNALLTESTSWRITE(stringout);
|
||||
RUNALLTESTSREAD(lsi);
|
||||
RUNALLTESTSWRITE(lso);
|
||||
RUNALLTESTSREAD(event);
|
||||
RUNALLTESTSREAD(waveform);
|
||||
RUNALLTESTSREAD(histogram);
|
||||
}
|
||||
|
||||
|
||||
MAIN(simmTest)
|
||||
{
|
||||
testPlan(0);
|
||||
startSimmTestIoc("simmTest.db");
|
||||
|
||||
testSimmSetup();
|
||||
testAllRecTypes();
|
||||
|
||||
testIocShutdownOk();
|
||||
testdbCleanup();
|
||||
return testDone();
|
||||
}
|
||||
30
src/std/rec/test/simmTest.substitutions
Normal file
30
src/std/rec/test/simmTest.substitutions
Normal file
@@ -0,0 +1,30 @@
|
||||
file "simmTestSimple.template" {
|
||||
{ TYPE="ai" }
|
||||
{ TYPE="ao" }
|
||||
{ TYPE="bi" }
|
||||
{ TYPE="bo" }
|
||||
{ TYPE="mbbi" }
|
||||
{ TYPE="mbbo" }
|
||||
{ TYPE="mbbiDirect" }
|
||||
{ TYPE="mbboDirect" }
|
||||
{ TYPE="longin" }
|
||||
{ TYPE="longout" }
|
||||
{ TYPE="int64in" }
|
||||
{ TYPE="int64out" }
|
||||
{ TYPE="stringin" }
|
||||
{ TYPE="stringout" }
|
||||
{ TYPE="lsi" }
|
||||
{ TYPE="lso" }
|
||||
{ TYPE="event" }
|
||||
}
|
||||
file "simmTestArray.template" {
|
||||
{ TYPE="aai" }
|
||||
{ TYPE="aao" }
|
||||
{ TYPE="waveform" }
|
||||
}
|
||||
file "simmTestHistogram.template" {
|
||||
{ TYPE="histogram" }
|
||||
}
|
||||
file "simmSetup.db" {
|
||||
{}
|
||||
}
|
||||
15
src/std/rec/test/simmTestArray.template
Normal file
15
src/std/rec/test/simmTestArray.template
Normal file
@@ -0,0 +1,15 @@
|
||||
# Array type records
|
||||
# Regular simulation mode and simm:SCAN tests
|
||||
record($(TYPE), "$(TYPE)") {
|
||||
field(SSCN,"Event")
|
||||
field(FTVL,"SHORT")
|
||||
field(NELM,"2")
|
||||
}
|
||||
record($(TYPE), "$(TYPE):simval") {
|
||||
field(FTVL,"SHORT")
|
||||
field(NELM,"2")
|
||||
}
|
||||
record(bo, "$(TYPE):simmode") {
|
||||
field(ZNAM,"off")
|
||||
field(ONAM,"on")
|
||||
}
|
||||
12
src/std/rec/test/simmTestHistogram.template
Normal file
12
src/std/rec/test/simmTestHistogram.template
Normal file
@@ -0,0 +1,12 @@
|
||||
# Array type records
|
||||
# Regular simulation mode and simm:SCAN tests
|
||||
record($(TYPE), "$(TYPE)") {
|
||||
field(SSCN,"Event")
|
||||
field(NELM,"2")
|
||||
}
|
||||
record(ai, "$(TYPE):simval") {
|
||||
}
|
||||
record(bo, "$(TYPE):simmode") {
|
||||
field(ZNAM,"off")
|
||||
field(ONAM,"on")
|
||||
}
|
||||
10
src/std/rec/test/simmTestSimple.template
Normal file
10
src/std/rec/test/simmTestSimple.template
Normal file
@@ -0,0 +1,10 @@
|
||||
# Regular simulation mode and simm:SCAN tests
|
||||
record($(TYPE), "$(TYPE)") {
|
||||
field(SSCN,"Event")
|
||||
}
|
||||
record($(TYPE), "$(TYPE):simval") {
|
||||
}
|
||||
record(bo, "$(TYPE):simmode") {
|
||||
field(ZNAM,"off")
|
||||
field(ONAM,"on")
|
||||
}
|
||||
Reference in New Issue
Block a user