47 std::cout <<
"B_2_1 - fault indicators" << std::endl;
53 BOOST_CHECK_EQUAL(status, 0);
54 BOOST_CHECK_EQUAL(
static_cast<std::string
>(message),
"");
56 deviceBackend->throwExceptionOpen =
true;
57 deviceBackend->throwExceptionRead =
true;
58 application.group1.pollModule.pollInput.read();
62 BOOST_CHECK_EQUAL(status, 1);
63 BOOST_CHECK(!
static_cast<std::string
>(message).empty());
65 deviceBackend->throwExceptionRead =
false;
66 deviceBackend->throwExceptionOpen =
false;
70 BOOST_CHECK_EQUAL(status, 0);
71 BOOST_CHECK_EQUAL(
static_cast<std::string
>(message),
"");
85 std::cout <<
"B_2_2_2_poll - exception with previous DataValidity::faulty" << std::endl;
88 write(exceptionDummyRegister, 134);
90 BOOST_REQUIRE_EQUAL(pollVariable, 134);
91 auto versionNumberBeforeRuntimeError = pollVariable.getVersionNumber();
98 pollVariable.setDataValidity(ctk::DataValidity::faulty);
99 for(
auto& e : pollVariable.getHardwareAccessingElements()) {
100 e->setDataValidity(ctk::DataValidity::faulty);
104 deviceBackend->throwExceptionOpen =
true;
105 deviceBackend->throwExceptionRead =
true;
106 write(exceptionDummyRegister, 10);
110 auto versionNumberOnRuntimeError = pollVariable.getVersionNumber();
111 BOOST_CHECK_EQUAL(pollVariable, 134);
112 BOOST_CHECK(pollVariable.dataValidity() == ctk::DataValidity::faulty);
113 BOOST_CHECK(versionNumberOnRuntimeError > versionNumberBeforeRuntimeError);
127 std::cout <<
"B_2_2_2_push - exception with previous DataValidity::faulty" << std::endl;
131 write(exceptionDummyRegister, 101);
132 ctk::VersionNumber versionNumberBeforeRuntimeError = {};
133 deviceBackend->triggerInterrupt(1);
137 pushVariable.setDataValidity(ctk::DataValidity::faulty);
138 for(
auto& e : pushVariable.getHardwareAccessingElements()) {
139 e->setDataValidity(ctk::DataValidity::faulty);
143 deviceBackend->throwExceptionOpen =
true;
144 deviceBackend->throwExceptionRead =
true;
145 write(exceptionDummyRegister, 11);
146 deviceBackend->triggerInterrupt(1);
150 auto versionNumberOnRuntimeError = pushVariable.getVersionNumber();
151 BOOST_CHECK_EQUAL(pushVariable, 101);
152 BOOST_CHECK(pushVariable.dataValidity() == ctk::DataValidity::faulty);
153 BOOST_CHECK(versionNumberOnRuntimeError > versionNumberBeforeRuntimeError);
166 std::cout <<
"B_2_2_3 - skip poll type reads" << std::endl;
169 write(exceptionDummyRegister, 100);
171 auto versionNumberBeforeRuntimeError = pollVariable.getVersionNumber();
174 deviceBackend->throwExceptionOpen =
true;
175 deviceBackend->throwExceptionRead =
true;
176 write(exceptionDummyRegister, 10);
180 auto versionNumberOnRuntimeError = pollVariable.getVersionNumber();
181 BOOST_CHECK_EQUAL(pollVariable, 100);
182 BOOST_CHECK(pollVariable.dataValidity() == ctk::DataValidity::faulty);
183 BOOST_CHECK(versionNumberOnRuntimeError > versionNumberBeforeRuntimeError);
187 BOOST_CHECK_EQUAL(pollVariable, 100);
188 BOOST_CHECK(pollVariable.dataValidity() == ctk::DataValidity::faulty);
189 BOOST_CHECK_EQUAL(pollVariable.getVersionNumber(), versionNumberOnRuntimeError);
203 std::cout <<
"B_2_2_3_TriggerFanOut - skip poll type reads (in TriggerFanOut)" << std::endl;
206 triggeredInput.readLatest();
208 write(exceptionDummy2Register, 666);
209 deviceBackend3->triggerInterrupt(1);
210 triggeredInput.read();
211 BOOST_REQUIRE_EQUAL(triggeredInput, 666);
214 deviceBackend2->throwExceptionOpen =
true;
215 deviceBackend2->throwExceptionRead =
true;
216 write(exceptionDummy2Register, 667);
219 deviceBackend3->triggerInterrupt(1);
220 triggeredInput.read();
221 BOOST_CHECK_EQUAL(triggeredInput, 666);
222 BOOST_CHECK(triggeredInput.dataValidity() == ctk::DataValidity::faulty);
225 deviceBackend3->triggerInterrupt(1);
226 triggeredInput.read();
227 BOOST_CHECK_EQUAL(triggeredInput, 666);
228 BOOST_CHECK(triggeredInput.dataValidity() == ctk::DataValidity::faulty);
242 std::cout <<
"B_2_2_4_blocking - first skip of blocking read" << std::endl;
244 pushVariable.readLatest();
247 ctk::VersionNumber
version = {};
248 deviceBackend->throwExceptionOpen =
true;
249 deviceBackend->throwExceptionRead =
true;
250 write(exceptionDummyRegister, 456);
251 deviceBackend->triggerInterrupt(1);
255 BOOST_CHECK_NE(pushVariable, 456);
256 BOOST_CHECK(pushVariable.dataValidity() == ctk::DataValidity::faulty);
257 auto versionNumberOnRuntimeError = pushVariable.getVersionNumber();
258 BOOST_CHECK(versionNumberOnRuntimeError >
version);
272 std::cout <<
"B_2_2_4_nonBlocking - first skip of readNonBlocking" << std::endl;
274 pushVariable.readLatest();
277 ctk::VersionNumber
version = {};
278 deviceBackend->throwExceptionOpen =
true;
279 deviceBackend->throwExceptionRead =
true;
280 write(exceptionDummyRegister, 123);
281 deviceBackend->triggerInterrupt(1);
284 CHECK_TIMEOUT(pushVariable.readNonBlocking() ==
true, 10000);
285 BOOST_CHECK_NE(pushVariable, 123);
286 BOOST_CHECK(pushVariable.dataValidity() == ctk::DataValidity::faulty);
287 auto versionNumberOnRuntimeError = pushVariable.getVersionNumber();
288 BOOST_CHECK(versionNumberOnRuntimeError >
version);
302 std::cout <<
"B_2_2_4_any - first skip of readAny" << std::endl;
304 pushVariable.readLatest();
306 ChimeraTK::ReadAnyGroup group({pushVariable});
309 ctk::VersionNumber
version = {};
310 deviceBackend->throwExceptionOpen =
true;
311 deviceBackend->throwExceptionRead =
true;
312 write(exceptionDummyRegister, 456);
313 deviceBackend->triggerInterrupt(1);
317 BOOST_CHECK_NE(pushVariable, 456);
318 BOOST_CHECK(pushVariable.dataValidity() == ctk::DataValidity::faulty);
319 auto versionNumberOnRuntimeError = pushVariable.getVersionNumber();
320 BOOST_CHECK(versionNumberOnRuntimeError >
version);
334 std::cout <<
"B_2_2_4_latest - first skip of readLatest" << std::endl;
336 pushVariable.readLatest();
339 ctk::VersionNumber
version = {};
340 deviceBackend->throwExceptionOpen =
true;
341 deviceBackend->throwExceptionRead =
true;
342 write(exceptionDummyRegister, 234);
343 deviceBackend->triggerInterrupt(1);
347 BOOST_CHECK_NE(pushVariable, 234);
348 BOOST_CHECK(pushVariable.dataValidity() == ctk::DataValidity::faulty);
349 auto versionNumberOnRuntimeError = pushVariable.getVersionNumber();
350 BOOST_CHECK(versionNumberOnRuntimeError >
version);
364 std::cout <<
"B_2_2_4_ThFO - first skip read in ThreadedFanOut" << std::endl;
367 pushVariable3copy.readLatest();
368 pushVariable3.readLatest();
371 ctk::VersionNumber
version = {};
372 deviceBackend2->throwExceptionOpen =
true;
373 deviceBackend2->throwExceptionRead =
true;
374 write(exceptionDummy2Register, 345);
375 deviceBackend2->triggerInterrupt(1);
378 pushVariable3.read();
379 BOOST_CHECK_NE(pushVariable3, 345);
380 BOOST_CHECK(pushVariable3.dataValidity() == ctk::DataValidity::faulty);
381 BOOST_CHECK(pushVariable3.getVersionNumber() >
version);
384 pushVariable3copy.read();
385 BOOST_CHECK_NE(pushVariable3copy, 345);
386 BOOST_CHECK(pushVariable3copy.dataValidity() == ctk::DataValidity::faulty);
387 BOOST_CHECK(pushVariable3copy.getVersionNumber() >
version);
401 std::cout <<
"B_2_2_4_TrFO - first skip read in TriggerFanOut on the trigger variable" << std::endl;
403 triggeredInput.readLatest();
406 write(exceptionDummy2Register, 668);
407 ctk::VersionNumber versionBeforeException = {};
408 deviceBackend3->triggerInterrupt(1);
409 triggeredInput.read();
412 deviceBackend3->throwExceptionOpen =
true;
413 deviceBackend3->throwExceptionRead =
true;
414 write(exceptionDummy2Register, 669);
415 pollVariable3.read();
419 triggeredInput.read();
420 BOOST_CHECK_EQUAL(triggeredInput, 669);
421 BOOST_CHECK(triggeredInput.dataValidity() == ctk::DataValidity::faulty);
422 BOOST_CHECK(triggeredInput.getVersionNumber() > versionBeforeException);
435 std::cout <<
"B_2_2_4_1_nonBlocking - following skip readNonBlocking" << std::endl;
437 pushVariable.readLatest();
440 deviceBackend->throwExceptionOpen =
true;
441 deviceBackend->throwExceptionRead =
true;
442 write(exceptionDummyRegister, 100);
443 deviceBackend->triggerInterrupt(1);
447 auto versionNumberOnRuntimeError = pushVariable.getVersionNumber();
450 for(
size_t i = 0; i < 5; ++i) {
452 BOOST_CHECK_EQUAL(pushVariable.readNonBlocking(),
false);
453 BOOST_CHECK(versionNumberOnRuntimeError == pushVariable.getVersionNumber());
454 BOOST_CHECK(pushVariable.dataValidity() == ctk::DataValidity::faulty);
468 std::cout <<
"B_2_2_4_1_latest - following skip readLatest" << std::endl;
470 pushVariable.readLatest();
473 deviceBackend->throwExceptionOpen =
true;
474 deviceBackend->throwExceptionRead =
true;
475 write(exceptionDummyRegister, 100);
476 deviceBackend->triggerInterrupt(1);
480 auto versionNumberOnRuntimeError = pushVariable.getVersionNumber();
483 for(
size_t i = 0; i < 5; ++i) {
485 BOOST_CHECK_EQUAL(pushVariable.readLatest(),
false);
486 BOOST_CHECK(versionNumberOnRuntimeError == pushVariable.getVersionNumber());
487 BOOST_CHECK(pushVariable.dataValidity() == ctk::DataValidity::faulty);
499 std::cout <<
"B_2_2_4_2 - freeze blocking read" << std::endl;
501 pushVariable.readLatest();
504 deviceBackend->throwExceptionOpen =
true;
505 deviceBackend->throwExceptionRead =
true;
506 write(exceptionDummyRegister, 100);
507 deviceBackend->triggerInterrupt(1);
513 deviceBackend->triggerInterrupt(1);
514 auto f = std::async(std::launch::async, [&]() { pushVariable.read(); });
515 BOOST_CHECK(f.wait_for(std::chrono::milliseconds(100)) == std::future_status::timeout);
518 deviceBackend->throwExceptionRead =
false;
519 deviceBackend->throwExceptionOpen =
false;
530 std::cout <<
"B_2_2_4_3 - value after recovery" << std::endl;
532 pushVariable.readLatest();
535 write(exceptionDummyRegister, 66);
536 deviceBackend->triggerInterrupt(1);
540 deviceBackend->throwExceptionOpen =
true;
541 deviceBackend->throwExceptionRead =
true;
542 write(exceptionDummyRegister, 77);
543 deviceBackend->triggerInterrupt(1);
546 BOOST_CHECK_EQUAL(pushVariable, 66);
549 deviceBackend->throwExceptionRead =
false;
550 deviceBackend->throwExceptionOpen =
false;
553 CHECK_TIMEOUT(pushVariable.readNonBlocking() ==
true, 10000);
554 BOOST_CHECK_EQUAL(pushVariable, 77);
565 std::cout <<
"B_2_2_5 - version numbers across PVs" << std::endl;
567 pushVariable.readLatest();
570 ctk::VersionNumber someVersionBeforeReporting = {};
571 deviceBackend->throwExceptionOpen =
true;
572 application.group1.device.reportException(
"explicit report by test");
573 ctk::VersionNumber someVersionAfterReporting = {};
577 auto exceptionVersion = pushVariable.getVersionNumber();
578 BOOST_CHECK(exceptionVersion > someVersionBeforeReporting);
579 BOOST_CHECK(exceptionVersion < someVersionAfterReporting);
583 BOOST_CHECK(pollVariable.getVersionNumber() == exceptionVersion);
594 std::cout <<
"B_2_2_6 - data buffer not updated" << std::endl;
596 pushVariable.readLatest();
599 write(exceptionDummyRegister, 66);
600 deviceBackend->triggerInterrupt(1);
602 BOOST_CHECK_EQUAL(pushVariable, 66);
604 write(exceptionDummyRegister, 67);
606 BOOST_CHECK_EQUAL(pollVariable, 67);
609 write(exceptionDummyRegister, 68);
610 deviceBackend->throwExceptionOpen =
true;
611 deviceBackend->throwExceptionRead =
true;
616 BOOST_REQUIRE(pushVariable.dataValidity() == ctk::DataValidity::ok);
618 BOOST_REQUIRE(pushVariable.dataValidity() == ctk::DataValidity::faulty);
619 BOOST_CHECK_EQUAL(pushVariable, 42);
624 BOOST_CHECK_EQUAL(pollVariable, 43);
636 std::cout <<
"B_2_3_3 - return value of write" << std::endl;
639 deviceBackend->throwExceptionOpen =
true;
640 deviceBackend->throwExceptionRead =
true;
644 outputVariable2 = 100;
645 auto testval = outputVariable2.write();
646 BOOST_CHECK_EQUAL(testval,
false);
648 outputVariable2 = 101;
649 BOOST_CHECK_EQUAL(outputVariable2.write(),
true);
660 std::cout <<
"B_2_3_5 - write before deviceBecameFunctional" << std::endl;
663 deviceBackend->throwExceptionOpen =
true;
664 deviceBackend->throwExceptionRead =
true;
668 outputVariable2 = 987;
669 outputVariable2.write();
672 deviceBackend->throwExceptionRead =
false;
673 deviceBackend->throwExceptionOpen =
false;
674 deviceBecameFunctional.read();
677 BOOST_CHECK_EQUAL(exceptionDummyRegister2[0], 987);
688 std::cout <<
"B_2_5 - isReadable/isWriteable/isReadOnly" << std::endl;
691 deviceBackend->throwExceptionOpen =
true;
692 deviceBackend->throwExceptionRead =
true;
697 BOOST_CHECK(pollVariable.isReadable());
699 BOOST_CHECK(pushVariable.isReadable());
701 BOOST_CHECK(outputVariable2.isWriteable());
702 BOOST_CHECK(!outputVariable2.isReadOnly());
719 std::cout <<
"B_3_2_2 - initialisation handlers" << std::endl;
722 BOOST_CHECK(initHandler1Called);
723 BOOST_CHECK(initHandler2Called);
724 initHandler1Called =
false;
725 initHandler2Called =
false;
728 deviceBackend->throwExceptionOpen =
true;
729 deviceBackend->throwExceptionRead =
true;
734 BOOST_CHECK(!initHandler1Called);
735 BOOST_CHECK(!initHandler2Called);
738 initHandler1Throws =
true;
739 deviceBackend->throwExceptionRead =
false;
740 deviceBackend->throwExceptionOpen =
false;
745 BOOST_CHECK(!initHandler2Called);
748 initHandler2Throws =
true;
749 initHandler1Called =
false;
750 initHandler1Throws =
false;
764 std::cout <<
"B_3_2_3 - delayed writes" << std::endl;
767 deviceBackend->throwExceptionOpen =
true;
768 deviceBackend->throwExceptionRead =
true;
771 (status.readNonBlocking(), status == 1), 10000);
774 auto wcReg2 = deviceBackend->getWriteCount(
"REG2");
775 auto wcReg3 = deviceBackend->getWriteCount(
"REG3");
776 auto wcRegV = deviceBackend->getWriteCount(
"REGV");
779 outputVariable2 = 801;
780 outputVariable2.write();
781 outputVariable3 = 802;
782 outputVariable3.write();
783 outputVariable2 = 803;
784 outputVariable2.write();
785 outputVariableV.write();
789 BOOST_CHECK_NE(exceptionDummyRegister2[0], 803);
790 BOOST_CHECK_NE(exceptionDummyRegister3[0], 802);
793 initHandler1Called =
false;
794 deviceBackend->throwExceptionRead =
false;
795 deviceBackend->throwExceptionWrite =
true;
796 deviceBackend->throwExceptionOpen =
false;
799 deviceBackend->throwExceptionCounter = 0;
800 CHECK_TIMEOUT(deviceBackend->throwExceptionCounter > 0, 10000);
801 BOOST_CHECK_NE(exceptionDummyRegister2[0], 803);
802 BOOST_CHECK_NE(exceptionDummyRegister3[0], 802);
805 BOOST_CHECK(initHandler1Called);
808 deviceBackend->throwExceptionWrite =
false;
811 CHECK_EQUAL_TIMEOUT((exceptionDummyRegister2.getBufferLock(), exceptionDummyRegister2[0]), 803, 10000);
812 CHECK_EQUAL_TIMEOUT((exceptionDummyRegister3.getBufferLock(), exceptionDummyRegister3[0]), 802, 10000);
815 auto woReg2 = deviceBackend->getWriteOrder(
"REG2");
816 auto woReg3 = deviceBackend->getWriteOrder(
"REG3");
817 BOOST_CHECK_GT(woReg2, woReg3);
820 BOOST_CHECK_EQUAL(deviceBackend->getWriteCount(
"REG2") - wcReg2, 1);
821 BOOST_CHECK_EQUAL(deviceBackend->getWriteCount(
"REG3") - wcReg3, 1);
824 BOOST_CHECK_EQUAL(deviceBackend->getWriteCount(
"REGV"), wcRegV);
835 std::cout <<
"B_3_2_5 - reactivate async reads" << std::endl;
838 BOOST_CHECK(deviceBackend->asyncReadActivated());
841 deviceBackend->throwExceptionOpen =
true;
842 deviceBackend->throwExceptionRead =
true;
846 outputVariable2.write();
849 assert(deviceBackend->asyncReadActivated() ==
false);
851 auto reg2WriteCountBeforeRecovery = deviceBackend->getWriteCount(
"REG2");
854 initHandler1Called =
false;
855 deviceBackend->throwExceptionRead =
false;
856 deviceBackend->throwExceptionOpen =
false;
860 BOOST_CHECK_EQUAL(deviceBackend->getWriteCount(
"REG2"), reg2WriteCountBeforeRecovery + 1);
871 std::cout <<
"B_3_2_6 - deviceBecameFunctional" << std::endl;
874 BOOST_CHECK(deviceBackend->asyncReadActivated());
875 BOOST_CHECK(initHandler1Called);
878 deviceBackend->throwExceptionOpen =
true;
879 deviceBackend->throwExceptionRead =
true;
884 BOOST_CHECK(deviceBecameFunctional.readNonBlocking() ==
false);
887 deviceBackend->throwExceptionRead =
false;
888 deviceBackend->throwExceptionOpen =
false;
891 CHECK_TIMEOUT(deviceBecameFunctional.readNonBlocking() ==
true, 10000);
895 BOOST_CHECK(deviceBecameFunctional.readNonBlocking() ==
false);
906 std::cout <<
"B_4_1 - broken devices don't affect unrelated modules" << std::endl;
908 pushVariable.readLatest();
911 write(exceptionDummyRegister, 101);
912 deviceBackend->triggerInterrupt(1);
914 BOOST_CHECK_EQUAL(pushVariable, 101);
916 write(exceptionDummyRegister, 102);
918 BOOST_CHECK_EQUAL(pollVariable, 102);
920 outputVariable2 = 103;
921 outputVariable2.write();
922 BOOST_CHECK_EQUAL(
int(exceptionDummyRegister2), 103);
925 status2.readLatest();
926 assert(status2 == 1);