Files
epics-base/modules/database/test/ioc/db/dbStaticTest.c
2018-06-19 11:31:13 +02:00

236 lines
6.5 KiB
C

#include <string.h>
#include <errlog.h>
#include <dbAccess.h>
#include <dbStaticLib.h>
#include <dbStaticPvt.h>
#include <dbUnitTest.h>
#include <testMain.h>
static void testEntry(const char *pv)
{
DBENTRY entry;
testDiag("testEntry(\"%s\")", pv);
dbInitEntry(pdbbase, &entry);
testOk1(dbFindRecord(&entry, pv)==0);
testDiag("precordType=%p precnode=%p", entry.precordType, entry.precnode);
testOk(entry.precordType &&
strcmp(entry.precordType->name, "x")==0,
"Record type is '%s' ('x')", entry.precordType->name);
testOk(entry.precnode &&
strcmp(((dbCommon*)entry.precnode->precord)->name, "testrec")==0,
"Record name is '%s' ('testrec')", ((dbCommon*)entry.precnode->precord)->name);
testOk(entry.pflddes &&
strcmp(entry.pflddes->name, "VAL")==0,
"Field name is '%s' ('VAL')", entry.pflddes->name);
/* all tested PVs are either a record with aliases, or an alias */
testOk(entry.precnode &&
(!(entry.precnode->flags & DBRN_FLAGS_ISALIAS) ^
!(entry.precnode->flags & DBRN_FLAGS_HASALIAS)),
"Recnode flags %d", entry.precnode->flags);
testOk1(dbFollowAlias(&entry)==0);
testOk(dbFindInfo(&entry, "A")==0 &&
strcmp(dbGetInfoString(&entry), "B")==0,
"Info item is set");
dbFinishEntry(&entry);
}
static void testAddr2Entry(const char *pv)
{
DBENTRY entry, entry2;
dbAddr addr;
testDiag("testAddr2Entry(\"%s\")", pv);
memset(&entry, 0, sizeof(entry));
memset(&entry2, 0, sizeof(entry2));
dbInitEntry(pdbbase, &entry);
if(dbFindRecord(&entry, pv)!=0)
testAbort("no entry for %s", pv);
if(dbFollowAlias(&entry))
testAbort("Can't follow alias");
if(dbNameToAddr(pv, &addr))
testAbort("no addr for %s", pv);
dbInitEntryFromAddr(&addr, &entry2);
testOk1(entry.pdbbase==entry2.pdbbase);
testOk1(entry.precordType==entry2.precordType);
testOk1(entry.pflddes==entry2.pflddes);
testOk1(entry.precnode==entry2.precnode);
testOk1(entry.pfield==entry2.pfield);
testOk1(entry.indfield==entry2.indfield);
testOk1(!entry2.pinfonode);
testOk1(!entry2.message);
testOk(memcmp(&entry, &entry2, sizeof(entry))==0, "dbEntries identical");
dbFinishEntry(&entry);
dbFinishEntry(&entry2);
}
static void testRec2Entry(const char *recname)
{
DBENTRY entry, entry2;
dbCommon *prec;
testDiag("testRec2Entry(\"%s\")", recname);
memset(&entry, 0, sizeof(entry));
memset(&entry2, 0, sizeof(entry2));
prec = testdbRecordPtr(recname);
dbInitEntry(pdbbase, &entry);
if(dbFindRecord(&entry, recname)!=0)
testAbort("no entry for %s", recname);
if(dbFollowAlias(&entry))
testAbort("Can't follow alias");
dbInitEntryFromRecord(prec, &entry2);
testOk1(entry.pdbbase==entry2.pdbbase);
testOk1(entry.precordType==entry2.precordType);
testOk1(entry.pflddes==entry2.pflddes);
testOk1(entry.precnode==entry2.precnode);
testOk1(entry.pfield==entry2.pfield);
testOk1(entry.indfield==entry2.indfield);
testOk1(!entry2.pinfonode);
testOk1(!entry2.message);
testOk(memcmp(&entry, &entry2, sizeof(entry))==0, "dbEntries identical");
dbFinishEntry(&entry);
dbFinishEntry(&entry2);
}
static void verify(DBENTRY *pentry, const char *put, const char *exp)
{
const char *msg;
int result;
msg = dbVerify(pentry, put);
result = (!msg && !exp) || (msg && exp && strcmp(msg, exp) == 0);
if (!testOk(result, "dbVerify('%s.%s', '%s') => '%s'",
(char *) pentry->precnode->precord, pentry->pflddes->name,
put, msg ? msg : "OK"))
testDiag("Expected => '%s'", exp ? exp : "OK");
}
static void testDbVerify(const char *record)
{
DBENTRY entry;
testDiag("# # # # # # # testDbVerify('%s') # # # # # # # #", record);
dbInitEntry(pdbbase, &entry);
if (dbFindRecord(&entry, record) != 0)
testAbort("Can't find record '%s'", record);
dbFindField(&entry, "UDF");
verify(&entry, "0", NULL);
verify(&entry, "255", NULL);
verify(&entry, "256", "Number too large for field type");
verify(&entry, "0x100", "Number too large for field type");
dbFindField(&entry, "PHAS");
verify(&entry, "0", NULL);
verify(&entry, "-32768", NULL);
verify(&entry, "-32769", "Number too large for field type");
verify(&entry, "0x7fff", NULL);
verify(&entry, "32768", "Number too large for field type");
dbFindField(&entry, "VAL");
verify(&entry, "0", NULL);
verify(&entry, "-123456789", NULL);
verify(&entry, "123456789", NULL);
verify(&entry, "0x1234FEDC", NULL);
verify(&entry, "0x100000000", "Number too large for field type");
verify(&entry, "1.2345", "Extraneous characters after number");
dbFindField(&entry, "DESC");
verify(&entry, "", NULL);
verify(&entry, "abcdefghijklmnopqrstuvwxyz", NULL);
verify(&entry, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
"String too long, max 40 characters");
dbFindField(&entry, "DTYP");
verify(&entry, "Soft Channel", NULL);
verify(&entry, "zzzz", "Not a valid device type");
dbFindField(&entry, "SCAN");
verify(&entry, "1 second", NULL);
verify(&entry, "zzzz", "Not a valid menu choice");
dbFindField(&entry, "FLNK");
verify(&entry, "Anything works here!", NULL);
dbFinishEntry(&entry);
}
void dbTestIoc_registerRecordDeviceDriver(struct dbBase *);
MAIN(dbStaticTest)
{
testPlan(223);
testdbPrepare();
testdbReadDatabase("dbTestIoc.dbd", NULL, NULL);
dbTestIoc_registerRecordDeviceDriver(pdbbase);
testdbReadDatabase("dbStaticTest.db", NULL, NULL);
testEntry("testrec.VAL");
testEntry("testalias.VAL");
testEntry("testalias2.VAL");
testEntry("testalias3.VAL");
testAddr2Entry("testrec.VAL");
testAddr2Entry("testalias.VAL");
testAddr2Entry("testalias2.VAL");
testAddr2Entry("testalias3.VAL");
testRec2Entry("testrec");
testRec2Entry("testalias");
testRec2Entry("testalias2");
testRec2Entry("testalias3");
eltc(0);
testIocInitOk();
eltc(1);
testEntry("testrec.VAL");
testEntry("testalias.VAL");
testEntry("testalias2.VAL");
testEntry("testalias3.VAL");
testAddr2Entry("testrec.VAL");
testAddr2Entry("testalias.VAL");
testAddr2Entry("testalias2.VAL");
testAddr2Entry("testalias3.VAL");
testRec2Entry("testrec");
testRec2Entry("testalias");
testRec2Entry("testalias2");
testRec2Entry("testalias3");
testDbVerify("testrec");
testIocShutdownOk();
testdbCleanup();
return testDone();
}