From 098d6c65df26c518635752b7c129b8501d70c077 Mon Sep 17 00:00:00 2001 From: Martin Hierholzer <martin.hierholzer@desy.de> Date: Wed, 5 Feb 2020 13:54:25 +0100 Subject: [PATCH] TestFacility: fix initial for bidirectional variables The default value was properly propagated but not visible to the test until a value was sent through the return channel. --- include/TestFacility.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/TestFacility.h b/include/TestFacility.h index 6d2be730..401ab5be 100644 --- a/include/TestFacility.h +++ b/include/TestFacility.h @@ -41,7 +41,10 @@ namespace ChimeraTK { // send default values for all control system variables for(auto& pv : pvManager->getAllProcessVariables()) { callForType(pv->getValueType(), [&pv, this](auto arg) { + // Applies only to writeable variables. @todo FIXME It should also NOT apply for application-to-controlsystem + // variables with a return channel, despite being writeable here! if(!pv->isWriteable()) return; + // Safety check against incorrect usage if(pv->getVersionNumber() != VersionNumber(nullptr)) { throw ChimeraTK::logic_error("The variable '" + pv->getName() + "' has been written before TestFacility::runApplication() was called. Instead use " @@ -50,9 +53,25 @@ namespace ChimeraTK { typedef decltype(arg) T; auto pv_casted = boost::dynamic_pointer_cast<NDRegisterAccessor<T>>(pv); auto table = boost::fusion::at_key<T>(defaults.table); + // If default value has been stored, copy the default value to the PV. if(table.find(pv->getName()) != table.end()) { + /// Since pv_casted is the undecorated PV (lacking the TestableModeAccessorDecorator), we need to copy the + /// value also to the decorator. We still have to write through the undecorated PV, otherwise the tests are + /// stalled. @todo It is not understood why this happens! + /// Decorated accessors are stored in different maps for scalars are arrays... + if(pv_casted->getNumberOfSamples() == 1) { // scalar + auto accessor = this->getScalar<T>(pv->getName()); + accessor = table.at(pv->getName())[0]; + } + else { // array + auto accessor = this->getArray<T>(pv->getName()); + accessor = table.at(pv->getName()); + } + // copy value also to undecorated PV pv_casted->accessChannel(0) = table.at(pv->getName()); } + // Write the initial value. This must be done even if no default value has been stored, since it is expected + // by the application. pv_casted->write(); }); } -- GitLab