Merge branch '7.0' into PSI-7.0

This commit is contained in:
2023-02-15 16:54:36 +01:00
455 changed files with 8983 additions and 5260 deletions

View File

@@ -321,7 +321,10 @@ MAIN(arrTest)
evtctx = db_init_events();
testOk(!!(plug = dbFindFilter(arr, strlen(arr))), "plugin arr registered correctly");
plug = dbFindFilter(arr, strlen(arr));
if (!plug)
testAbort("plugin '%s' not registered", arr);
testPass("plugin '%s' registered correctly", arr);
check(DBR_LONG);
check(DBR_DOUBLE);

View File

@@ -13,6 +13,7 @@
#include <string.h>
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbAccessDefs.h"
#include "db_field_log.h"
@@ -46,6 +47,7 @@ static void fl_setup(dbChannel *chan, db_field_log *pfl) {
pfl->stat = prec->stat;
pfl->sevr = prec->sevr;
pfl->time = prec->time;
pfl->mask = DBE_VALUE;
pfl->field_type = dbChannelFieldType(chan);
pfl->field_size = dbChannelFieldSize(chan);
pfl->no_elements = dbChannelElements(chan);

View File

@@ -145,8 +145,10 @@ MAIN(decTest)
evtctx = db_init_events();
testOk(!!(plug = dbFindFilter(myname, strlen(myname))),
"plugin '%s' registered correctly", myname);
plug = dbFindFilter(myname, strlen(myname));
if (!plug)
testAbort("Plugin '%s' not registered", myname);
testPass("plugin '%s' registered correctly", myname);
/* N < 1 */
testOk(!(pch = dbChannelCreate("x.VAL{dec:{n:-1}}")),

View File

@@ -223,6 +223,8 @@ MAIN(syncTest)
testOk(!!(plug = dbFindFilter(myname, strlen(myname))), "plugin %s registered correctly", myname);
testOk(!!(red = dbStateCreate("red")), "state 'red' created successfully");
if (!plug || !red)
testAbort("Can't continue given above failure(s)");
/* nonexisting state */
testOk(!(pch = dbChannelCreate("x.VAL{sync:{m:'while',s:'blue'}}")),

View File

@@ -72,7 +72,10 @@ MAIN(tsTest)
evtctx = db_init_events();
testOk(!!(plug = dbFindFilter(ts, strlen(ts))), "plugin ts registered correctly");
plug = dbFindFilter(ts, strlen(ts));
if (!plug)
testAbort("plugin '%s' not registered", ts);
testPass("plugin '%s' registered correctly", ts);
testOk(!!(pch = dbChannelCreate("x.VAL{ts:{}}")), "dbChannel with plugin ts created");
testOk((ellCount(&pch->filters) == 1), "channel has one plugin");

View File

@@ -21,7 +21,7 @@
#define testPutLongStr(PV, VAL) \
testdbPutArrFieldOk(PV, DBF_CHAR, sizeof(VAL), VAL);
void linkTest_registerRecordDeviceDriver(struct dbBase *);
int linkTest_registerRecordDeviceDriver(struct dbBase *);
static void startTestIoc(const char *dbfile)
{

View File

@@ -18,7 +18,7 @@
#include "testMain.h"
void linkTest_registerRecordDeviceDriver(struct dbBase *);
int linkTest_registerRecordDeviceDriver(struct dbBase *);
static void startTestIoc(const char *dbfile)
{

View File

@@ -37,9 +37,8 @@ TESTS += arrayOpTest
TESTPROD_HOST += recMiscTest
recMiscTest_SRCS += recMiscTest.c
ifeq (NO,$(STATIC_BUILD))
recMiscTest_CFLAGS += -DLINK_DYNAMIC
endif
recMiscTest_CFLAGS_NO = -DLINK_DYNAMIC
recMiscTest_CFLAGS += $(recMiscTest_CFLAGS_$(STATIC_BUILD))
recMiscTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp
testHarness_SRCS += recMiscTest.c
TESTFILES += ../recMiscTest.db
@@ -87,6 +86,13 @@ testHarness_SRCS += seqTest.c
TESTFILES += ../seqTest.db
TESTS += seqTest
TESTPROD_HOST += longoutTest
longoutTest_SRCS += longoutTest.c
longoutTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp
testHarness_SRCS += longoutTest.c
TESTFILES += ../longoutTest.db
TESTS += longoutTest
TARGETS += $(COMMON_DIR)/asTestIoc.dbd
DBDDEPENDS_FILES += asTestIoc.dbd$(DEP)
asTestIoc_DBD += base.dbd
@@ -128,6 +134,8 @@ regressTest_SRCS += regressTest.c
regressTest_SRCS += regressTest_registerRecordDeviceDriver.cpp
TESTFILES += $(COMMON_DIR)/regressTest.dbd ../regressArray1.db ../regressHex.db ../regressLinkMS.db
TESTFILES += ../badCaLink.db
TESTFILES += ../regressLongCalc.db
TESTFILES += ../regressLinkSevr.db
TESTS += regressTest
TARGETS += $(COMMON_DIR)/simmTest.dbd
@@ -166,12 +174,11 @@ testHarness_SRCS += linkFilterTest.c
TESTFILES += ../linkFilterTest.db
TESTS += linkFilterTest
# dbHeader* is only a compile test
# no need to actually run
TESTPROD += dbHeaderTest
dbHeaderTest_SRCS += dbHeaderTest.cpp
TESTPROD += dbHeaderTestxx
dbHeaderTestxx_SRCS += dbHeaderTestxx.cpp
# These are compile-time tests, no need to link or run
TARGETS += dbHeaderTest$(OBJ)
TARGET_SRCS += dbHeaderTest.cpp
TARGETS += dbHeaderTestxx$(OBJ)
TARGET_SRCS += dbHeaderTestxx.cpp
ifeq ($(T_A),$(EPICS_HOST_ARCH))
# Host-only tests of softIoc/softIocPVA, caget and pvget (if present)

View File

@@ -8,6 +8,8 @@
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbTest.h"
@@ -116,6 +118,8 @@ void checkAsyncOutput(const char *rec, dbCommon *async)
strcpy(proc, rec);
strcat(proc, ".PROC");
testdbCaWaitForConnect(dbGetDevLink(testdbRecordPtr(rec)));
testdbPutFieldOk(proc, DBF_CHAR, 1);
epicsEventWait(asyncEvent);

View File

@@ -6,7 +6,7 @@
\*************************************************************************/
/* This test includes all public headers from libCom and database modules
* to ensure they are all syntaxtically correct in both C and C++
* to ensure they are all syntactically correct in both C and C++
*/
#include <aaiRecord.h>

View File

@@ -144,6 +144,8 @@ static void testPrintfStrings()
static void testArrayInputs()
{
epicsInt32 oneToTwelve[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
epicsOldString reindeer[10] = {"Dasher", "Dancer", "Prancer", "Vixen",
"Comet", "Cupid", "Donner", "Blitzen", "Rudolph"};
testDiag("testArrayInputs");
@@ -168,6 +170,7 @@ static void testArrayInputs()
testdbGetArrFieldEqual("sa2.VAL", DBF_LONG, 10, 0, NULL);
testdbGetArrFieldEqual("wf1.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]);
testdbGetArrFieldEqual("wf2.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]);
testdbGetArrFieldEqual("reindeer.VAL", DBF_STRING, 10, 9, &reindeer[0]);
testdbPutFieldOk("sa1.INDX", DBF_LONG, 3);
testdbGetArrFieldEqual("sa1.VAL", DBF_LONG, 12, 9, &oneToTwelve[3]);
@@ -243,7 +246,7 @@ void testInt64Inputs(void)
MAIN(linkInitTest)
{
testPlan(78);
testPlan(79);
testLongStringInit();
testCalcInit();

View File

@@ -64,6 +64,12 @@ record(waveform, "wf2") {
field(FTVL, "LONG")
field(INP, {const:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]})
}
record(waveform, "reindeer") {
field(FTVL, "STRING")
field(NELM, "20")
field(INP, ["Dasher", "Dancer", "Prancer", "Vixen",
"Comet", "Cupid", "Donner", "Blitzen", "Rudolph"])
}
record(longin, "li1") {
field(INP, 1)
@@ -104,4 +110,3 @@ record(waveform, "i4") {
field(FTVL, "INT64")
field(INP, [1234567890123456789,])
}

View File

@@ -0,0 +1,270 @@
/*************************************************************************\
* Copyright (c) 2020 Joao Paulo Martins
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include "dbUnitTest.h"
#include "testMain.h"
#include "dbLock.h"
#include "errlog.h"
#include "dbAccess.h"
#include "epicsMath.h"
#include "menuYesNo.h"
#include "longoutRecord.h"
void recTestIoc_registerRecordDeviceDriver(struct dbBase *);
static void test_oopt_everytime(void){
/* reset rec processing counter_a */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
/* write the same value two times */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* write two times with different values*/
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 18);
/* Test if the counter_a was processed 4 times */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 4.0);
// number of tests = 6
}
static void test_oopt_onchange(void){
/* change OOPT to On Change */
testdbPutFieldOk("longout_rec.OOPT", DBF_ENUM, longoutOOPT_On_Change);
/* reset rec processing counter_a */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
/* write the same value two times */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* Test if the counter_a was processed only once */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 1.0);
/* write two times with different values*/
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 18);
/* Test if the counter_a was processed 1 + 2 times */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 3.0);
//number of tests 8
}
static void test_oopt_whenzero(void){
testdbPutFieldOk("longout_rec.OOPT", DBF_ENUM, longoutOOPT_When_Zero);
/* reset rec processing counter_a */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
/* write zero two times */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 0);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 0);
/* Test if the counter_a was processed twice */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 2.0);
/* write two times with non-zero values*/
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 18);
/* Test if the counter_a was still processed 2 times */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 2.0);
//number of tests 8
}
static void test_oopt_whennonzero(void){
testdbPutFieldOk("longout_rec.OOPT", DBF_ENUM, longoutOOPT_When_Non_zero);
/* reset rec processing counter_a */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
/* write zero two times */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 0);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 0);
/* Test if the counter_a was never processed */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 0.0);
/* write two times with non-zero values*/
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 18);
/* Test if the counter_a was still processed 2 times */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 2.0);
//number of tests 8
}
static void test_oopt_when_transition_zero(void){
testdbPutFieldOk("longout_rec.OOPT", DBF_ENUM, longoutOOPT_Transition_To_Zero);
/* reset rec processing counter_a */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
/* write non-zero then zero */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 0);
/* Test if the counter_a was processed */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 1.0);
/* write another transition to zero */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 0);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
/* Test if the counter_a was processed once more */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 2.0);
//number of tests 9
}
static void test_oopt_when_transition_nonzero(void){
testdbPutFieldOk("longout_rec.OOPT", DBF_ENUM, longoutOOPT_Transition_To_Non_zero);
/* write non-zero to start fresh */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* reset rec processing counter_a */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
/* write non-zero then zero */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 0);
/* Test if the counter_a was never processed */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 0.0);
/* write a transition to non-zero */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 18);
/* Test if the counter_a was processed */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 1.0);
//number of tests 8
}
static void test_changing_out_field(void){
/* change OOPT to On Change */
testdbPutFieldOk("longout_rec.OOPT", DBF_ENUM, longoutOOPT_On_Change);
/* write an initial value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* reset rec processing counters */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
testdbPutFieldOk("counter_b.VAL", DBF_DOUBLE, 0.0);
/* write the same value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* Test if the counter was never processed */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 0.0);
/* change the OUT link to another counter */
testdbPutFieldOk("longout_rec.OUT", DBF_STRING, "counter_b.B PP");
/* write the same value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* Test if the counter was processed once */
testdbGetFieldEqual("counter_b", DBF_DOUBLE, 1.0);
/* write the same value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* Test if the counter was not processed again */
testdbGetFieldEqual("counter_b", DBF_DOUBLE, 1.0);
/* Set option to write ON CHANGE even when the OUT link was changed */
testdbPutFieldOk("longout_rec.OOCH", DBF_ENUM, menuYesNoNO);
/* write an initial value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* reset rec processing counters */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
testdbPutFieldOk("counter_b.VAL", DBF_DOUBLE, 0.0);
/* write the same value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* Test if the counter_b was never processed */
testdbGetFieldEqual("counter_b", DBF_DOUBLE, 0.0);
/* change back the OUT link to counter_a */
testdbPutFieldOk("longout_rec.OUT", DBF_STRING, "counter_a.B PP");
/* write the same value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* Test if the counter was never processed */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 0.0);
/* write the same value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 16);
/* Test if the counter was not processed again */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 0.0);
/* write new value */
testdbPutFieldOk("longout_rec.VAL", DBF_LONG, 17);
/* Test if the counter was processed once */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 1.0);
/* reset rec processing counters */
testdbPutFieldOk("counter_a.VAL", DBF_DOUBLE, 0.0);
/* test if record with OOPT == On Change will
write to output at its first process */
testdbPutFieldOk("longout_rec2.VAL", DBF_LONG, 16);
/* Test if the counter was processed once */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 1.0);
/* write the same value */
testdbPutFieldOk("longout_rec2.VAL", DBF_LONG, 16);
/* Test if the counter was not processed again */
testdbGetFieldEqual("counter_a", DBF_DOUBLE, 1.0);
//number of tests 29
}
MAIN(longoutTest) {
testPlan(6+8+8+8+9+8+29);
testdbPrepare();
testdbReadDatabase("recTestIoc.dbd", NULL, NULL);
recTestIoc_registerRecordDeviceDriver(pdbbase);
testdbReadDatabase("longoutTest.db", NULL, NULL);
eltc(0);
testIocInitOk();
eltc(1);
test_oopt_everytime();
test_oopt_onchange();
test_oopt_whenzero();
test_oopt_whennonzero();
test_oopt_when_transition_zero();
test_oopt_when_transition_nonzero();
test_changing_out_field();
testIocShutdownOk();
testdbCleanup();
return testDone();
}

View File

@@ -0,0 +1,25 @@
record(calc, "counter_a") {
field(INPA, "counter_a")
field(CALC, "A+1")
field(SCAN, "Passive")
}
record(calc, "counter_b") {
field(INPA, "counter_b")
field(CALC, "A+1")
field(SCAN, "Passive")
}
record(longout, "longout_rec") {
field(VAL, "0")
field(OUT, "counter_a.B PP")
field(PINI, "YES")
}
record(longout, "longout_rec2") {
field(VAL, "16")
field(OUT, "counter_a.B PP")
field(PINI, "NO")
field(OOPT, "On Change")
}

View File

@@ -33,15 +33,16 @@
#include "epicsExport.h"
static
void testmbbioFields(const char* rec, unsigned int value)
void testmbbioFields(char dir, unsigned n, unsigned int value)
{
char field[40];
unsigned int i;
testdbGetFieldEqual(rec, DBF_ULONG, value);
sprintf(field,"d%c%d", dir, n);
testdbGetFieldEqual(field, DBF_ULONG, value);
for (i=0; i < 32; i++)
{
sprintf(field,"%s.B%X", rec, i);
sprintf(field,"d%c%d.B%X", dir, n, i);
testdbGetFieldEqual(field, DBF_ULONG, (value>>i)&1);
}
}
@@ -49,16 +50,14 @@ void testmbbioFields(const char* rec, unsigned int value)
static
void testmbbioRecords(unsigned int count, unsigned int value)
{
char rec[40];
unsigned int i;
for (i = 1; i <= count; i++)
{
sprintf(rec, "do%d", i);
testDiag(" ### %s ###", rec);
testmbbioFields(rec, value);
sprintf(rec, "di%d", i);
testmbbioFields(rec, value);
testDiag(" ### do%d ###", i);
testmbbioFields('o', i, value);
testDiag(" ### di%d ###", i);
testmbbioFields('i', i, value);
}
}

View File

@@ -0,0 +1,18 @@
record(ai, "ai") {}
record(stringin, "si1") {
field(INP, "ai.SEVR")
field(FLNK, "li1")
}
record(longin, "li1") {
field(INP, "ai.SEVR")
field(FLNK, "si2")
}
record(stringin, "si2") {
field(INP, "ai.SEVR CA")
field(FLNK, "li2")
}
record(longin, "li2") {
field(INP, "ai.SEVR CA")
}

View File

@@ -0,0 +1,5 @@
record(calc, "test_calc")
{
field(SCAN, "1 second")
field(CALC, "RNDM*100")
}

View File

@@ -5,6 +5,8 @@
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#define EPICS_DBCA_PRIVATE_API
#include <dbUnitTest.h>
#include <testMain.h>
#include <dbAccess.h>
@@ -23,6 +25,8 @@ void regressTest_registerRecordDeviceDriver(struct dbBase *);
static
void startRegressTestIoc(const char *dbfile)
{
testDiag("Testing with %s", dbfile);
testdbPrepare();
testdbReadDatabase("regressTest.dbd", NULL, NULL);
regressTest_registerRecordDeviceDriver(pdbbase);
@@ -72,6 +76,8 @@ void testArrayLength1(void)
/*
* https://bugs.launchpad.net/epics-base/+bug/1699445 and 1887981
*
* also https://github.com/epics-base/epics-base/issues/284
*/
static
void testHexConstantLinks(void)
@@ -90,6 +96,22 @@ void testHexConstantLinks(void)
testdbGetFieldEqual("as1.G", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.H", DBR_LONG, 0x10);
testdbPutFieldOk("ai1.PROC", DBR_LONG, 1);
testdbPutFieldOk("li1.PROC", DBR_LONG, 1);
testdbPutFieldOk("as1.PROC", DBR_LONG, 1);
testdbGetFieldEqual("ai1", DBR_LONG, 0x10);
testdbGetFieldEqual("li1", DBR_LONG, 0x10);
testdbGetFieldEqual("mi1", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.A", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.B", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.C", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.D", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.E", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.F", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.G", DBR_LONG, 0x10);
testdbGetFieldEqual("as1.H", DBR_LONG, 0x10);
testIocShutdownOk();
testdbCleanup();
}
@@ -183,14 +205,80 @@ testSpecialLinks(void)
testdbCleanup();
}
/* https://github.com/epics-base/epics-base/issues/194 */
static
void testLongCalc(void)
{
const char small[] = "0.0000000000000000000000000000000000000001";
startRegressTestIoc("regressLongCalc.db");
testdbGetFieldEqual("test_calc.CALC", DBF_STRING, "RNDM*100");
testdbPutArrFieldOk("test_calc.CALC$", DBF_CHAR, 4, "300\0");
testdbGetFieldEqual("test_calc.CALC", DBF_STRING, "300");
testdbPutFieldOk("test_calc.PROC", DBF_LONG, 1);
testdbGetFieldEqual("test_calc", DBF_DOUBLE, 300.0);
testdbPutArrFieldOk("test_calc.CALC$", DBF_CHAR, sizeof(small), small);
testdbGetFieldEqual("test_calc.CALC", DBF_STRING, "0.0000000000000000000000000000000000000");
testdbPutFieldOk("test_calc.PROC", DBF_LONG, 1);
testdbGetFieldEqual("test_calc", DBF_DOUBLE, 1e-40);
testIocShutdownOk();
testdbCleanup();
}
/* https://github.com/epics-base/epics-base/issues/183 */
static
void testLinkSevr(void)
{
dbChannel *chan;
startRegressTestIoc("regressLinkSevr.db");
/* wait for CA links to connect and receive an initial update */
testdbCaWaitForUpdateCount(dbGetDevLink(testdbRecordPtr("si2")), 1);
testdbCaWaitForUpdateCount(dbGetDevLink(testdbRecordPtr("li2")), 1);
chan = dbChannelCreate("ai.SEVR");
if(!chan)
testAbort("Can't create channel for ai.SEVR");
testOk1(!dbChannelOpen(chan));
#define testType(FN, TYPE) testOk(FN(chan)==TYPE, #FN "() -> (%d) == " #TYPE " (%d)", FN(chan), TYPE)
testType(dbChannelExportType, DBF_ENUM);
testType(dbChannelFieldType, DBF_MENU);
testType(dbChannelFinalFieldType, DBF_ENUM);
#undef testType
dbChannelDelete(chan);
testdbGetFieldEqual("ai.SEVR", DBF_LONG, INVALID_ALARM);
testdbGetFieldEqual("ai.SEVR", DBF_STRING, "INVALID");
testdbPutFieldOk("si1.PROC", DBF_LONG, 1);
testdbGetFieldEqual("si1", DBF_STRING, "INVALID");
testdbGetFieldEqual("li1", DBF_LONG, INVALID_ALARM);
testTodoBegin("Not working");
testdbGetFieldEqual("si2", DBF_STRING, "INVALID");
testTodoEnd();
testdbGetFieldEqual("li2", DBF_LONG, INVALID_ALARM);
testIocShutdownOk();
testdbCleanup();
}
MAIN(regressTest)
{
testPlan(62);
testPlan(96);
testArrayLength1();
testHexConstantLinks();
testLinkMS();
testCADisconn();
testSpecialLinks();
testLongCalc();
testLinkSevr();
return testDone();
}

View File

@@ -65,6 +65,10 @@ static char *rawSupp[] = {
"bi",
"mbbi",
"mbbiDirect",
"ao",
"bo",
"mbbo",
"mbboDirect"
};
static
@@ -78,7 +82,10 @@ int hasRawSimmSupport(const char *rectype) {
#define PVNAMELENGTH 60
static char nameVAL[PVNAMELENGTH];
static char nameB0[PVNAMELENGTH];
static char nameONVL[PVNAMELENGTH];
static char nameRVAL[PVNAMELENGTH];
static char nameROFF[PVNAMELENGTH];
static char nameSHFT[PVNAMELENGTH];
static char nameSGNL[PVNAMELENGTH];
static char nameSIMM[PVNAMELENGTH];
static char nameSIML[PVNAMELENGTH];
@@ -100,7 +107,8 @@ static char nameSimvalLEN[PVNAMELENGTH];
static
void setNames(const char *name)
{
SETNAME(VAL); SETNAME(B0); SETNAME(RVAL); SETNAME(SGNL);
SETNAME(VAL); SETNAME(B0); SETNAME(ONVL);
SETNAME(RVAL); SETNAME(ROFF); SETNAME(SHFT); SETNAME(SGNL);
SETNAME(SVAL); SETNAME(SIMM); SETNAME(SIML); SETNAME(SIOL); SETNAME(SIMS);
SETNAME(SCAN); SETNAME(PROC); SETNAME(PACT);
SETNAME(STAT); SETNAME(SEVR); SETNAME(TSE);
@@ -401,6 +409,37 @@ void testSiolWrite(const char *name,
testdbPutFieldOk(nameVAL, DBR_LONG, 1);
testdbGetFieldEqual(nameSimval, DBR_USHORT, 1);
if (hasRawSimmSupport(name)) {
testDiag("in simmRAW, RVAL should be written to SIOL");
testDiag("SIML overrides SIMM, disable it here");
testdbPutFieldOk(nameSIML, DBR_STRING, "");
testdbPutFieldOk(nameSIMM, DBR_STRING, "RAW");
if (strcmp(name, "ao") == 0) {
testdbPutFieldOk(nameROFF, DBR_ULONG, 2);
testdbPutFieldOk(nameVAL, DBR_DOUBLE, 5.);
testdbGetFieldEqual(nameRVAL, DBR_LONG, 3);
testdbGetFieldEqual(nameSimval, DBR_DOUBLE, 3.);
} else if (strcmp(name, "bo") == 0) {
boRecord *prec;
prec = (boRecord *) testdbRecordPtr("bo");
prec->mask = 0x55;
testdbPutFieldOk(nameVAL, DBR_USHORT, 1);
testdbGetFieldEqual(nameRVAL, DBR_ULONG, 0x55);
testdbGetFieldEqual(nameSimval, DBR_ULONG, 0x55);
} else if (strcmp(name, "mbbo") == 0) {
testdbPutFieldOk(nameONVL, DBR_ULONG, 5);
testdbPutFieldOk(nameVAL, DBR_UCHAR, 1);
testdbGetFieldEqual(nameRVAL, DBR_ULONG, 5);
testdbGetFieldEqual(nameSimval, DBR_UCHAR, 5);
} else if (strcmp(name, "mbboDirect") == 0) {
testdbPutFieldOk(nameSHFT, DBR_ULONG, 2);
testdbPutFieldOk(nameB0, DBR_UCHAR, 1);
testdbGetFieldEqual(nameRVAL, DBR_ULONG, 4);
testdbGetFieldEqual(nameSimval, DBR_UCHAR, 4);
}
testdbPutFieldOk(nameSIML, DBR_STRING, nameSimmode);
}
/* Set TSE to -2 (from device) and reprocess: timestamp is taken from IOC */
epicsTimeGetCurrent(&now);
testdbPutFieldOk(nameTSE, DBR_SHORT, -2);
@@ -518,7 +557,7 @@ void testAllRecTypes(void)
MAIN(simmTest)
{
testPlan(1176);
testPlan(1267);
startSimmTestIoc("simmTest.db");
testSimmSetup();

View File

@@ -8,8 +8,11 @@
#include <string.h>
#define EPICS_DBCA_PRIVATE_API
#include "dbAccess.h"
#include "dbStaticLib.h"
#include "dbCa.h"
#include "dbTest.h"
#include "dbUnitTest.h"
#include "epicsThread.h"
@@ -60,14 +63,17 @@ void testGroup0(void)
testDiag("============ Starting %s ============", EPICS_FUNCTION);
testdbPutFieldOk("source", DBR_LONG, 1);
/* The above put sends CA monitors to all of the CA links, but
* doesn't trigger record processing (the links are not CP/CPP).
* How could we wait until all of those monitors have arrived,
* instead of just waiting for an arbitrary time period?
*/
epicsThreadSleep(1.0); /* FIXME: Wait here? */
for (rec = records; *rec; rec++) {
DBLINK* plink = dbGetDevLink(testdbRecordPtr(*rec));
if(plink->type==CA_LINK)
testdbCaWaitForUpdateCount(plink, 1);
}
testdbPutFieldOk("source", DBR_LONG, 1);
for (rec = records; *rec; rec++) {
DBLINK* plink = dbGetDevLink(testdbRecordPtr(*rec));
if(plink->type==CA_LINK)
testdbCaWaitForUpdateCount(plink, 2);
if (strncmp(*rec, "lsi0", 4) != 0)
testdbGetFieldEqual(*rec, DBR_LONG, 0);
checkDtyp(*rec);
@@ -76,8 +82,10 @@ void testGroup0(void)
}
testdbPutFieldOk("source", DBR_LONG, 0);
epicsThreadSleep(1.0); /* FIXME: Wait here as above */
for (rec = records; *rec; rec++) {
DBLINK* plink = dbGetDevLink(testdbRecordPtr(*rec));
if(plink->type==CA_LINK)
testdbCaWaitForUpdateCount(plink, 3);
doProcess(*rec);
testdbGetFieldEqual(*rec, DBR_LONG, 0);
}