Add test code for sync plugin.

This commit is contained in:
Michael Davidsaver
2012-04-27 13:25:17 -04:00
parent 95881525e5
commit 83586b49d0
2 changed files with 362 additions and 0 deletions
+6
View File
@@ -33,6 +33,12 @@ arrTest_LIBS += dbStaticIoc
OBJS_IOC_vxWorks += arrTest
TESTS += arrTest
TESTPROD_HOST += syncTest
syncTest_SRCS += syncTest.c
syncTest_LIBS += dbStaticHost
OBJS_IOC_vxWorks += syncTest
TESTS += syncTest
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
include $(TOP)/configure/RULES
+356
View File
@@ -0,0 +1,356 @@
/*************************************************************************\
* Copyright (c) 2010 Brookhaven National Laboratory.
* Copyright (c) 2010 Helmholtz-Zentrum Berlin
* fuer Materialien und Energie GmbH.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author: Ralph Lange <Ralph.Lange@bessy.de>
*/
#include <string.h>
#include "dbStaticLib.h"
#include "dbAccessDefs.h"
#include "db_field_log.h"
#include "dbCommon.h"
#include "chfPlugin.h"
#include "epicsUnitTest.h"
#include "epicsTime.h"
#include "dbState.h"
#include "testMain.h"
#define PATTERN 0x55
epicsShareExtern void (*pvar_func_syncInitialize)(void);
static db_field_log fl;
static dbStateId red;
static int fl_equal(const db_field_log *pfl1, const db_field_log *pfl2) {
return !(memcmp(pfl1, pfl2, sizeof(db_field_log)));
}
static void fl_setup(dbChannel *chan, db_field_log *pfl, long val) {
struct dbCommon *prec = dbChannelRecord(chan);
pfl->ctx = dbfl_context_event;
pfl->type = dbfl_type_val;
pfl->stat = prec->stat;
pfl->sevr = prec->sevr;
pfl->time = prec->time;
pfl->field_type = DBF_LONG;
pfl->no_elements = 1;
/*
* use memcpy to avoid a bus error on
* union copy of char in the db at an odd
* address
*/
memcpy(&pfl->u.v.field,
dbChannelField(chan),
dbChannelFieldSize(chan));
pfl->u.v.field.dbf_long = val;
}
static void changeValue(db_field_log *pfl2, long val) {
pfl2->u.v.field.dbf_long = val;
}
static void testHead (char* title) {
testDiag("--------------------------------------------------------");
testDiag(title);
testDiag("--------------------------------------------------------");
}
static void mustDrop(dbChannel *pch, db_field_log *pfl2, char* m) {
db_field_log *pfl = dbChannelRunPreChain(pch, pfl2);
testOk(NULL == pfl, "filter drops field_log (%s)", m);
}
static void mustPassTwice(dbChannel *pch, db_field_log *pfl2, char* m) {
testDiag("%s: filter must pass twice", m);
db_field_log *pfl = dbChannelRunPreChain(pch, pfl2);
testOk(pfl2 == pfl, "call 1 does not drop or replace field_log");
pfl = dbChannelRunPreChain(pch, pfl2);
testOk(pfl2 == pfl, "call 2 does not drop or replace field_log");
}
static void mustPassOld(dbChannel *pch, db_field_log *old, db_field_log *cur, char* m) {
db_field_log *pfl = dbChannelRunPreChain(pch, cur);
testOk(old == pfl, "filter passes previous field log (%s)", m);
}
static void mustPass(dbChannel *pch, db_field_log *cur, char* m) {
db_field_log *pfl = dbChannelRunPreChain(pch, cur);
testOk(cur == pfl, "filter passes field_log (%s)", m);
}
static void checkCtxRead(dbChannel *pch, dbStateId id) {
fl.ctx = dbfl_context_read;
dbStateClear(id);
mustPassTwice(pch, &fl, "ctx='read', state=FALSE");
dbStateSet(id);
mustPassTwice(pch, &fl, "ctx='read', state=TRUE");
dbStateClear(id);
mustPassTwice(pch, &fl, "ctx='read', state=FALSE");
fl.ctx = dbfl_context_event;
}
static void checkAndOpenChannel(dbChannel *pch, const chFilterPlugin *plug) {
ELLNODE *node;
chFilter *filter;
chPostEventFunc *cb_out = NULL;
void *arg_out = NULL;
testDiag("Test filter structure and open channel");
testOk((ellCount(&pch->filters) == 1), "channel has one plugin");
db_field_log fl1 = fl;
node = ellFirst(&pch->filters);
filter = CONTAINER(node, chFilter, list_node);
plug->fif->channel_register_pre(filter, &cb_out, &arg_out, &fl1);
testOk(!!(cb_out) && !!(arg_out), "register_pre registers one filter with argument");
testOk(fl_equal(&fl1, &fl), "register_pre does not change field_log data type");
testOk(!(dbChannelOpen(pch)), "dbChannel with plugin sync opened");
node = ellFirst(&pch->pre_chain);
filter = CONTAINER(node, chFilter, pre_node);
testOk((ellCount(&pch->pre_chain) == 1 && filter->pre_arg != NULL),
"sync has one filter with argument in pre chain");
testOk((ellCount(&pch->post_chain) == 0), "sync has no filter in post chain");
checkCtxRead(pch, red);
}
//MAIN(syncTest)
main()
{
dbChannel *pch;
chFilter *filter;
const chFilterPlugin *plug;
char myname[] = "sync";
ELLNODE *node;
chPostEventFunc *cb_out = NULL;
void *arg_out = NULL;
db_field_log *pfl[10];
db_field_log fl1;
int i;
testPlan(0);
db_init_events();
testOk1(!dbReadDatabase(&pdbbase, "filterTest.dbx", ".:..", NULL));
testOk(!!pdbbase, "pdbbase was set");
(*pvar_func_syncInitialize)(); /* manually initialize plugin */
testOk(!!(plug = dbFindFilter(myname, strlen(myname))), "plugin %s registered correctly", myname);
testOk(!!(red = dbStateCreate("red")), "state 'red' created successfully");
/* nonexisting state */
testOk(!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"while\",\"s\":\"blue\"}}")),
"dbChannel with sync (m='while' s='blue') (nonex state) failed");
/* missing state */
testOk(!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"while\"}}")),
"dbChannel with sync (m='while') (no state) failed");
/* missing mode */
testOk(!(pch = dbChannelCreate("x.VAL{\"sync\":{\"s\":\"red\"}}")),
"dbChannel with sync (s='red') (no mode) failed");
/* mode WHILE */
testHead("Mode WHILE (m='while', s='red')");
testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"while\",\"s\":\"red\"}}")),
"dbChannel with plugin sync (m='while' s='red') created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
mustDrop(pch, pfl[2], "state=FALSE, log2");
dbStateSet(red);
mustPass(pch, pfl[3], "state=TRUE, log3");
mustPass(pch, pfl[4], "state=TRUE, log4");
mustPass(pch, pfl[5], "state=TRUE, log5");
dbStateClear(red);
mustDrop(pch, pfl[6], "state=FALSE, log6");
mustDrop(pch, pfl[7], "state=FALSE, log7");
mustDrop(pch, pfl[8], "state=FALSE, log8");
for (i = 0; i < 10; i++)
db_delete_field_log(pfl[i]);
/* mode UNLESS */
testHead("Mode UNLESS (m='unless', s='red')");
testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"unless\",\"s\":\"red\"}}")),
"dbChannel with plugin sync (m='unless' s='red') created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
dbStateClear(red);
mustPass(pch, pfl[0], "state=FALSE, log0");
mustPass(pch, pfl[1], "state=FALSE, log1");
mustPass(pch, pfl[2], "state=FALSE, log2");
dbStateSet(red);
mustDrop(pch, pfl[3], "state=TRUE, log3");
mustDrop(pch, pfl[4], "state=TRUE, log4");
mustDrop(pch, pfl[5], "state=TRUE, log5");
dbStateClear(red);
mustPass(pch, pfl[6], "state=FALSE, log6");
mustPass(pch, pfl[7], "state=FALSE, log7");
mustPass(pch, pfl[8], "state=FALSE, log8");
for (i = 0; i < 10; i++)
db_delete_field_log(pfl[i]);
/* mode BEFORE */
testHead("Mode BEFORE (m='before', s='red')");
testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"before\",\"s\":\"red\"}}")),
"dbChannel with plugin sync (m='before' s='red') created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
mustDrop(pch, pfl[2], "state=FALSE, log2");
dbStateSet(red);
mustPassOld(pch, pfl[2], pfl[3], "state=TRUE, log3, pass=log2");
mustDrop(pch, pfl[4], "state=TRUE, log4");
mustDrop(pch, pfl[5], "state=TRUE, log5");
mustDrop(pch, pfl[6], "state=TRUE, log6");
dbStateClear(red);
mustDrop(pch, pfl[7], "state=FALSE, log7");
mustDrop(pch, pfl[8], "state=FALSE, log8");
mustDrop(pch, pfl[9], "state=FALSE, log9");
for (i = 0; i < 10; i++)
db_delete_field_log(pfl[i]);
/* mode FIRST */
testHead("Mode FIRST (m='first', s='red')");
testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"first\",\"s\":\"red\"}}")),
"dbChannel with plugin sync (m='first' s='red') created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
mustDrop(pch, pfl[2], "state=FALSE, log2");
dbStateSet(red);
mustPass(pch, pfl[3], "state=TRUE, log3");
mustDrop(pch, pfl[4], "state=TRUE, log4");
mustDrop(pch, pfl[5], "state=TRUE, log5");
dbStateClear(red);
mustDrop(pch, pfl[6], "state=FALSE, log6");
mustDrop(pch, pfl[7], "state=FALSE, log7");
mustDrop(pch, pfl[8], "state=FALSE, log8");
for (i = 0; i < 10; i++)
db_delete_field_log(pfl[i]);
/* mode LAST */
testHead("Mode LAST (m='last', s='red')");
testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"last\",\"s\":\"red\"}}")),
"dbChannel with plugin sync (m='last' s='red') created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
mustDrop(pch, pfl[2], "state=FALSE, log2");
dbStateSet(red);
mustDrop(pch, pfl[3], "state=TRUE, log3");
mustDrop(pch, pfl[4], "state=TRUE, log4");
mustDrop(pch, pfl[5], "state=TRUE, log5");
dbStateClear(red);
mustPassOld(pch, pfl[5], pfl[6], "state=TRUE, log6, pass=log5");
mustDrop(pch, pfl[7], "state=FALSE, log7");
mustDrop(pch, pfl[8], "state=FALSE, log8");
mustDrop(pch, pfl[9], "state=FALSE, log9");
for (i = 0; i < 10; i++)
db_delete_field_log(pfl[i]);
/* mode AFTER */
testHead("Mode AFTER (m='after', s='red')");
testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"after\",\"s\":\"red\"}}")),
"dbChannel with plugin sync (m='after' s='red') created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
mustDrop(pch, pfl[2], "state=FALSE, log2");
dbStateSet(red);
mustDrop(pch, pfl[3], "state=TRUE, log3");
mustDrop(pch, pfl[4], "state=TRUE, log4");
mustDrop(pch, pfl[5], "state=TRUE, log5");
dbStateClear(red);
mustPass(pch, pfl[6], "state=FALSE, log6");
mustDrop(pch, pfl[7], "state=FALSE, log7");
mustDrop(pch, pfl[8], "state=FALSE, log8");
for (i = 0; i < 10; i++)
db_delete_field_log(pfl[i]);
dbChannelDelete(pch);
dbFreeBase(pdbbase);
return testDone();
}