Merge 3.15 branch into 7.0

This commit is contained in:
Andrew Johnson
2019-10-28 01:03:12 -05:00
66 changed files with 7111 additions and 4573 deletions
@@ -59,6 +59,12 @@ syncTest_SRCS += filterTest_registerRecordDeviceDriver.cpp
testHarness_SRCS += syncTest.c
TESTS += syncTest
TESTPROD_HOST += decTest
decTest_SRCS += decTest.c
decTest_SRCS += filterTest_registerRecordDeviceDriver.cpp
testHarness_SRCS += decTest.c
TESTS += decTest
# epicsRunFilterTests runs all the test programs in a known working order.
testHarness_SRCS += epicsRunFilterTests.c
+30 -1
View File
@@ -39,12 +39,14 @@ static int fl_equal(const db_field_log *pfl1, const db_field_log *pfl2) {
static void fl_setup(dbChannel *chan, db_field_log *pfl) {
struct dbCommon *prec = dbChannelRecord(chan);
memset(pfl, 0, sizeof(db_field_log));
pfl->ctx = dbfl_context_read;
pfl->type = dbfl_type_val;
pfl->stat = prec->stat;
pfl->sevr = prec->sevr;
pfl->time = prec->time;
pfl->field_type = dbChannelFieldType(chan);
pfl->field_size = dbChannelFieldSize(chan);
pfl->no_elements = dbChannelElements(chan);
/*
* use memcpy to avoid a bus error on
@@ -62,6 +64,7 @@ static void changeValue(db_field_log *pfl2, long val) {
}
static void mustPassOnce(dbChannel *pch, db_field_log *pfl2, char* m, double d, long val) {
int oldFree = db_available_logs(), newFree;
db_field_log *pfl;
changeValue(pfl2, val);
@@ -71,18 +74,26 @@ static void mustPassOnce(dbChannel *pch, db_field_log *pfl2, char* m, double d,
testOk(fl_equal(pfl, pfl2), "call 1 does not change field_log data");
pfl = dbChannelRunPreChain(pch, pfl2);
testOk(NULL == pfl, "call 2 drops field_log");
newFree = db_available_logs();
testOk(newFree == oldFree + 1, "field_log was freed - %d+1 => %d",
oldFree, newFree);
}
static void mustDrop(dbChannel *pch, db_field_log *pfl2, char* m, double d, long val) {
int oldFree = db_available_logs(), newFree;
db_field_log *pfl;
changeValue(pfl2, val);
testDiag("mode=%s delta=%g filter must drop", m, d);
pfl = dbChannelRunPreChain(pch, pfl2);
testOk(NULL == pfl, "call 1 drops field_log");
newFree = db_available_logs();
testOk(newFree == oldFree + 1, "field_log was freed - %d+1 => %d",
oldFree, newFree);
}
static void mustPassTwice(dbChannel *pch, db_field_log *pfl2, char* m, double d, long val) {
int oldFree = db_available_logs(), newFree;
db_field_log *pfl;
changeValue(pfl2, val);
@@ -93,6 +104,9 @@ static void mustPassTwice(dbChannel *pch, db_field_log *pfl2, char* m, double d,
pfl = dbChannelRunPreChain(pch, pfl2);
testOk(pfl2 == pfl, "call 2 does not drop or replace field_log");
testOk(fl_equal(pfl, pfl2), "call 2 does not change field_log data");
newFree = db_available_logs();
testOk(newFree == oldFree, "field_log was not freed - %d => %d",
oldFree, newFree);
}
static void testHead (char* title) {
@@ -113,8 +127,9 @@ MAIN(dbndTest)
db_field_log *pfl2;
db_field_log fl1;
dbEventCtx evtctx;
int logsFree, logsFinal;
testPlan(59);
testPlan(77);
testdbPrepare();
@@ -135,6 +150,11 @@ MAIN(dbndTest)
testOk(!!(pch = dbChannelCreate("x.VAL{\"dbnd\":{}}")), "dbChannel with plugin dbnd (delta=0) created");
testOk((ellCount(&pch->filters) == 1), "channel has one plugin");
/* Start the free-list */
db_delete_field_log(db_create_read_log(pch));
logsFree = db_available_logs();
testDiag("%d field_logs on free-list", logsFree);
memset(&fl, PATTERN, sizeof(fl));
fl1 = fl;
node = ellFirst(&pch->filters);
@@ -176,6 +196,8 @@ MAIN(dbndTest)
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* Delta = -1: pass any update */
testHead("Delta = -1: pass any update");
@@ -192,6 +214,8 @@ MAIN(dbndTest)
db_delete_field_log(pfl2);
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* Delta = absolute */
testHead("Delta = absolute");
@@ -224,6 +248,8 @@ MAIN(dbndTest)
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* Delta = relative */
testHead("Delta = relative");
@@ -275,6 +301,9 @@ MAIN(dbndTest)
dbChannelDelete(pch);
logsFinal = db_available_logs();
testOk(logsFree == logsFinal, "%d field_logs on free-list", logsFinal);
db_close_events(evtctx);
testIocShutdownOk();
+289
View File
@@ -0,0 +1,289 @@
/*************************************************************************\
* Copyright (c) 2019 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* 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.
\*************************************************************************/
/*
* Authors: Ralph Lange <Ralph.Lange@bessy.de>,
* Andrew Johnson <anj@anl.gov>
*/
#include <string.h>
#include "dbStaticLib.h"
#include "dbAccessDefs.h"
#include "db_field_log.h"
#include "dbCommon.h"
#include "dbChannel.h"
#include "registry.h"
#include "chfPlugin.h"
#include "errlog.h"
#include "dbmf.h"
#include "epicsUnitTest.h"
#include "dbUnitTest.h"
#include "epicsTime.h"
#include "testMain.h"
#include "osiFileName.h"
void filterTest_registerRecordDeviceDriver(struct dbBase *);
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);
memset(pfl, 0, sizeof(db_field_log));
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->field_size = sizeof(epicsInt32);
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 testHead (char* title) {
testDiag("--------------------------------------------------------");
testDiag("%s", title);
testDiag("--------------------------------------------------------");
}
static void mustDrop(dbChannel *pch, db_field_log *pfl, char* m) {
int oldFree = db_available_logs();
db_field_log *pfl2 = dbChannelRunPreChain(pch, pfl);
int newFree = db_available_logs();
testOk(NULL == pfl2, "filter drops field_log (%s)", m);
testOk(newFree == oldFree + 1, "field_log was freed - %d+1 => %d",
oldFree, newFree);
db_delete_field_log(pfl2);
}
static void mustPass(dbChannel *pch, db_field_log *pfl, char* m) {
int oldFree = db_available_logs();
db_field_log *pfl2 = dbChannelRunPreChain(pch, pfl);
int newFree = db_available_logs();
testOk(pfl == pfl2, "filter passes field_log (%s)", m);
testOk(newFree == oldFree, "field_log was not freed - %d => %d",
oldFree, newFree);
db_delete_field_log(pfl2);
}
static void checkAndOpenChannel(dbChannel *pch, const chFilterPlugin *plug) {
ELLNODE *node;
chFilter *filter;
chPostEventFunc *cb_out = NULL;
void *arg_out = NULL;
db_field_log fl, fl1;
testDiag("Test filter structure and open channel");
testOk((ellCount(&pch->filters) == 1), "channel has one plugin");
fl_setup(pch, &fl, 1);
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 dec opened");
node = ellFirst(&pch->pre_chain);
filter = CONTAINER(node, chFilter, pre_node);
testOk((ellCount(&pch->pre_chain) == 1 && filter->pre_arg != NULL),
"dec has one filter with argument in pre chain");
testOk((ellCount(&pch->post_chain) == 0),
"sync has no filter in post chain");
}
MAIN(decTest)
{
dbChannel *pch;
const chFilterPlugin *plug;
char myname[] = "dec";
db_field_log *pfl[10];
int i, logsFree, logsFinal;
dbEventCtx evtctx;
testPlan(104);
testdbPrepare();
testdbReadDatabase("filterTest.dbd", NULL, NULL);
filterTest_registerRecordDeviceDriver(pdbbase);
testdbReadDatabase("xRecord.db", NULL, NULL);
eltc(0);
testIocInitOk();
eltc(1);
evtctx = db_init_events();
testOk(!!(plug = dbFindFilter(myname, strlen(myname))),
"plugin '%s' registered correctly", myname);
/* N < 1 */
testOk(!(pch = dbChannelCreate("x.VAL{\"dec\":{\"n\":-1}}")),
"dbChannel with dec (n=-1) failed");
testOk(!(pch = dbChannelCreate("x.VAL{\"dec\":{\"n\":0}}")),
"dbChannel with dec (n=0) failed");
/* Bad parms */
testOk(!(pch = dbChannelCreate("x.VAL{\"dec\":{}}")),
"dbChannel with dec (no parm) failed");
testOk(!(pch = dbChannelCreate("x.VAL{\"dec\":{\"x\":true}}")),
"dbChannel with dec (x=true) failed");
/* No Decimation (N=1) */
testHead("No Decimation (n=1)");
testOk(!!(pch = dbChannelCreate("x.VAL{\"dec\":{\"n\":1}}")),
"dbChannel with plugin dec (n=1) created");
/* Start the free-list */
db_delete_field_log(db_create_read_log(pch));
logsFree = db_available_logs();
testDiag("%d field_logs on free-list", logsFree);
checkAndOpenChannel(pch, plug);
for (i = 0; i < 5; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 10 + i);
}
testDiag("Test event stream");
mustPass(pch, pfl[0], "i=0");
mustPass(pch, pfl[1], "i=1");
mustPass(pch, pfl[2], "i=2");
mustPass(pch, pfl[3], "i=3");
mustPass(pch, pfl[4], "i=4");
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* Decimation (N=2) */
testHead("Decimation (n=2)");
testOk(!!(pch = dbChannelCreate("x.VAL{\"dec\":{\"n\":2}}")),
"dbChannel with plugin dec (n=2) created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 20 + i);
}
testDiag("Test event stream");
mustPass(pch, pfl[0], "i=0");
mustDrop(pch, pfl[1], "i=1");
mustPass(pch, pfl[2], "i=2");
mustDrop(pch, pfl[3], "i=3");
mustPass(pch, pfl[4], "i=4");
mustDrop(pch, pfl[5], "i=5");
mustPass(pch, pfl[6], "i=6");
mustDrop(pch, pfl[7], "i=7");
mustPass(pch, pfl[8], "i=8");
mustDrop(pch, pfl[9], "i=9");
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* Decimation (N=3) */
testHead("Decimation (n=3)");
testOk(!!(pch = dbChannelCreate("x.VAL{\"dec\":{\"n\":3}}")),
"dbChannel with plugin dec (n=3) created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 30 + i);
}
testDiag("Test event stream");
mustPass(pch, pfl[0], "i=0");
mustDrop(pch, pfl[1], "i=1");
mustDrop(pch, pfl[2], "i=2");
mustPass(pch, pfl[3], "i=3");
mustDrop(pch, pfl[4], "i=4");
mustDrop(pch, pfl[5], "i=5");
mustPass(pch, pfl[6], "i=6");
mustDrop(pch, pfl[7], "i=7");
mustDrop(pch, pfl[8], "i=8");
mustPass(pch, pfl[9], "i=9");
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* Decimation (N=4) */
testHead("Decimation (n=4)");
testOk(!!(pch = dbChannelCreate("x.VAL{\"dec\":{\"n\":4}}")),
"dbChannel with plugin dec (n=4) created");
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 40 + i);
}
testDiag("Test event stream");
mustPass(pch, pfl[0], "i=0");
mustDrop(pch, pfl[1], "i=1");
mustDrop(pch, pfl[2], "i=2");
mustDrop(pch, pfl[3], "i=3");
mustPass(pch, pfl[4], "i=4");
mustDrop(pch, pfl[5], "i=5");
mustDrop(pch, pfl[6], "i=6");
mustDrop(pch, pfl[7], "i=7");
mustPass(pch, pfl[8], "i=8");
mustDrop(pch, pfl[9], "i=9");
dbChannelDelete(pch);
logsFinal = db_available_logs();
testOk(logsFree == logsFinal, "%d field_logs on free-list", logsFinal);
db_close_events(evtctx);
testIocShutdownOk();
testdbCleanup();
return testDone();
}
@@ -17,6 +17,7 @@ int tsTest(void);
int dbndTest(void);
int syncTest(void);
int arrTest(void);
int decTest(void);
void epicsRunFilterTests(void)
{
@@ -26,6 +27,7 @@ void epicsRunFilterTests(void)
runTest(dbndTest);
runTest(syncTest);
runTest(arrTest);
runTest(decTest);
dbmfFreeChunks();
+130 -61
View File
@@ -42,12 +42,14 @@ static int fl_equal(const db_field_log *pfl1, const db_field_log *pfl2) {
static void fl_setup(dbChannel *chan, db_field_log *pfl, long val) {
struct dbCommon *prec = dbChannelRecord(chan);
memset(pfl, 0, sizeof(db_field_log));
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->field_size = sizeof(epicsInt32);
pfl->no_elements = 1;
/*
* use memcpy to avoid a bus error on
@@ -66,31 +68,92 @@ static void testHead (char* 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);
/*
* Use mustDrop() and mustPass() to test filters with no memory
* of previous field_log pointers.
*/
static void mustDrop(dbChannel *pch, db_field_log *pfl, char* m) {
int oldFree = db_available_logs();
db_field_log *pfl2 = dbChannelRunPreChain(pch, pfl);
int newFree = db_available_logs();
testOk(NULL == pfl2, "filter drops field_log (%s)", m);
testOk(newFree == oldFree + 1, "a field_log was freed - %d+1 => %d",
oldFree, newFree);
db_delete_field_log(pfl2);
}
static void mustPassTwice(dbChannel *pch, db_field_log *pfl2, char* m) {
db_field_log *pfl;
static void mustPass(dbChannel *pch, db_field_log *pfl, char* m) {
int oldFree = db_available_logs();
db_field_log *pfl2 = dbChannelRunPreChain(pch, pfl);
int newFree = db_available_logs();
testOk(pfl == pfl2, "filter passes field_log (%s)", m);
testOk(newFree == oldFree, "no field_logs were freed - %d => %d",
oldFree, newFree);
db_delete_field_log(pfl2);
}
/*
* Use mustStash() and mustSwap() to test filters that save
* field_log pointers and return them later.
*
* mustStash() expects the filter to save the current pointer
* (freeing any previously saved pointer) and return NULL.
* mustSwap() expects the filter to return the previously
* saved pointer and save the current pointer.
*/
static db_field_log *stashed;
static void streamReset(void) {
stashed = NULL;
}
static void mustStash(dbChannel *pch, db_field_log *pfl, char* m) {
int oldFree = db_available_logs();
db_field_log *pfl2 = dbChannelRunPreChain(pch, pfl);
int newFree = db_available_logs();
testOk(NULL == pfl2, "filter stashes field_log (%s)", m);
if (stashed) {
testOk(newFree == oldFree + 1, "a field_log was freed - %d+1 => %d",
oldFree, newFree);
}
else {
testOk(newFree == oldFree, "no field_logs were freed - %d => %d",
oldFree, newFree);
}
stashed = pfl;
db_delete_field_log(pfl2);
}
static void mustSwap(dbChannel *pch, db_field_log *pfl, char* m) {
int oldFree = db_available_logs();
db_field_log *pfl2 = dbChannelRunPreChain(pch, pfl);
int newFree = db_available_logs();
testOk(stashed == pfl2, "filter returns stashed field log (%s)", m);
testOk(newFree == oldFree, "no field_logs were freed - %d => %d",
oldFree, newFree);
stashed = pfl;
db_delete_field_log(pfl2);
}
static void mustPassTwice(dbChannel *pch, db_field_log *pfl, char* m) {
int oldFree = db_available_logs(), newFree;
db_field_log *pfl2;
testDiag("%s: filter must pass twice", m);
pfl = dbChannelRunPreChain(pch, pfl2);
pfl2 = dbChannelRunPreChain(pch, pfl);
testOk(pfl2 == pfl, "call 1 does not drop or replace field_log");
pfl = dbChannelRunPreChain(pch, pfl2);
pfl2 = dbChannelRunPreChain(pch, pfl);
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);
newFree = db_available_logs();
testOk(newFree == oldFree, "no field_logs were freed - %d => %d",
oldFree, newFree);
}
static void checkCtxRead(dbChannel *pch, dbStateId id) {
@@ -138,10 +201,10 @@ MAIN(syncTest)
const chFilterPlugin *plug;
char myname[] = "sync";
db_field_log *pfl[10];
int i;
int i, logsFree, logsFinal;
dbEventCtx evtctx;
testPlan(139);
testPlan(214);
testdbPrepare();
@@ -176,9 +239,14 @@ MAIN(syncTest)
testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"while\",\"s\":\"red\"}}")),
"dbChannel with plugin sync (m='while' s='red') created");
/* Start the free-list */
db_delete_field_log(db_create_read_log(pch));
logsFree = db_available_logs();
testDiag("%d field_logs on free-list", logsFree);
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
for (i = 0; i < 9; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
@@ -198,11 +266,10 @@ MAIN(syncTest)
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);
testDiag("%d field_logs on free-list", db_available_logs());
/* mode UNLESS */
testHead("Mode UNLESS (m='unless', s='red')");
@@ -211,7 +278,7 @@ MAIN(syncTest)
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
for (i = 0; i < 9; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
@@ -231,11 +298,10 @@ MAIN(syncTest)
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]);
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* mode BEFORE */
testHead("Mode BEFORE (m='before', s='red')");
@@ -251,24 +317,25 @@ MAIN(syncTest)
testDiag("Test event stream");
streamReset();
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
mustDrop(pch, pfl[2], "state=FALSE, log2");
mustStash(pch, pfl[0], "state=FALSE, log0");
mustStash(pch, pfl[1], "state=FALSE, log1");
mustStash(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");
mustSwap(pch, pfl[3], "state=TRUE, log3");
mustStash(pch, pfl[4], "state=TRUE, log4");
mustStash(pch, pfl[5], "state=TRUE, log5");
mustStash(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");
db_delete_field_log(pfl[2]);
mustStash(pch, pfl[7], "state=FALSE, log7");
mustStash(pch, pfl[8], "state=FALSE, log8");
mustStash(pch, pfl[9], "state=FALSE, log9");
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* mode FIRST */
testHead("Mode FIRST (m='first', s='red')");
@@ -277,13 +344,14 @@ MAIN(syncTest)
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
for (i = 0; i < 9; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
streamReset();
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
@@ -297,11 +365,10 @@ MAIN(syncTest)
mustDrop(pch, pfl[7], "state=FALSE, log7");
mustDrop(pch, pfl[8], "state=FALSE, log8");
db_delete_field_log(pfl[3]);
db_delete_field_log(pfl[9]);
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* mode LAST */
testHead("Mode LAST (m='last', s='red')");
@@ -317,24 +384,25 @@ MAIN(syncTest)
testDiag("Test event stream");
streamReset();
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
mustDrop(pch, pfl[2], "state=FALSE, log2");
mustStash(pch, pfl[0], "state=FALSE, log0");
mustStash(pch, pfl[1], "state=FALSE, log1");
mustStash(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");
mustStash(pch, pfl[3], "state=TRUE, log3");
mustStash(pch, pfl[4], "state=TRUE, log4");
mustStash(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");
db_delete_field_log(pfl[5]);
mustSwap(pch, pfl[6], "state=TRUE, log6");
mustStash(pch, pfl[7], "state=FALSE, log7");
mustStash(pch, pfl[8], "state=FALSE, log8");
mustStash(pch, pfl[9], "state=FALSE, log9");
dbChannelDelete(pch);
testDiag("%d field_logs on free-list", db_available_logs());
/* mode AFTER */
testHead("Mode AFTER (m='after', s='red')");
@@ -343,13 +411,14 @@ MAIN(syncTest)
checkAndOpenChannel(pch, plug);
for (i = 0; i < 10; i++) {
for (i = 0; i < 9; i++) {
pfl[i] = db_create_read_log(pch);
fl_setup(pch, pfl[i], 120 + i);
}
testDiag("Test event stream");
streamReset();
dbStateClear(red);
mustDrop(pch, pfl[0], "state=FALSE, log0");
mustDrop(pch, pfl[1], "state=FALSE, log1");
@@ -363,11 +432,11 @@ MAIN(syncTest)
mustDrop(pch, pfl[7], "state=FALSE, log7");
mustDrop(pch, pfl[8], "state=FALSE, log8");
db_delete_field_log(pfl[6]);
db_delete_field_log(pfl[9]);
dbChannelDelete(pch);
logsFinal = db_available_logs();
testOk(logsFree == logsFinal, "%d field_logs on free-list", logsFinal);
db_close_events(evtctx);
testIocShutdownOk();