From c7bcb09540271cf4ca116f6ef272b7504005e70e Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 25 Feb 2016 17:44:45 -0600 Subject: [PATCH 1/6] Add tests for dbGet() with db_field_log Regression testing for a bug where an array field with a sub-array channel filter can read past the end of the db_field_log array, because in dbGet() the call to prset->get_array_info() occurs even when pfl is supposed to be overriding the record's array. --- src/ioc/db/test/Makefile | 13 ++ src/ioc/db/test/arrRecord.c | 135 ++++++++++++++++++ src/ioc/db/test/arrRecord.dbd | 34 +++++ src/ioc/db/test/dbChArrTest.cpp | 242 ++++++++++++++++++++++++++++++++ src/ioc/db/test/dbChArrTest.db | 15 ++ 5 files changed, 439 insertions(+) create mode 100644 src/ioc/db/test/arrRecord.c create mode 100644 src/ioc/db/test/arrRecord.dbd create mode 100644 src/ioc/db/test/dbChArrTest.cpp create mode 100644 src/ioc/db/test/dbChArrTest.db diff --git a/src/ioc/db/test/Makefile b/src/ioc/db/test/Makefile index c16016378..b844a0bd6 100644 --- a/src/ioc/db/test/Makefile +++ b/src/ioc/db/test/Makefile @@ -12,6 +12,7 @@ include $(TOP)/configure/CONFIG TESTLIBRARY = dbTestIoc +dbTestIoc_SRCS += arrRecord.c dbTestIoc_SRCS += xRecord.c dbTestIoc_SRCS += dbLinkdset.c dbTestIoc_LIBS = dbCore ca Com @@ -20,6 +21,7 @@ TARGETS += $(COMMON_DIR)/dbTestIoc.dbd dbTestIoc_DBD += menuGlobal.dbd dbTestIoc_DBD += menuConvert.dbd dbTestIoc_DBD += menuScan.dbd +#dbTestIoc_DBD += arrRecord.dbd dbTestIoc_DBD += xRecord.dbd dbTestIoc_DBD += dbLinkdset.dbd TESTFILES += $(COMMON_DIR)/dbTestIoc.dbd ../xRecord.db @@ -95,6 +97,16 @@ dbChannelTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp testHarness_SRCS += dbChannelTest.c TESTS += dbChannelTest +TARGETS += $(COMMON_DIR)/dbChArrTest.dbd +dbChArrTest_DBD += arrRecord.dbd +TESTPROD_HOST += dbChArrTest +dbChArrTest_SRCS += dbChArrTest.cpp +dbChArrTest_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp +testHarness_SRCS += dbChArrTest.cpp +testHarness_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp +TESTFILES += $(COMMON_DIR)/dbChArrTest.dbd ../dbChArrTest.db +TESTS += dbChArrTest + TESTPROD_HOST += chfPluginTest chfPluginTest_SRCS += chfPluginTest.c chfPluginTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp @@ -132,6 +144,7 @@ TESTSCRIPTS_HOST += $(TESTS:%=%.t) include $(TOP)/configure/RULES +arrRecord$(DEP): $(COMMON_DIR)/arrRecord.h xRecord$(DEP): $(COMMON_DIR)/xRecord.h dbPutLinkTest$(DEP): $(COMMON_DIR)/xRecord.h scanIoTest$(DEP): $(COMMON_DIR)/yRecord.h diff --git a/src/ioc/db/test/arrRecord.c b/src/ioc/db/test/arrRecord.c new file mode 100644 index 000000000..5e9b2f02c --- /dev/null +++ b/src/ioc/db/test/arrRecord.c @@ -0,0 +1,135 @@ +/*************************************************************************\ +* Copyright (c) 2010 Brookhaven National Laboratory. +* Copyright (c) 2010 Helmholtz-Zentrum Berlin +* fuer Materialien und Energie GmbH. +* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* 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 file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* arrRecord.c - minimal array record for test purposes: no processing */ + +/* + * Author: Ralph Lange + * + * vaguely implemented like parts of recWaveform.c by Bob Dalesio + * + */ + +#include + +#include "dbDefs.h" +#include "epicsPrint.h" +#include "dbAccess.h" +#include "dbEvent.h" +#include "dbFldTypes.h" +#include "recSup.h" +#include "recGbl.h" +#include "cantProceed.h" +#define GEN_SIZE_OFFSET +#include "arrRecord.h" +#undef GEN_SIZE_OFFSET +#include "epicsExport.h" + +/* Create RSET - Record Support Entry Table*/ +#define report NULL +#define initialize NULL +static long init_record(arrRecord *, int); +static long process(arrRecord *); +#define special NULL +#define get_value NULL +static long cvt_dbaddr(DBADDR *); +static long get_array_info(DBADDR *, long *, long *); +static long put_array_info(DBADDR *, long); +#define get_units NULL +#define get_precision NULL +#define get_enum_str NULL +#define get_enum_strs NULL +#define put_enum_str NULL +#define get_graphic_double NULL +#define get_control_double NULL +#define get_alarm_double NULL + +rset arrRSET = { + RSETNUMBER, + report, + initialize, + init_record, + process, + special, + get_value, + cvt_dbaddr, + get_array_info, + put_array_info, + get_units, + get_precision, + get_enum_str, + get_enum_strs, + put_enum_str, + get_graphic_double, + get_control_double, + get_alarm_double +}; +epicsExportAddress(rset, arrRSET); + +static long init_record(arrRecord *prec, int pass) +{ + if (pass == 0) { + if (prec->nelm <= 0) + prec->nelm = 1; + if (prec->ftvl > DBF_ENUM) + prec->ftvl = DBF_UCHAR; + prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), + "arr calloc failed"); + + if (prec->nelm == 1) { + prec->nord = 1; + } else { + prec->nord = 0; + } + return 0; + } + return 0; +} + +static long process(arrRecord *prec) +{ + return 0; +} + +static long cvt_dbaddr(DBADDR *paddr) +{ + arrRecord *prec = (arrRecord *) paddr->precord; + + paddr->pfield = prec->bptr; + paddr->no_elements = prec->nelm; + paddr->field_type = prec->ftvl; + paddr->field_size = dbValueSize(prec->ftvl); + paddr->dbr_field_type = prec->ftvl; + + return 0; +} + +static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) +{ + arrRecord *prec = (arrRecord *) paddr->precord; + + *no_elements = prec->nord; + *offset = prec->off; + + return 0; +} + +static long put_array_info(DBADDR *paddr, long nNew) +{ + arrRecord *prec = (arrRecord *) paddr->precord; + + prec->nord = nNew; + if (prec->nord > prec->nelm) + prec->nord = prec->nelm; + + return 0; +} diff --git a/src/ioc/db/test/arrRecord.dbd b/src/ioc/db/test/arrRecord.dbd new file mode 100644 index 000000000..2b115b500 --- /dev/null +++ b/src/ioc/db/test/arrRecord.dbd @@ -0,0 +1,34 @@ +include "menuGlobal.dbd" +include "menuConvert.dbd" +include "menuScan.dbd" +recordtype(arr) { + include "dbCommon.dbd" + field(VAL, DBF_NOACCESS) { + prompt("Value") + special(SPC_DBADDR) + pp(TRUE) + extra("void *val") + } + field(NELM, DBF_ULONG) { + prompt("Number of Elements") + special(SPC_NOMOD) + initial("1") + } + field(FTVL, DBF_MENU) { + prompt("Field Type of Value") + special(SPC_NOMOD) + menu(menuFtype) + } + field(NORD, DBF_ULONG) { + prompt("Number elements read") + special(SPC_NOMOD) + } + field(OFF, DBF_ULONG) { + prompt("Offset into array") + } + field(BPTR, DBF_NOACCESS) { + prompt("Buffer Pointer") + special(SPC_NOMOD) + extra("void *bptr") + } +} diff --git a/src/ioc/db/test/dbChArrTest.cpp b/src/ioc/db/test/dbChArrTest.cpp new file mode 100644 index 000000000..6116e3db5 --- /dev/null +++ b/src/ioc/db/test/dbChArrTest.cpp @@ -0,0 +1,242 @@ +/*************************************************************************\ +* Copyright (c) 2010 Brookhaven National Laboratory. +* Copyright (c) 2010 Helmholtz-Zentrum Berlin +* fuer Materialien und Energie GmbH. +* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2003 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to the Software License Agreement +* found in the file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* + * Authors: Ralph Lange , + * Andrew Johnson + */ + +#include +#include +#include +#include +#include + +#include "registryFunction.h" +#include "epicsThread.h" +#include "epicsExit.h" +#include "epicsStdio.h" +#include "epicsString.h" +#include "envDefs.h" +#include "dbStaticLib.h" +#include "dbmf.h" +#include "registry.h" +#include "dbAddr.h" +#include "dbAccess.h" +#include "asDbLib.h" +#include "iocInit.h" +#include "iocsh.h" +#include "dbChannel.h" +#include "epicsUnitTest.h" +#include "testMain.h" +#include "osiFileName.h" + +extern "C" { + int dbChArrTest_registerRecordDeviceDriver(struct dbBase *pdbbase); +} + +#define CA_SERVER_PORT "65535" + +const char *server_port = CA_SERVER_PORT; + +static void createAndOpen(const char *name, dbChannel**pch) +{ + testOk(!!(*pch = dbChannelCreate(name)), "dbChannel %s created", name); + testOk(!(dbChannelOpen(*pch)), "dbChannel opened"); + testOk((ellCount(&(*pch)->pre_chain) == 0), "no filters in pre chain"); + testOk((ellCount(&(*pch)->post_chain) == 0), "no filters in post chain"); +} + +static void freeArray(db_field_log *pfl) { + if (pfl->type == dbfl_type_ref) { + free(pfl->u.r.field); + } +} + +static void testHead (const char *title, const char *typ = "") { + const char *line = "------------------------------------------------------------------------------"; + testDiag("%s", line); + testDiag(title, typ); + testDiag("%s", line); +} + +static void check(short dbr_type) { + dbChannel *pch; + db_field_log *pfl; + dbAddr valaddr; + dbAddr offaddr; + const char *offname = NULL, *valname = NULL, *typname = NULL; + epicsInt32 buf[26]; + long off, req; + int i; + + switch (dbr_type) { + case DBR_LONG: + offname = "i32.OFF"; + valname = "i32.VAL"; + typname = "long"; + break; + case DBR_DOUBLE: + offname = "f64.OFF"; + valname = "f64.VAL"; + typname = "double"; + break; + case DBR_STRING: + offname = "c40.OFF"; + valname = "c40.VAL"; + typname = "string"; + break; + default: + testDiag("Invalid data type %d", dbr_type); + } + + (void) dbNameToAddr(offname, &offaddr); + (void) dbNameToAddr(valname, &valaddr); + + testHead("Ten %s elements", typname); + + /* Fill the record's array field with data, 10..19 */ + + epicsInt32 ar[10] = {10,11,12,13,14,15,16,17,18,19}; + (void) dbPutField(&valaddr, DBR_LONG, ar, 10); + + /* Open a channel to it, make sure no filters present */ + + createAndOpen(valname, &pch); + testOk(pch->final_type == valaddr.field_type, + "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); + testOk(pch->final_no_elements == valaddr.no_elements, + "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); + + /* TEST1 sets the record's OFF field, then requests 10 elements from the channel, + * passing in a transparent db_field_log and converting the data to LONG on the way in. + * It checks that it got back the expected data and the right number of elements. + */ + +#define TEST1(Size, Offset, Text, Expected) \ + testDiag("Reading from offset = %d (%s)", Offset, Text); \ + off = Offset; req = 10; \ + memset(buf, sizeof(buf), 0); \ + (void) dbPutField(&offaddr, DBR_LONG, &off, 1); \ + pfl = db_create_read_log(pch); \ + testOk(pfl && pfl->type == dbfl_type_rec, "Valid pfl, type = rec"); \ + testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \ + testOk(req == Size, "Got %ld elements (expected %d)", req, Size); \ + if (!testOk(!memcmp(buf, Expected, sizeof(Expected)), "Data correct")) \ + for (i=0; ifinal_type == valaddr.field_type, + "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); + testOk(pch->final_no_elements == valaddr.no_elements, + "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); + + const epicsInt32 res_5_0[] = {15,16,17,18,19}; + TEST1(5, 0, "no offset", res_5_0); + + const epicsInt32 res_5_3[] = {18,19,15,16,17}; + TEST1(5, 3, "wrapped", res_5_3); + + /* TEST2 sets the record's OFF field, then requests 15 elements from the channel + * but passes in a db_field_log with alternate data, converting that data to LONG. + * It checks that it got back the expected data and the right number of elements. + */ + +#define TEST2(Size, Offset, Text, Expected) \ + testDiag("Reading from offset = %d (%s)", Offset, Text); \ + off = Offset; req = 15; \ + memset(buf, sizeof(buf), 0); \ + (void) dbPutField(&offaddr, DBR_LONG, &off, 1); \ + pfl = db_create_read_log(pch); \ + pfl->type = dbfl_type_ref; \ + pfl->field_type = DBF_CHAR; \ + pfl->field_size = 1; \ + pfl->no_elements = 26; \ + pfl->u.r.dtor = freeArray; \ + pfl->u.r.field = epicsStrDup("abcdefghijklmnopqrsstuvwxyz"); \ + testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \ + testOk(req == Size, "Got %ld elements (expected %d)", req, Size); \ + if (!testOk(!memcmp(buf, Expected, sizeof(Expected)), "Data correct")) \ + for (i=0; i Date: Thu, 25 Feb 2016 17:50:33 -0600 Subject: [PATCH 2/6] Fix the dbGet() array with field-log bug. This also fixes a problem where the array is used in circular buffer mode and the request has an offset, but the array is not actually full at the time; to copy the data out of the array the convert() routine needs to know the capacity of the array to know when to wrap around, but we were passing it the current length instead. --- src/ioc/db/dbAccess.c | 49 +++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c index b7a650282..50fd5a7f3 100644 --- a/src/ioc/db/dbAccess.c +++ b/src/ioc/db/dbAccess.c @@ -812,11 +812,10 @@ long dbGet(DBADDR *paddr, short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { char *pbuf = pbuffer; - void *pfieldsave; + void *pfieldsave = paddr->pfield; db_field_log *pfl = (db_field_log *)pflin; short field_type; - long no_elements; - long offset; + long capacity, no_elements, offset; struct rset *prset; long status = 0; @@ -826,11 +825,20 @@ long dbGet(DBADDR *paddr, short dbrType, return 0; if (!pfl || pfl->type == dbfl_type_rec) { - field_type = paddr->field_type; - no_elements = paddr->no_elements; + field_type = paddr->field_type; + no_elements = capacity = paddr->no_elements; + + /* Update field info from record */ + if (paddr->pfldDes->special == SPC_DBADDR && + (prset = dbGetRset(paddr)) && + prset->get_array_info) { + status = prset->get_array_info(paddr, &no_elements, &offset); + } else + offset = 0; } else { - field_type = pfl->field_type; - no_elements = pfl->no_elements; + field_type = pfl->field_type; + no_elements = capacity = pfl->no_elements; + offset = 0; } if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) @@ -848,23 +856,9 @@ long dbGet(DBADDR *paddr, short dbrType, return S_db_badDbrtype; } - /* For SPC_DBADDR fields, the rset function - * get_array_info() is allowed to modify - * paddr->pfield. So we store the original - * value and restore it later. - */ - pfieldsave = paddr->pfield; - - /* Update field info */ - if (paddr->pfldDes->special == SPC_DBADDR && - (prset = dbGetRset(paddr)) && - prset->get_array_info) { - status = prset->get_array_info(paddr, &no_elements, &offset); - } else - offset = 0; - if (offset == 0 && (!nRequest || no_elements == 1)) { - if (nRequest) *nRequest = 1; + if (nRequest) + *nRequest = 1; if (!pfl || pfl->type == dbfl_type_rec) { status = dbFastGetConvertRoutine[field_type][dbrType] (paddr->pfield, pbuf, paddr); @@ -886,7 +880,8 @@ long dbGet(DBADDR *paddr, short dbrType, long (*convert)(); if (nRequest) { - if (no_elements<(*nRequest)) *nRequest = no_elements; + if (no_elements < *nRequest) + *nRequest = no_elements; n = *nRequest; } else { n = 1; @@ -901,11 +896,11 @@ long dbGet(DBADDR *paddr, short dbrType, status = S_db_badDbrtype; goto done; } - /* convert database field and place it in the buffer */ + /* convert data into the caller's buffer */ if (n <= 0) { ;/*do nothing*/ } else if (!pfl || pfl->type == dbfl_type_rec) { - status = convert(paddr, pbuf, n, no_elements, offset); + status = convert(paddr, pbuf, n, capacity, offset); } else { DBADDR localAddr = *paddr; /* Structure copy */ @@ -916,7 +911,7 @@ long dbGet(DBADDR *paddr, short dbrType, localAddr.pfield = (char *) &pfl->u.v.field; else localAddr.pfield = (char *) pfl->u.r.field; - status = convert(&localAddr, pbuf, n, no_elements, offset); + status = convert(&localAddr, pbuf, n, capacity, offset); } } done: From 4b8c11aeef9be005e74bb7db37b27b073c0b3dea Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 25 Feb 2016 20:08:44 -0500 Subject: [PATCH 3/6] memset transposed arguments --- src/ioc/db/test/dbChArrTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ioc/db/test/dbChArrTest.cpp b/src/ioc/db/test/dbChArrTest.cpp index 6116e3db5..6451fa35a 100644 --- a/src/ioc/db/test/dbChArrTest.cpp +++ b/src/ioc/db/test/dbChArrTest.cpp @@ -125,7 +125,7 @@ static void check(short dbr_type) { #define TEST1(Size, Offset, Text, Expected) \ testDiag("Reading from offset = %d (%s)", Offset, Text); \ off = Offset; req = 10; \ - memset(buf, sizeof(buf), 0); \ + memset(buf, 0, sizeof(buf)); \ (void) dbPutField(&offaddr, DBR_LONG, &off, 1); \ pfl = db_create_read_log(pch); \ testOk(pfl && pfl->type == dbfl_type_rec, "Valid pfl, type = rec"); \ @@ -169,7 +169,7 @@ static void check(short dbr_type) { #define TEST2(Size, Offset, Text, Expected) \ testDiag("Reading from offset = %d (%s)", Offset, Text); \ off = Offset; req = 15; \ - memset(buf, sizeof(buf), 0); \ + memset(buf, 0, sizeof(buf)); \ (void) dbPutField(&offaddr, DBR_LONG, &off, 1); \ pfl = db_create_read_log(pch); \ pfl->type = dbfl_type_ref; \ From 51a69862e721b5a4488d169dac8ad65c82f81a1d Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 25 Feb 2016 20:59:10 -0500 Subject: [PATCH 4/6] ioc/db: single return for dbGet() Single return path after call to prset->get_array_info to ensure that paddr->pfield is restored. --- src/ioc/db/dbAccess.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c index 50fd5a7f3..a45aa9b93 100644 --- a/src/ioc/db/dbAccess.c +++ b/src/ioc/db/dbAccess.c @@ -828,7 +828,9 @@ long dbGet(DBADDR *paddr, short dbrType, field_type = paddr->field_type; no_elements = capacity = paddr->no_elements; - /* Update field info from record */ + /* Update field info from record + * may modify paddr->pfield + */ if (paddr->pfldDes->special == SPC_DBADDR && (prset = dbGetRset(paddr)) && prset->get_array_info) { @@ -841,11 +843,15 @@ long dbGet(DBADDR *paddr, short dbrType, offset = 0; } - if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) - return getLinkValue(paddr, dbrType, pbuf, nRequest); + if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) { + status = getLinkValue(paddr, dbrType, pbuf, nRequest); + goto done; + } - if (paddr->special == SPC_ATTRIBUTE) - return getAttrValue(paddr, dbrType, pbuf, nRequest); + if (paddr->special == SPC_ATTRIBUTE) { + status = getAttrValue(paddr, dbrType, pbuf, nRequest); + goto done; + } /* Check for valid request */ if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) { @@ -853,7 +859,8 @@ long dbGet(DBADDR *paddr, short dbrType, sprintf(message, "dbGet: Request type is %d\n", dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); - return S_db_badDbrtype; + status = S_db_badDbrtype; + goto done; } if (offset == 0 && (!nRequest || no_elements == 1)) { @@ -877,7 +884,7 @@ long dbGet(DBADDR *paddr, short dbrType, } } else { long n; - long (*convert)(); + GETCONVERTFUNC convert; if (nRequest) { if (no_elements < *nRequest) From bfa8e324f73faf13dd15d2e4e2340ebb78a48f6e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 25 Feb 2016 21:10:42 -0500 Subject: [PATCH 5/6] remove dbChArrTest from testHarness dbChArrTest calls iocInit() and so can't be in the shared test harness --- src/ioc/db/test/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ioc/db/test/Makefile b/src/ioc/db/test/Makefile index b844a0bd6..8c7db590f 100644 --- a/src/ioc/db/test/Makefile +++ b/src/ioc/db/test/Makefile @@ -102,8 +102,6 @@ dbChArrTest_DBD += arrRecord.dbd TESTPROD_HOST += dbChArrTest dbChArrTest_SRCS += dbChArrTest.cpp dbChArrTest_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbChArrTest.cpp -testHarness_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp TESTFILES += $(COMMON_DIR)/dbChArrTest.dbd ../dbChArrTest.db TESTS += dbChArrTest From 58285501dea6b90d61a5b39308d8be32a4652c66 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 26 Feb 2016 12:25:59 -0600 Subject: [PATCH 6/6] Revert, test programs may be included in harness without being run --- src/ioc/db/test/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ioc/db/test/Makefile b/src/ioc/db/test/Makefile index 8c7db590f..b844a0bd6 100644 --- a/src/ioc/db/test/Makefile +++ b/src/ioc/db/test/Makefile @@ -102,6 +102,8 @@ dbChArrTest_DBD += arrRecord.dbd TESTPROD_HOST += dbChArrTest dbChArrTest_SRCS += dbChArrTest.cpp dbChArrTest_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp +testHarness_SRCS += dbChArrTest.cpp +testHarness_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp TESTFILES += $(COMMON_DIR)/dbChArrTest.dbd ../dbChArrTest.db TESTS += dbChArrTest