From 302d2ec0a32bd51a12d94f325ea685c856b8d932 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 17 Mar 2016 17:00:43 -0400 Subject: [PATCH] more --- pdbApp/pdbgroup.cpp | 2 +- pdbApp/pvif.cpp | 24 ++++++++--------- testApp/testpdb.cpp | 36 +++++++++++++------------ testApp/testpdb.db | 2 ++ testApp/testpvif.cpp | 63 ++++++++++++++++++++++++++++---------------- testApp/testpvif.db | 1 + testApp/utilities.h | 16 +++++++++++ 7 files changed, 92 insertions(+), 52 deletions(-) diff --git a/pdbApp/pdbgroup.cpp b/pdbApp/pdbgroup.cpp index 250aea7..238bacb 100644 --- a/pdbApp/pdbgroup.cpp +++ b/pdbApp/pdbgroup.cpp @@ -45,7 +45,7 @@ void pdb_group_event(void *user_arg, struct dbChannel *chan, self->members[i].pvif->put(self->scratch, evt->dbe_mask, FL.pfl); } - if(info.had_initial_VALUE) { + if(!info.had_initial_VALUE) { info.had_initial_VALUE = true; self->initial_waits--; } diff --git a/pdbApp/pvif.cpp b/pdbApp/pvif.cpp index 8f35ad2..5433fae 100644 --- a/pdbApp/pvif.cpp +++ b/pdbApp/pvif.cpp @@ -315,19 +315,19 @@ void putMeta(const pvCommon& pv, unsigned dbe, db_field_log *pfl) } if(dbe&DBE_PROPERTY) { #undef FMAP -#define FMAP(MNAME, FNAME) if(pv.MNAME) pv.MNAME->put(meta.FNAME) - FMAP(displayHigh, upper_disp_limit); - FMAP(displayLow, lower_disp_limit); - FMAP(controlHigh, upper_ctrl_limit); - FMAP(controlLow, lower_ctrl_limit); - FMAP(egu, units); +#define FMAP(MASK, MNAME, FNAME) if(META::mask&(MASK) && pv.MNAME) pv.MNAME->put(meta.FNAME) + FMAP(DBR_GR_DOUBLE|DBR_GR_LONG, displayHigh, upper_disp_limit); + FMAP(DBR_GR_DOUBLE|DBR_GR_LONG, displayLow, lower_disp_limit); + FMAP(DBR_CTRL_DOUBLE|DBR_CTRL_DOUBLE, controlHigh, upper_ctrl_limit); + FMAP(DBR_CTRL_DOUBLE|DBR_CTRL_DOUBLE, controlLow, lower_ctrl_limit); + FMAP(DBR_GR_DOUBLE|DBR_GR_LONG, egu, units); #undef FMAP -#define FMAP(MNAME, FNAME) if(pv.MNAME) pv.MNAME->putFrom(meta.FNAME) - FMAP(prec, precision.dp); - FMAP(warnHigh, upper_warning_limit); - FMAP(warnLow, lower_warning_limit); - FMAP(alarmHigh, upper_alarm_limit); - FMAP(alarmLow, lower_alarm_limit); +#define FMAP(MASK, MNAME, FNAME) if(META::mask&(MASK) && pv.MNAME) pv.MNAME->putFrom(meta.FNAME) + FMAP(DBR_GR_DOUBLE, prec, precision.dp); + FMAP(DBR_AL_DOUBLE|DBR_AL_DOUBLE, warnHigh, upper_warning_limit); + FMAP(DBR_AL_DOUBLE|DBR_AL_DOUBLE, warnLow, lower_warning_limit); + FMAP(DBR_AL_DOUBLE|DBR_AL_DOUBLE, alarmHigh, upper_alarm_limit); + FMAP(DBR_AL_DOUBLE|DBR_AL_DOUBLE, alarmLow, lower_alarm_limit); #undef FMAP if(pv.enumopts) { pvd::shared_vector strs(meta.no_str); diff --git a/testApp/testpdb.cpp b/testApp/testpdb.cpp index 63df38e..80bb503 100644 --- a/testApp/testpdb.cpp +++ b/testApp/testpdb.cpp @@ -16,22 +16,6 @@ namespace pva = epics::pvAccess; namespace { -template -void testFieldEqual(const pvd::PVStructurePtr& val, const char *name, typename PVD::value_type expect) -{ - if(!val) { - testFail("empty structure"); - return; - } - typename PVD::shared_pointer fval(val->getSubField(name)); - if(!fval) { - testFail("field '%s' with type %s does not exist", name, typeid(PVD).name()); - } else { - typename PVD::value_type actual(fval->get()); - testEqualx(name, "expect", actual, expect); - } -} - pvd::PVStructurePtr makeRequest(bool atomic) { pvd::StructureConstPtr def(pvd::getFieldCreate()->createFieldBuilder() ->addNestedStructure("record") @@ -351,7 +335,25 @@ void testGroupMonitor(const PDBProvider::shared_pointer& prov) testDiag("subscribe to grp1"); PVMonitor mon(prov, "grp1"); - mon.mon->start(); + PVMonitor::Element e(mon); + + testOk1(mon.mon->start().isOK()); + + testDiag("Wait for initial event"); + testOk1(mon.monreq->waitForEvent()); + testDiag("Initial event"); + + e = mon.poll(); + testOk1(!!e); + + testFieldEqual(e, "fld1.value", 3.0); + testFieldEqual(e, "fld2.value", 30); + testFieldEqual(e, "fld3.value", 4.0); + testFieldEqual(e, "fld4.value", 40); + testFieldEqual(e, "fld1.display.limitHigh", 200.0); + testFieldEqual(e, "fld1.display.limitLow", -200.0); + testFieldEqual(e, "fld2.display.limitHigh", 2147483647.0); + testFieldEqual(e, "fld2.display.limitLow", -2147483648.0); } } // namespace diff --git a/testApp/testpdb.db b/testApp/testpdb.db index 0eeeff6..7237976 100644 --- a/testApp/testpdb.db +++ b/testApp/testpdb.db @@ -12,6 +12,8 @@ record(ai, "rec3") { field(VAL, "3.0") field(RVAL, "30") info(pdbGroup, "grp1|fld1=VAL|fld2=RVAL") + field(HOPR, "200") + field(LOPR, "-200") } record(ai, "rec4") { field(VAL, "4.0") diff --git a/testApp/testpvif.cpp b/testApp/testpvif.cpp index de52796..ac81ebf 100644 --- a/testApp/testpvif.cpp +++ b/testApp/testpvif.cpp @@ -37,18 +37,26 @@ void testScalar() DBCH chan_li("test:li"); DBCH chan_ai("test:ai"); + DBCH chan_ai_rval("test:ai.RVAL"); DBCH chan_mbbi("test:mbbi"); - testOk1(dbChannelFieldType(chan_li)==DBR_LONG); - testOk1(dbChannelFieldType(chan_ai)==DBR_DOUBLE); - testOk1(dbChannelFieldType(chan_mbbi)==DBR_ENUM); + testEqual(dbChannelFieldType(chan_li), DBR_LONG); + testEqual(dbChannelFieldType(chan_ai), DBR_DOUBLE); + testEqual(dbChannelFieldType(chan_ai_rval), DBR_LONG); + testEqual(dbChannelFieldType(chan_mbbi), DBR_ENUM); + testEqual(dbChannelFinalFieldType(chan_li), DBR_LONG); + testEqual(dbChannelFinalFieldType(chan_ai), DBR_DOUBLE); + testEqual(dbChannelFinalFieldType(chan_ai_rval), DBR_LONG); + testEqual(dbChannelFinalFieldType(chan_mbbi), DBR_ENUM); pvd::StructureConstPtr dtype_li(PVIF::dtype(chan_li)); pvd::StructureConstPtr dtype_ai(PVIF::dtype(chan_ai)); + pvd::StructureConstPtr dtype_ai_rval(PVIF::dtype(chan_ai_rval)); pvd::StructureConstPtr dtype_mbbi(PVIF::dtype(chan_mbbi)); pvd::StructureConstPtr dtype_root(pvd::getFieldCreate()->createFieldBuilder() ->add("li", dtype_li) ->add("ai", dtype_ai) + ->add("ai_rval", dtype_ai_rval) ->add("mbbi", dtype_mbbi) ->createStructure()); @@ -56,6 +64,7 @@ void testScalar() std::auto_ptr pvif_li(PVIF::attach(chan_li, root->getSubField("li"))); std::auto_ptr pvif_ai(PVIF::attach(chan_ai, root->getSubField("ai"))); + std::auto_ptr pvif_ai_rval(PVIF::attach(chan_ai_rval, root->getSubField("ai_rval"))); std::auto_ptr pvif_mbbi(PVIF::attach(chan_mbbi, root->getSubField("mbbi"))); pvd::BitSet mask; @@ -70,6 +79,7 @@ void testScalar() prec_ai->time.secPastEpoch = 0x12345678; prec_ai->time.nsec = 12345678; pvif_ai->put(mask, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL); + pvif_ai_rval->put(mask, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL); dbScanUnlock((dbCommon*)prec_ai); dbScanLock((dbCommon*)prec_mbbi); @@ -78,27 +88,36 @@ void testScalar() pvif_mbbi->put(mask, DBE_VALUE|DBE_ALARM|DBE_PROPERTY, NULL); dbScanUnlock((dbCommon*)prec_mbbi); - testOk1(root->getSubFieldT("li.value")->get()==102042); - testOk1(root->getSubFieldT("li.alarm.severity")->get()==1); - testOk1(root->getSubFieldT("li.timeStamp.secondsPastEpoch")->get()==0x12345678); - testOk1(root->getSubFieldT("li.timeStamp.nanoseconds")->get()==12345678); - testOk1(root->getSubFieldT("li.display.limitHigh")->get()==100.0); - testOk1(root->getSubFieldT("li.display.limitLow")->get()==10.0); - testOk1(root->getSubFieldT("li.display.units")->get()=="arb"); + testFieldEqual(root, "li.value", 102042); + testFieldEqual(root, "li.alarm.severity", 1); + testFieldEqual(root, "li.timeStamp.secondsPastEpoch", 0x12345678); + testFieldEqual(root, "li.timeStamp.nanoseconds", 12345678); + testFieldEqual(root, "li.display.limitHigh", 100.0); + testFieldEqual(root, "li.display.limitLow", 10.0); + testFieldEqual(root, "li.display.units", "arb"); - testOk1(root->getSubFieldT("ai.value")->get()==42.2); - testOk1(root->getSubFieldT("ai.alarm.severity")->get()==2); - testOk1(root->getSubFieldT("ai.timeStamp.secondsPastEpoch")->get()==0x12345678); - testOk1(root->getSubFieldT("ai.timeStamp.nanoseconds")->get()==12345678); - testOk1(root->getSubFieldT("ai.display.limitHigh")->get()==200.0); - testOk1(root->getSubFieldT("ai.display.limitLow")->get()==20.0); - testOk1(root->getSubFieldT("ai.display.format")->get()=="2"); - testOk1(root->getSubFieldT("ai.display.units")->get()=="foo"); + testFieldEqual(root, "ai.value", 42.2); + testFieldEqual(root, "ai.alarm.severity", 2); + testFieldEqual(root, "ai.timeStamp.secondsPastEpoch", 0x12345678); + testFieldEqual(root, "ai.timeStamp.nanoseconds", 12345678); + testFieldEqual(root, "ai.display.limitHigh", 200.0); + testFieldEqual(root, "ai.display.limitLow", 20.0); + testFieldEqual(root, "ai.display.format", "2"); + testFieldEqual(root, "ai.display.units", "foo"); - testOk1(root->getSubFieldT("mbbi.value.index")->get()==1); - testOk1(root->getSubFieldT("mbbi.alarm.severity")->get()==0); - testOk1(root->getSubFieldT("mbbi.timeStamp.secondsPastEpoch")->get()==0x12345678); - testOk1(root->getSubFieldT("mbbi.timeStamp.nanoseconds")->get()==12345678); + testFieldEqual(root, "ai_rval.value", 1234); + testFieldEqual(root, "ai_rval.alarm.severity", 2); + testFieldEqual(root, "ai_rval.timeStamp.secondsPastEpoch", 0x12345678); + testFieldEqual(root, "ai_rval.timeStamp.nanoseconds", 12345678); + testFieldEqual(root, "ai_rval.display.limitHigh", 2147483647.0); + testFieldEqual(root, "ai_rval.display.limitLow", -2147483648.0); + testFieldEqual(root, "ai_rval.display.format", ""); + testFieldEqual(root, "ai_rval.display.units", ""); + + testFieldEqual(root, "mbbi.value.index", 1); + testFieldEqual(root, "mbbi.alarm.severity", 0); + testFieldEqual(root, "mbbi.timeStamp.secondsPastEpoch", 0x12345678); + testFieldEqual(root, "mbbi.timeStamp.nanoseconds", 12345678); { pvd::PVStringArray::const_svector choices(root->getSubFieldT("mbbi.value.choices")->view()); testOk1(choices.size()==3); diff --git a/testApp/testpvif.db b/testApp/testpvif.db index 304d62b..1f8cdd8 100644 --- a/testApp/testpvif.db +++ b/testApp/testpvif.db @@ -8,6 +8,7 @@ record(longin, "test:li") { } record(ai, "test:ai") { field(VAL, "42.2") + field(RVAL, "1234") field(SEVR, "2") field(STAT, "0") field(EGU, "foo") diff --git a/testApp/utilities.h b/testApp/utilities.h index 35fe1d3..c50b1bd 100644 --- a/testApp/utilities.h +++ b/testApp/utilities.h @@ -60,6 +60,22 @@ void testEqualx(const char *nLHS, const char *nRHS, LHS l, RHS r) } #define testEqual(LHS, RHS) testEqualx(#LHS, #RHS, LHS, RHS) +template +void testFieldEqual(const epics::pvData::PVStructurePtr& val, const char *name, typename PVD::value_type expect) +{ + if(!val) { + testFail("empty structure"); + return; + } + typename PVD::shared_pointer fval(val->getSubField(name)); + if(!fval) { + testFail("field '%s' with type %s does not exist", name, typeid(PVD).name()); + } else { + typename PVD::value_type actual(fval->get()); + testEqualx(name, "expect", actual, expect); + } +} + // Boilerplate reduction for accessing a scalar field template struct ScalarAccessor {