Merge branch '7.0' into PSI-7.0
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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}}")),
|
||||
|
||||
@@ -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'}}")),
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "testMain.h"
|
||||
|
||||
void linkTest_registerRecordDeviceDriver(struct dbBase *);
|
||||
int linkTest_registerRecordDeviceDriver(struct dbBase *);
|
||||
|
||||
static void startTestIoc(const char *dbfile)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,])
|
||||
}
|
||||
|
||||
|
||||
270
modules/database/test/std/rec/longoutTest.c
Normal file
270
modules/database/test/std/rec/longoutTest.c
Normal 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();
|
||||
}
|
||||
25
modules/database/test/std/rec/longoutTest.db
Normal file
25
modules/database/test/std/rec/longoutTest.db
Normal 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")
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
18
modules/database/test/std/rec/regressLinkSevr.db
Normal file
18
modules/database/test/std/rec/regressLinkSevr.db
Normal 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")
|
||||
}
|
||||
5
modules/database/test/std/rec/regressLongCalc.db
Normal file
5
modules/database/test/std/rec/regressLongCalc.db
Normal file
@@ -0,0 +1,5 @@
|
||||
record(calc, "test_calc")
|
||||
{
|
||||
field(SCAN, "1 second")
|
||||
field(CALC, "RNDM*100")
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user