4 #define BOOST_TEST_DYN_LINK
5 #define BOOST_TEST_MODULE LMapBackendUnifiedTest
6 #include <boost/test/unit_test.hpp>
7 using namespace boost::unit_test_framework;
18 BOOST_AUTO_TEST_SUITE(LMapBackendUnifiedTestSuite)
22 static boost::shared_ptr<ExceptionDummy> exceptionDummyLikeMtcadummy, exceptionDummyMuxed, exceptionDummyPush;
23 static boost::shared_ptr<LogicalNameMappingBackend> lmapBackend;
29 template<
typename Derived>
31 Derived* derived{
static_cast<Derived*
>(
this)};
35 .disableAsyncReadInconsistency()
36 .disableSwitchReadOnly()
37 .disableSwitchWriteOnly()
38 .disableTestWriteNeverLosesData()
39 .enableTestRawTransfer();
55 auto& dummy =
dynamic_cast<ExceptionDummy&
>(derived->acc.getBackend());
57 dummy.throwExceptionWrite = enable;
58 dummy.throwExceptionOpen = enable;
59 if(derived->isPush() && enable) {
60 dummy.triggerInterrupt(6);
66 template<
typename Derived>
74 template<
typename UserType>
76 std::vector<UserType> v;
77 for(
size_t k = 0; k < derived->nElementsPerChannel(); ++k) {
78 v.push_back(derived->acc[derived->channel][k] + derived->increment * (k + 1));
83 template<
typename UserType>
85 std::vector<UserType> v;
86 for(
size_t k = 0; k < derived->nElementsPerChannel(); ++k) {
87 v.push_back(derived->acc[derived->channel][k]);
93 auto v = generateValue<typename Derived::minimumUserType>()[0];
94 for(
size_t k = 0; k < derived->nElementsPerChannel(); ++k) {
95 derived->acc[derived->channel][k] = v[k];
97 if(derived->isPush()) {
99 dynamic_cast<DummyBackend&
>(derived->acc.getBackend()).triggerInterrupt(6);
105 template<
typename Derived>
114 template<
typename T,
typename Traw>
116 return static_cast<T
>(value);
119 template<
typename UserType>
123 template<
typename Type>
126 typedef typename Derived::rawUserType Traw;
127 typedef typename Derived::minimumUserType T;
128 auto cv = derived->template getRemoteValue<Traw>(
true)[0];
129 for(
size_t i = 0; i < derived->nElementsPerChannel(); ++i) {
130 Traw e = cv[i] + derived->increment * (
static_cast<Traw
>(i) + 1);
132 v.push_back(derived->template convertRawToCooked<T, Traw>(e));
135 v.push_back(
static_cast<T
>(e));
138 derived->generateValueHook(v);
142 template<
typename UserType>
144 typedef typename Derived::rawUserType Traw;
146 std::vector<UserType> cookedValues(derived->nElementsPerChannel());
147 std::vector<Traw> rawValues(derived->nElementsPerChannel());
153 auto bufferLock = derived->acc.getBufferLock();
155 for(
size_t i = 0; i < derived->nElementsPerChannel(); ++i) {
156 rawValues[i] = derived->acc[i + derived->myOffset()];
160 for(
size_t i = 0; i < derived->nElementsPerChannel(); ++i) {
162 cookedValues[i] = derived->template convertRawToCooked<UserType, Traw>(rawValues[i]);
165 cookedValues[i] =
static_cast<UserType
>(rawValues[i]);
169 return {cookedValues};
173 auto v = generateValue<typename Derived::rawUserType>(
true)[0];
175 auto bufferLock = derived->acc.getBufferLock();
176 for(
size_t i = 0; i < derived->nElementsPerChannel(); ++i) {
177 derived->acc[i + derived->myOffset()] = v[i];
180 if(derived->isPush()) {
181 dynamic_cast<ExceptionDummy&
>(derived->acc.getBackend()).triggerInterrupt(6);
187 template<
typename Derived>
193 template<
typename Derived>
196 static constexpr
auto capabilities =
205 template<
typename UserType>
207 return this->getRemoteValue<UserType>();
210 template<
typename UserType>
212 std::vector<UserType> v;
213 for(
size_t k = 0; k < derived->nElementsPerChannel(); ++k) {
214 v.push_back(derived->value[k]);
225 template<
typename Derived>
235 template<
typename UserType>
244 bool backendWasOpened = lmapBackend->isOpen();
245 bool backendWasFunctional = lmapBackend->isFunctional();
246 if(!backendWasOpened || !backendWasFunctional) {
249 auto acc = lmapBackend->getRegisterAccessor<
typename Derived::minimumUserType>(derived->path(), 0, 0, {});
251 if(!backendWasOpened) {
252 lmapBackend->close();
254 else if(!backendWasFunctional) {
255 lmapBackend->setException(
"Some message");
257 std::vector<UserType> v;
258 for(
size_t k = 0; k < derived->nElementsPerChannel(); ++k) {
259 v.push_back(acc->accessData(k));
265 auto acc = lmapBackend->getRegisterAccessor<
typename Derived::minimumUserType>(derived->path(), 0, 0, {});
266 auto v = derived->template generateValue<typename Derived::minimumUserType>()[0];
267 for(
size_t k = 0; k < derived->nElementsPerChannel(); ++k) {
268 acc->accessData(k) = v[k];
270 bool backendWasOpened = lmapBackend->isOpen();
271 if(!backendWasOpened) {
281 if(!backendWasOpened) {
282 lmapBackend->close();
290 template<
typename Derived>
305 template<
typename UserType>
307 return {{!this->
template getRemoteValue<uint64_t>()[0][0]}};
310 template<
typename UserType>
312 uint64_t v = derived->target.template getRemoteValue<uint64_t>()[0][0];
313 uint64_t mask = 1 << derived->bit;
314 bool result = v & mask;
319 derived->target.setRemoteValue();
320 if(derived->isPush()) {
322 exceptionDummyPush->triggerInterrupt(6);
326 void setForceRuntimeError(
bool enable,
size_t caseIndex) { derived->target.setForceRuntimeError(enable, caseIndex); }
334 std::string
path() {
return "/SingleWord"; }
336 const uint32_t increment = 3;
346 std::string
path() {
return "/SingleWord"; }
348 const uint32_t increment = 3;
357 std::string
path() {
return "/SingleWord_push"; }
360 std::cout <<
"Warning: Writing test for /SingleWord_push has been disabled due to missing support in the dummy."
365 const uint32_t increment = 3;
374 std::string
path() {
return "/FullArea"; }
376 const int32_t increment = 7;
386 std::string
path() {
return "/PartOfArea"; }
388 const int32_t increment = 11;
399 std::string
path() {
return "/Channel3"; }
401 const int32_t increment = 17;
403 const size_t channel{3};
415 std::string
path() {
return "/Channel4_push"; }
418 const int32_t increment = 23;
420 const size_t channel{4};
432 std::string
path() {
return "/LastChannelInRegister"; }
434 const int32_t increment = 27;
436 const size_t channel{15};
448 std::string
path() {
return "/Constant"; }
451 const std::vector<int32_t> value{42};
459 std::string
path() {
return "/Constant2"; }
462 const std::vector<int32_t> value{666};
470 std::string
path() {
return "/MyModule/SomeSubmodule/Variable"; }
472 const int increment = 43;
481 std::string
path() {
return "/ArrayConstant"; }
483 const std::vector<int32_t> value{1111, 2222, 3333, 4444, 5555};
492 std::string
path() {
return "/ArrayVariable"; }
494 const int increment = 121;
503 std::string
path() {
return "/Bit0ofVar"; }
511 std::string
path() {
return "/Bit3ofVar"; }
519 std::string
path() {
return "/Bit2ofWordFirmwareA"; }
527 std::string
path() {
return "/Bit2ofWordFirmwareB"; }
533 boost::shared_ptr<NDRegisterAccessor<minimumUserType>> fixAccessorOnA{
539 std::string
path() {
return "/Bit2ofWordFirmware_push"; }
543 <<
"Warning: Writing test for /Bit2ofWordFirmware_push has been disabled due to missing support in the dummy."
553 template<
typename Derived>
555 std::string
path() {
return "/SingleWord_Scaled"; }
557 const double increment = std::exp(1.);
573 template<
typename T,
typename Traw>
586 template<
typename T,
typename Traw>
593 std::string
path() {
return "/SingleWord_NotScaled"; }
597 template<
typename T,
typename Traw>
605 std::string
path() {
return "/SingleWord_Scaled_Twice_push"; }
609 const double increment = std::exp(3.);
611 template<
typename T,
typename Traw>
619 static constexpr
auto capabilities =
627 std::string
path() {
return "/FullArea_Scaled"; }
632 static constexpr
auto capabilities =
635 const double increment = std::exp(4.);
638 template<
typename T,
typename Traw>
652 std::string
path() {
return "/WordFirmwareForcedReadOnly"; }
654 const uint32_t increment = -47;
664 std::string
path() {
return "/WordFirmwareForcedReadOnly_push"; }
667 const uint32_t increment = -47;
676 template<
typename Derived>
678 const double increment = 7;
689 std::string
path() {
return "/WordFirmwareWithMath_r"; }
692 template<
typename T,
typename Traw>
694 return value + 2.345;
701 std::string
path() {
return "/WordFirmwareWithMath_push"; }
703 template<
typename T,
typename Traw>
705 return value + 2.345;
712 std::string
path() {
return "/WordFirmwareWithMath_w"; }
716 template<
typename T,
typename Traw>
718 return value - 2.345;
724 std::string
path() {
return "/WordFirmwareAsParameterInMath"; }
729 const double increment = 91;
731 template<
typename T,
typename Traw>
739 static constexpr
auto capabilities =
749 static double RegVariableAsPushParameterInMathBase_lastX;
761 template<
typename Derived,
typename RawToCookedProv
ider>
766 .disableTestRawTransfer()
767 .disableTestCatalogue();
776 template<
typename T,
typename Traw>
778 return RawToCookedProvider::convertRawToCooked_impl(value, lmapBackend);
790 auto variable2 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest2", 0, 0, {});
792 return (value - variable2->accessData(0) * 121 - RegVariableAsPushParameterInMathBase_lastX) / 120;
798 std::string
path() {
return "/VariableForMathTest1"; }
800 const double increment = 17;
802 template<
typename UserType>
807 lmapBackend->activateAsyncRead();
811 auto x = lmapBackend->getRegisterAccessor<
double>(
"/RegisterWithVariableAsPushParameterInMath", 0, 0, {});
812 x->accessData(0) = RegVariableAsPushParameterInMathBase_lastX;
814 auto p2 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest2", 0, 0, {});
820 template<
typename Derived,
typename RawToCookedProv
ider>
823 template<
typename UserType>
826 registerValueBeforeWrite = getRemoteValue<double>(
true)[0][0];
828 auto generatedValue =
830 lastGeneratedValue = generatedValue[0][0];
831 return generatedValue;
834 template<
typename UserType>
840 auto remoteRawValue =
848 return remoteRawValue;
851 auto convertedValue = this->derived->template convertRawToCooked<double, double>(registerValueBeforeWrite);
852 assert(convertedValue != lastGeneratedValue);
854 if(remoteRawValue[0][0] == registerValueBeforeWrite) {
856 return {{lastGeneratedValue}};
860 if((lastReportedRemoteValue != remoteRawValue[0][0]) ||
861 (lastReportedValueBeforeWrite != registerValueBeforeWrite)) {
862 std::cout <<
"FAILED TEST: Register content altered when it should not have been. (" << remoteRawValue[0][0]
863 <<
" != " << registerValueBeforeWrite <<
")" << std::endl;
864 lastReportedRemoteValue = remoteRawValue[0][0];
865 lastReportedValueBeforeWrite = registerValueBeforeWrite;
867 return {{convertedValue}};
873 double lastReportedRemoteValue{0};
874 double lastReportedValueBeforeWrite{0};
879 RawToCookedProvider_Var1> {
880 std::string
path() {
return "/VariableForMathTest1"; }
882 const double increment = 18;
884 template<
typename UserType>
889 lmapBackend->close();
891 lmapBackend->activateAsyncRead();
893 auto x = lmapBackend->getRegisterAccessor<
double>(
"/RegisterWithVariableAsPushParameterInMath", 0, 0, {});
894 x->accessData(0) = RegVariableAsPushParameterInMathBase_lastX;
901 RawToCookedProvider_Var1> {
902 std::string
path() {
return "/VariableForMathTest1"; }
904 const double increment = 19;
906 template<
typename UserType>
911 lmapBackend->close();
913 lmapBackend->activateAsyncRead();
915 auto p2 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest2", 0, 0, {});
923 auto variable1 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest1", 0, 0, {});
925 return (value - variable1->accessData(0) * 120 - RegVariableAsPushParameterInMathBase_lastX) / 121;
931 std::string
path() {
return "/VariableForMathTest2"; }
933 const double increment = 23;
935 template<
typename UserType>
940 lmapBackend->activateAsyncRead();
944 auto x = lmapBackend->getRegisterAccessor<
double>(
"/RegisterWithVariableAsPushParameterInMath", 0, 0, {});
945 x->accessData(0) = RegVariableAsPushParameterInMathBase_lastX;
947 auto p1 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest1", 0, 0, {});
955 auto variable1 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest1", 0, 0, {});
957 auto variable2 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest2", 0, 0, {});
959 return value - variable1->accessData(0) * 120 - variable2->accessData(0) * 121;
966 std::string
path() {
return "/RegisterWithVariableAsPushParameterInMath"; }
968 const double increment = 42;
970 template<
typename UserType>
974 RegVariableAsPushParameterInMathBase_lastX = v[0];
978 lmapBackend->activateAsyncRead();
981 auto p1 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest1", 0, 0, {});
984 auto p2 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest2", 0, 0, {});
992 std::string
path() {
return "/RegisterWithVariableAsPushParameterInMath"; }
994 const double increment = 43;
996 template<
typename UserType>
1000 RegVariableAsPushParameterInMathBase_lastX = v[0];
1004 lmapBackend->close();
1005 lmapBackend->open();
1006 lmapBackend->activateAsyncRead();
1008 auto p1 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest1", 0, 0, {});
1017 std::string
path() {
return "/RegisterWithVariableAsPushParameterInMath"; }
1019 const double increment = 44;
1021 template<
typename UserType>
1025 RegVariableAsPushParameterInMathBase_lastX = v[0];
1029 lmapBackend->close();
1030 lmapBackend->open();
1031 lmapBackend->activateAsyncRead();
1033 auto p2 = lmapBackend->getRegisterAccessor<
double>(
"/VariableForMathTest2", 0, 0, {});
1042 static constexpr
double theOffset = 10;
1045 return ((uint32_t(value) >> 3) & 1) + theOffset;
1051 std::string
path() {
return "/RedirectedBitWithMath"; }
1053 const double increment = 8;
1056 template<
typename UserType>
1061 lmapBackend->activateAsyncRead();
1065 auto x = lmapBackend->getRegisterAccessor<
double>(
"/RedirectedBitWithMath_helper", 0, 0, {});
1073 std::string
path() {
return "/MonostableTrigger"; }
1080 uint32_t increment = 0;
1082 template<
typename UserType>
1090 template<
typename UserType>
1092 return generateValue<UserType>();
1100 static constexpr
auto capabilities =
1107 template<
typename Derived>
1119 template<
typename UserType>
1121 return derived->target.template generateValue<UserType>();
1124 template<
typename UserType>
1126 uint64_t v = derived->target.template getRemoteValue<uint64_t>()[0][0];
1127 uint64_t mask = ((1 << derived->width) - 1) << derived->shift;
1128 UserType result = (v & mask) >> derived->shift;
1134 void setForceRuntimeError(
bool enable,
size_t caseIndex) { derived->target.setForceRuntimeError(enable, caseIndex); }
1138 std::string
path() {
return "/BOARD.WORD_FIRMWARE"; }
1142 using minimumUserType = uint32_t;
1143 using rawUserType = int32_t;
1144 DummyRegisterAccessor<minimumUserType> acc{exceptionDummyLikeMtcadummy.get(), "", "/BOARD.WORD_FIRMWARE"};
1147 struct RegLowerHalfOfFirmware : RegBitRangeDescriptor<RegLowerHalfOfFirmware> {
1148 std::string path() { return "/BitRangeLower"; }
1150 using minimumUserType = int8_t;
1155 BitRangeAccessorTarget target;
1158 struct RegUpperHalfOfFirmware : RegBitRangeDescriptor<RegUpperHalfOfFirmware> {
1159 std::string path() { return "/BitRangeUpper"; }
1161 using minimumUserType = int16_t;
1163 uint16_t width = 16;
1164 uint16_t shift = 16;
1166 BitRangeAccessorTarget target;
1169 struct Reg9BitsInChar : RegBitRangeDescriptor<Reg9BitsInChar> {
1170 std::string path() { return "/BitRangeMiddle"; }
1172 using minimumUserType = int8_t;
1177 BitRangeAccessorTarget target;
1180 /**********************************************************************************************************************/
1182 BOOST_AUTO_TEST_CASE(unifiedBackendTest) {
1183 std::string dummyCdd = "(ExceptionDummy?map=mtcadummy.map)";
1184 std::string muxedDummyCdd = "(ExceptionDummy?map=muxedDataAcessor.map)";
1185 std::string pushDummyCdd = "(ExceptionDummy?map=mtcadummyB.map)";
1186 std::string lmapCdd = "(logicalNameMap?map=unifiedTest.xlmap&target=" + dummyCdd + "&target2=" + muxedDummyCdd +
1187 "&target3=" + pushDummyCdd + ")";
1188 exceptionDummyLikeMtcadummy =
1189 boost::dynamic_pointer_cast<ExceptionDummy>(BackendFactory::getInstance().createBackend(dummyCdd));
1190 exceptionDummyMuxed =
1191 boost::dynamic_pointer_cast<ExceptionDummy>(BackendFactory::getInstance().createBackend(muxedDummyCdd));
1192 // needed for a test that redirected bit goes to right target device
1193 exceptionDummyPush =
1194 boost::dynamic_pointer_cast<ExceptionDummy>(BackendFactory::getInstance().createBackend(pushDummyCdd));
1196 boost::dynamic_pointer_cast<LogicalNameMappingBackend>(BackendFactory::getInstance().createBackend(lmapCdd));
1198 ChimeraTK::UnifiedBackendTest<>()
1199 .addRegister<RegSingleWord>()
1200 .addRegister<RegSingleWord_push>()
1201 .addRegister<RegFullArea>()
1202 .addRegister<RegPartOfArea>()
1203 .addRegister<RegChannel3>()
1204 .addRegister<RegChannel4_push>()
1205 .addRegister<RegChannelLast>()
1206 .addRegister<RegConstant>()
1207 .addRegister<RegConstant2>()
1208 .addRegister<RegVariable>()
1209 .addRegister<RegArrayConstant>()
1210 .addRegister<RegArrayVariable>()
1211 .addRegister<RegBit0OfVar>()
1212 .addRegister<RegBit3OfVar>()
1213 .addRegister<RegBit2OfWordFirmware>()
1214 .addRegister<RegBit2OfWordFirmwareB>()
1215 .addRegister<RegBit2OfWordFirmware_push>()
1216 .addRegister<RegSingleWordScaled_R>()
1217 .addRegister<RegSingleWordScaled_W>()
1218 .addRegister<RegSingleWordScaled_RW>()
1219 .addRegister<RegSingleWordScaledTwice_push>()
1220 .addRegister<RegFullAreaScaled>()
1221 .addRegister<RegWordFirmwareForcedReadOnly>()
1222 .addRegister<RegWordFirmwareForcedReadOnly_push>()
1223 .addRegister<RegWordFirmwareWithMath_R>()
1224 .addRegister<RegWordFirmwareWithMath_R_push>()
1225 .addRegister<RegWordFirmwareWithMath_W>()
1226 .addRegister<RegWordFirmwareAsParameterInMath>()
1227 .addRegister<RegVariableAsPushParameterInMath_var1>()
1228 .addRegister<RegVariableAsPushParameterInMath_var1_not_written1>()
1229 .addRegister<RegVariableAsPushParameterInMath_var1_not_written2>()
1230 .addRegister<RegVariableAsPushParameterInMath_var2>()
1231 .addRegister<RegVariableAsPushParameterInMath_x>()
1232 .addRegister<RegVariableAsPushParameterInMath_x_not_written1>()
1233 .addRegister<RegVariableAsPushParameterInMath_x_not_written2>()
1234 .addRegister<RegRedirectedBitWithMath>()
1235 .addRegister<RegMonostableTrigger>()
1236 .addRegister<RegLowerHalfOfFirmware>()
1237 .addRegister<RegUpperHalfOfFirmware>()
1238 .addRegister<Reg9BitsInChar>()
1242 /**********************************************************************************************************************/
1244 BOOST_AUTO_TEST_SUITE_END()