asTest: fix link with mingw

This test has device support, which the registerRDD script
always emits as dllimport, so it fails to link if the dsets
are part of the executable itself.

Use iocsh to avoid calling the RDD function directly since
a DLL can't link against functions in the main executable.
This commit is contained in:
Michael Davidsaver
2015-09-07 15:06:02 -04:00
parent 8aea808b1d
commit 655735fa13
3 changed files with 242 additions and 195 deletions

View File

@@ -10,7 +10,12 @@ TOP=../../../..
include $(TOP)/configure/CONFIG
PROD_LIBS = dbRecStd dbCore ca Com
TESTLIBRARY = dbRecStdTest
dbRecStdTest_SRCS += asTestLib.c
dbRecStdTest_LIBS += dbRecStd dbCore ca Com
PROD_LIBS = dbRecStdTest dbRecStd dbCore ca Com
TARGETS += $(COMMON_DIR)/recTestIoc.dbd
recTestIoc_DBD = base.dbd

View File

@@ -36,205 +36,13 @@
#include "testMain.h"
epicsShareFunc void testRestore(void);
#include "epicsExport.h"
void asTestIoc_registerRecordDeviceDriver(struct dbBase *);
static unsigned iran;
static void hookPass0(initHookState state)
{
DBENTRY entry;
if(state!=initHookAfterInitDevSup)
return;
testDiag("initHookAfterInitDevSup");
dbInitEntry(pdbbase, &entry);
/* rec0.VAL is initially 1, set it to 2 */
if(dbFindRecord(&entry, "rec0.VAL")==0) {
aoRecord *prec = entry.precnode->precord;
testOk(prec->val==1, "VAL %d==1 (initial value from .db)", (int)prec->val);
testOk1(dbPutString(&entry, "2")==0);
testOk(prec->val==2, "VAL %d==2", (int)prec->val);
} else {
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* rec0.OUT is initially "rec0.DISV", set it to "rec0.SEVR" */
if(dbFindRecord(&entry, "rec0.OUT")==0) {
aoRecord *prec = entry.precnode->precord;
if(prec->out.type==CONSTANT)
testOk(strcmp(prec->out.text,"rec0.DISV")==0,
"%s==rec0.DISV (initial value from .db)",
prec->out.text);
else
testFail("Wrong link type: %d", (int)prec->out.type);
testOk1(dbPutString(&entry, "rec0.SEVR")==0);
} else{
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* rec0.SDIS is initially NULL, set it to "rec0.STAT" */
if(dbFindRecord(&entry, "rec0.SDIS")==0) {
aoRecord *prec = entry.precnode->precord;
if(prec->sdis.type==CONSTANT)
testOk1(prec->sdis.value.constantStr==NULL);
else
testFail("Wrong link type: %d", (int)prec->sdis.type);
testOk1(dbPutString(&entry, "rec0.STAT")==0);
} else{
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* can't restore array field in pass0 */
dbFinishEntry(&entry);
}
static long initRec0(aoRecord *prec)
{
DBLINK *plink = &prec->out;
testDiag("init_record(%s)", prec->name);
testOk(prec->val==2, "VAL %d==2 (pass0 value)", (int)prec->val);
prec->val = 3;
testOk(prec->val==3, "VAL %d==3", (int)prec->val);
testOk1(plink->type==DB_LINK);
if(plink->type==DB_LINK)
testOk(strcmp(plink->value.pv_link.pvname,"rec0.SEVR")==0,
"%s==rec0.SEVR (pass0 value)", plink->value.pv_link.pvname);
else
testFail("Wrong link type");
plink = &prec->sdis;
testOk1(plink->type==DB_LINK);
if(plink->type==DB_LINK)
testOk(strcmp(plink->value.pv_link.pvname,"rec0.STAT")==0,
"%s==rec0.STAT (pass0 value)", plink->value.pv_link.pvname);
else
testFail("Wrong link type");
iran |= 1;
return 2; /* we set .VAL, so don't use RVAL */
}
static long initRec1(waveformRecord *prec)
{
testDiag("init_record(%s)", prec->name);
testOk(prec->nord==0, "NORD %d==0", (int)prec->nord);
iran |= 2;
return 0;
}
static double values[] = {1,2,3,4,5};
static void hookPass1(initHookState state)
{
DBENTRY entry;
DBADDR addr;
if(state!=initHookAfterInitDatabase)
return;
testDiag("initHookAfterInitDatabase");
dbInitEntry(pdbbase, &entry);
if(dbFindRecord(&entry, "rec0.VAL")==0) {
aoRecord *prec = entry.precnode->precord;
testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val);
testOk1(dbPutString(&entry, "4")==0);
testOk(prec->val==4, "VAL %d==4", (int)prec->val);
} else{
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* Can't restore links in pass 1 */
if(dbNameToAddr("rec1.VAL", &addr)) {
testFail("missing rec1");
testSkip(3, "missing record");
} else {
struct rset *prset = dbGetRset(&addr);
dbfType ftype = addr.field_type;
long count=-1, offset=-1, maxcount = addr.no_elements;
testOk1(prset && prset->get_array_info && prset->put_array_info);
testOk1((*prset->get_array_info)(&addr, &count, &offset)==0);
/* count is ignored */
testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0);
testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0);
}
dbFinishEntry(&entry);
}
static void testRestore(void)
{
aoRecord *rec0;
waveformRecord *rec1;
testDiag("test Restore");
initHookRegister(hookPass0);
initHookRegister(hookPass1);
testdbPrepare();
testdbReadDatabase("asTestIoc.dbd", NULL, NULL);
asTestIoc_registerRecordDeviceDriver(pdbbase);
testdbReadDatabase("asTest.db", NULL, NULL);
rec0 = (aoRecord*)testdbRecordPtr("rec0");
rec1 = (waveformRecord*)testdbRecordPtr("rec1");
eltc(0);
testIocInitOk();
eltc(1);
testDiag("Post initialization");
testOk1(iran==3);
testOk1(rec0->val==4);
testOk1(rec1->nord==5);
{
double *buf = rec1->bptr;
testOk(buf[0]==1, "buf[0] %f==1", buf[0]);
testOk1(buf[1]==2);
testOk1(buf[2]==3);
testOk1(buf[3]==4);
testOk1(buf[4]==5);
}
testIocShutdownOk();
testdbCleanup();
}
MAIN(asTest)
{
testPlan(29);
testRestore();
return testDone();
}
struct dset6 {
dset common;
DEVSUPFUN proc;
DEVSUPFUN linconv;
};
static long noop() {return 0;}
static struct dset6 devAOasTest = { {6, NULL, NULL, (DEVSUPFUN)initRec0, NULL}, (DEVSUPFUN)noop, NULL};
static struct dset6 devWFasTest = { {6, NULL, NULL, (DEVSUPFUN)initRec1, NULL}, (DEVSUPFUN)noop, NULL};
epicsExportAddress(dset, devAOasTest);
epicsExportAddress(dset, devWFasTest);

View File

@@ -0,0 +1,234 @@
/*************************************************************************\
* Copyright (c) 2015 Brookhaven Science Assoc. as operator of Brookhaven
* National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author: Michael Davidsaver <mdavidsaver@bnl.gov>
*
* Test the hooks that autosave uses during initialization
*/
#include "string.h"
#include "epicsString.h"
#include "dbUnitTest.h"
#include "epicsThread.h"
#include "iocInit.h"
#include "dbBase.h"
#include "link.h"
#include "recSup.h"
#include "iocsh.h"
#include "dbAccess.h"
#include "dbConvert.h"
#include "dbStaticLib.h"
#include "registry.h"
#include "dbStaticLib.h"
#include "dbStaticPvt.h"
#include "osiFileName.h"
#include "initHooks.h"
#include "devSup.h"
#include "errlog.h"
#include "aoRecord.h"
#include "waveformRecord.h"
#include "epicsExport.h"
static unsigned iran;
static void hookPass0(initHookState state)
{
DBENTRY entry;
if(state!=initHookAfterInitDevSup)
return;
testDiag("initHookAfterInitDevSup");
dbInitEntry(pdbbase, &entry);
/* rec0.VAL is initially 1, set it to 2 */
if(dbFindRecord(&entry, "rec0.VAL")==0) {
aoRecord *prec = entry.precnode->precord;
testOk(prec->val==1, "VAL %d==1 (initial value from .db)", (int)prec->val);
testOk1(dbPutString(&entry, "2")==0);
testOk(prec->val==2, "VAL %d==2", (int)prec->val);
} else {
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* rec0.OUT is initially "rec0.DISV", set it to "rec0.SEVR" */
if(dbFindRecord(&entry, "rec0.OUT")==0) {
aoRecord *prec = entry.precnode->precord;
if(prec->out.type==CONSTANT)
testOk(strcmp(prec->out.text,"rec0.DISV")==0,
"%s==rec0.DISV (initial value from .db)",
prec->out.text);
else
testFail("Wrong link type: %d", (int)prec->out.type);
testOk1(dbPutString(&entry, "rec0.SEVR")==0);
} else{
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* rec0.SDIS is initially NULL, set it to "rec0.STAT" */
if(dbFindRecord(&entry, "rec0.SDIS")==0) {
aoRecord *prec = entry.precnode->precord;
if(prec->sdis.type==CONSTANT)
testOk1(prec->sdis.value.constantStr==NULL);
else
testFail("Wrong link type: %d", (int)prec->sdis.type);
testOk1(dbPutString(&entry, "rec0.STAT")==0);
} else{
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* can't restore array field in pass0 */
dbFinishEntry(&entry);
}
static long initRec0(aoRecord *prec)
{
DBLINK *plink = &prec->out;
testDiag("init_record(%s)", prec->name);
testOk(prec->val==2, "VAL %d==2 (pass0 value)", (int)prec->val);
prec->val = 3;
testOk(prec->val==3, "VAL %d==3", (int)prec->val);
testOk1(plink->type==DB_LINK);
if(plink->type==DB_LINK)
testOk(strcmp(plink->value.pv_link.pvname,"rec0.SEVR")==0,
"%s==rec0.SEVR (pass0 value)", plink->value.pv_link.pvname);
else
testFail("Wrong link type");
plink = &prec->sdis;
testOk1(plink->type==DB_LINK);
if(plink->type==DB_LINK)
testOk(strcmp(plink->value.pv_link.pvname,"rec0.STAT")==0,
"%s==rec0.STAT (pass0 value)", plink->value.pv_link.pvname);
else
testFail("Wrong link type");
iran |= 1;
return 2; /* we set .VAL, so don't use RVAL */
}
static long initRec1(waveformRecord *prec)
{
testDiag("init_record(%s)", prec->name);
testOk(prec->nord==0, "NORD %d==0", (int)prec->nord);
iran |= 2;
return 0;
}
static double values[] = {1,2,3,4,5};
static void hookPass1(initHookState state)
{
DBENTRY entry;
DBADDR addr;
if(state!=initHookAfterInitDatabase)
return;
testDiag("initHookAfterInitDatabase");
dbInitEntry(pdbbase, &entry);
if(dbFindRecord(&entry, "rec0.VAL")==0) {
aoRecord *prec = entry.precnode->precord;
testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val);
testOk1(dbPutString(&entry, "4")==0);
testOk(prec->val==4, "VAL %d==4", (int)prec->val);
} else{
testFail("Missing rec0");
testSkip(1, "missing record");
}
/* Can't restore links in pass 1 */
if(dbNameToAddr("rec1.VAL", &addr)) {
testFail("missing rec1");
testSkip(3, "missing record");
} else {
struct rset *prset = dbGetRset(&addr);
dbfType ftype = addr.field_type;
long count=-1, offset=-1, maxcount = addr.no_elements;
testOk1(prset && prset->get_array_info && prset->put_array_info);
testOk1((*prset->get_array_info)(&addr, &count, &offset)==0);
/* count is ignored */
testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0);
testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0);
}
dbFinishEntry(&entry);
}
epicsShareFunc
void testRestore(void)
{
aoRecord *rec0;
waveformRecord *rec1;
testDiag("test Restore");
initHookRegister(hookPass0);
initHookRegister(hookPass1);
testdbPrepare();
testdbReadDatabase("asTestIoc.dbd", NULL, NULL);
iocshCmd("asTestIoc_registerRecordDeviceDriver(pdbbase)");
testdbReadDatabase("asTest.db", NULL, NULL);
rec0 = (aoRecord*)testdbRecordPtr("rec0");
rec1 = (waveformRecord*)testdbRecordPtr("rec1");
eltc(0);
testIocInitOk();
eltc(1);
testDiag("Post initialization");
testOk1(iran==3);
testOk1(rec0->val==4);
testOk1(rec1->nord==5);
{
double *buf = rec1->bptr;
testOk(buf[0]==1, "buf[0] %f==1", buf[0]);
testOk1(buf[1]==2);
testOk1(buf[2]==3);
testOk1(buf[3]==4);
testOk1(buf[4]==5);
}
testIocShutdownOk();
testdbCleanup();
/* recSup doesn't cleanup after itself */
free(bptr);
}
struct dset6 {
dset common;
DEVSUPFUN proc;
DEVSUPFUN linconv;
};
static long noop() {return 0;}
static struct dset6 devAOasTest = { {6, NULL, NULL, (DEVSUPFUN)initRec0, NULL}, (DEVSUPFUN)noop, NULL};
static struct dset6 devWFasTest = { {6, NULL, NULL, (DEVSUPFUN)initRec1, NULL}, (DEVSUPFUN)noop, NULL};
epicsExportAddress(dset, devAOasTest);
epicsExportAddress(dset, devWFasTest);