Add dummy putValue methods to const link types

Includes a new softTest program to detect regressions.
Resolves http://www.aps.anl.gov/epics/core-talk/2017/msg00503.php
This commit is contained in:
Andrew Johnson
2017-09-07 13:48:39 -05:00
parent 736b81e044
commit 1fe3e9e772
5 changed files with 417 additions and 2 deletions

View File

@@ -211,6 +211,12 @@ static long dbConstGetValue(struct link *plink, short dbrType, void *pbuffer,
return 0;
}
static long dbConstPutValue(struct link *plink, short dbrType,
const void *pbuffer, long nRequest)
{
return 0;
}
static lset dbConst_lset = {
1, 0, /* Constant, not Volatile */
NULL, NULL,
@@ -223,6 +229,6 @@ static lset dbConst_lset = {
NULL, NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
dbConstPutValue, NULL,
NULL, NULL
};

View File

@@ -558,6 +558,12 @@ static long lnkConst_getValue(struct link *plink, short dbrType, void *pbuffer,
return 0;
}
static long lnkConst_putValue(struct link *plink, short dbrType,
const void *pbuffer, long nRequest)
{
return 0;
}
/************************* Interface Tables *************************/
@@ -569,7 +575,7 @@ static lset lnkConst_lset = {
NULL, NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
lnkConst_putValue, NULL,
NULL, NULL
};

View File

@@ -67,6 +67,13 @@ testHarness_SRCS += asyncSoftTest.c
TESTFILES += ../asyncSoftTest.db
TESTS += asyncSoftTest
TESTPROD_HOST += softTest
softTest_SRCS += softTest.c
softTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp
testHarness_SRCS += softTest.c
TESTFILES += ../softTest.db
TESTS += softTest
TARGETS += $(COMMON_DIR)/asTestIoc.dbd
DBDDEPENDS_FILES += asTestIoc.dbd$(DEP)
asTestIoc_DBD += base.dbd

169
src/std/rec/test/softTest.c Normal file
View File

@@ -0,0 +1,169 @@
/*************************************************************************\
* 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 "errlog.h"
#include "registryFunction.h"
#include "subRecord.h"
#include "testMain.h"
static
void checkDtyp(const char *rec)
{
char dtyp[16];
strcpy(dtyp, rec);
strcat(dtyp, ".DTYP");
testdbGetFieldEqual(dtyp, DBF_LONG, 0); /* Soft Channel = 0 */
}
static
void checkInput(const char *rec, int value)
{
char proc[16];
testDiag("Checking record '%s'", rec);
strcpy(proc, rec);
strcat(proc, ".PROC");
testdbPutFieldOk(proc, DBF_CHAR, 1);
testdbGetFieldEqual(rec, DBF_LONG, value);
}
static
void testGroup0(void)
{
const char ** rec;
const char * records[] = {
"ai0", "bi0", "di0", "ii0", "li0", "lsi0", "mi0", "si0", NULL
};
testDiag("============ Starting %s ============", EPICS_FUNCTION);
testdbPutFieldOk("source", DBF_LONG, 1);
for (rec = records; *rec; rec++) {
checkInput(*rec, 1);
checkDtyp(*rec);
}
testdbPutFieldOk("source", DBF_LONG, 0);
for (rec = records; *rec; rec++) {
checkInput(*rec, 0);
}
}
static
void testGroup1(void)
{
const char ** rec;
const char * records[] = {
"bi1",
"ai1", "di1", "ii1", "li1", "lsi1", "mi1", "si1", NULL
};
int init = 1; /* bi1 initializes to 1 */
testDiag("============ Starting %s ============", EPICS_FUNCTION);
for (rec = records; *rec; rec++) {
checkInput(*rec, init);
init = 9; /* remainder initialize to 9 */
}
}
int dest;
static
long destSubr(subRecord *prec)
{
dest = prec->val;
return 0;
}
static
void checkOutput(const char *rec, int value)
{
testDiag("Checking record '%s'", rec);
testdbPutFieldOk(rec, DBF_LONG, value);
testOk(dest == value, "value %d output -> %d", value, dest);
}
static
void testGroup2(void)
{
const char ** rec;
const char * records[] = {
"ao0", "bo0", "io0", "lo0", "lso0", "mo0", "so0", NULL,
};
testDiag("============ Starting %s ============", EPICS_FUNCTION);
for (rec = records; *rec; rec++) {
checkOutput(*rec, 1);
checkDtyp(*rec);
}
checkOutput("do0.B0", 1);
checkDtyp("do0");
for (rec = records; *rec; rec++) {
checkOutput(*rec, 0);
}
checkOutput("do0.B0", 0);
}
static
void testGroup3(void)
{
const char ** rec;
const char * records[] = {
"ao1", "bo1", "do1.B0", "io1", "lo1", "lso1", "mo1", "so1", NULL,
};
testDiag("============ Starting %s ============", EPICS_FUNCTION);
for (rec = records; *rec; rec++) {
checkOutput(*rec, 0);
}
}
void recTestIoc_registerRecordDeviceDriver(struct dbBase *);
MAIN(softTest)
{
testPlan(114);
testdbPrepare();
testdbReadDatabase("recTestIoc.dbd", NULL, NULL);
recTestIoc_registerRecordDeviceDriver(pdbbase);
registryFunctionAdd("destSubr", (REGISTRYFUNCTION) destSubr);
testdbReadDatabase("softTest.db", NULL, NULL);
eltc(0);
testIocInitOk();
eltc(1);
testGroup0();
testGroup1();
testGroup2();
testGroup3();
testIocShutdownOk();
testdbCleanup();
return testDone();
}

View File

@@ -0,0 +1,227 @@
# Group 0 are input records with INP being a DB link to 'source'.
# Processing them reads that value.
record(longin, "source") {}
record(ai, "ai0") {
field(DTYP, "Soft Channel")
field(INP, "source")
}
record(bi, "bi0") {
field(DTYP, "Soft Channel")
field(INP, "source")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64in, "ii0") {
field(DTYP, "Soft Channel")
field(INP, "source")
}
record(longin, "li0") {
field(DTYP, "Soft Channel")
field(INP, "source")
}
record(mbbiDirect, "di0") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(INP, "source")
}
record(mbbi, "mi0") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(INP, "source")
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(lsi, "lsi0") {
field(DTYP, "Soft Channel")
field(SIZV, 40)
field(INP, "source")
}
record(stringin, "si0") {
field(DTYP, "Soft Channel")
field(INP, "source")
}
# Group 1 are input records with INP being a non-zero constant.
# Processing them succeeds but does not change VAL.
record(ai, "ai1") {
field(DTYP, "Soft Channel")
field(INP, {const:9})
}
record(bi, "bi1") {
field(DTYP, "Soft Channel")
field(INP, {const:1})
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64in, "ii1") {
field(DTYP, "Soft Channel")
field(INP, {const:9})
}
record(longin, "li1") {
field(DTYP, "Soft Channel")
field(INP, {const:9})
}
record(mbbiDirect, "di1") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(INP, {const:9})
}
record(mbbi, "mi1") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(INP, {const:9})
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(lsi, "lsi1") {
field(DTYP, "Soft Channel")
field(SIZV, 40)
field(INP, {const:"9"})
}
record(stringin, "si1") {
field(DTYP, "Soft Channel")
field(INP, {const:"9"})
}
# Group 2 are output records with OUT being a DB link to 'dest' with PP.
# Putting a value to them writes that value to 'dest'.
record(sub, "dest") {
field(SNAM, "destSubr")
}
record(ao, "ao0") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
record(bo, "bo0") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64out, "io0") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
record(longout, "lo0") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
record(mbboDirect, "do0") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(OUT, "dest PP")
}
record(mbbo, "mo0") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
field(OUT, "dest PP")
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, "lso0") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
field(SIZV, 40)
}
record(stringout, "so0") {
field(DTYP, "Soft Channel")
field(OUT, "dest PP")
}
# Group 3 are output records with OUT being empty (a constant link).
# Putting a value to them must succeed.
record(ao, "ao1") {
field(DTYP, "Soft Channel")
}
record(bo, "bo1") {
field(DTYP, "Soft Channel")
field(ZNAM, "Zero")
field(ONAM, "One")
}
record(int64out, "io1") {
field(DTYP, "Soft Channel")
}
record(longout, "lo1") {
field(DTYP, "Soft Channel")
}
record(mbboDirect, "do1") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
}
record(mbbo, "mo1") {
field(DTYP, "Soft Channel")
field(NOBT, 4)
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, "Soft Channel")
field(SIZV, 40)
}
record(stringout, "so1") {
field(DTYP, "Soft Channel")
}