5#define BOOST_TEST_MODULE testPropagateDataFaultFlag
17#include <ChimeraTK/BackendFactory.h>
18#include <ChimeraTK/Device.h>
19#include <ChimeraTK/DummyRegisterAccessor.h>
20#include <ChimeraTK/ExceptionDummyBackend.h>
21#include <ChimeraTK/NDRegisterAccessor.h>
23#include <boost/mpl/list.hpp>
25#define BOOST_NO_EXCEPTIONS
26#include <boost/test/included/unit_test.hpp>
27#undef BOOST_NO_EXCEPTIONS
31 using namespace boost::unit_test_framework;
39 using ctk::ApplicationModule::ApplicationModule;
59 oStat.setDataValidity(ctk::DataValidity::faulty);
70 using ctk::ApplicationModule::ApplicationModule;
108 std::cout <<
"testDirectConnections" << std::endl;
114 auto i2 = test.
getArray<
int>(
"/t1/i2");
117 auto o2 = test.
getArray<
int>(
"/t1/o2");
118 auto oStat = test.
getArray<
int>(
"/t1/oStat");
124 i1.setDataValidity(ctk::DataValidity::faulty);
130 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
131 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
132 BOOST_CHECK(oStat.dataValidity() == ctk::DataValidity::ok);
133 BOOST_CHECK_EQUAL(
int(o1), 1);
134 BOOST_CHECK_EQUAL(o2[0], 0);
135 BOOST_CHECK_EQUAL(o2[1], 0);
139 BOOST_CHECK(i1.dataValidity() == ctk::DataValidity::faulty);
144 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
145 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
146 BOOST_CHECK_EQUAL(
int(o1), 42);
147 BOOST_CHECK_EQUAL(o2[0], 0);
148 BOOST_CHECK_EQUAL(o2[1], 0);
153 BOOST_CHECK(i2.dataValidity() == ctk::DataValidity::ok);
158 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
159 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
160 BOOST_CHECK_EQUAL(
int(o1), 42);
161 BOOST_CHECK_EQUAL(o2[0], 10);
162 BOOST_CHECK_EQUAL(o2[1], 11);
165 BOOST_CHECK(i3.readNonBlocking() ==
false);
166 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
173 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
174 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
175 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
176 BOOST_CHECK_EQUAL(
int(o1), 42);
177 BOOST_CHECK_EQUAL(o2[0], 10);
178 BOOST_CHECK_EQUAL(o2[1], 11);
179 BOOST_CHECK_EQUAL(
int(i3), 10);
183 i1.setDataValidity(ctk::DataValidity::ok);
188 BOOST_CHECK(i3.readNonBlocking() ==
false);
189 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::ok);
190 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::ok);
191 BOOST_CHECK_EQUAL(
int(o1), 3);
192 BOOST_CHECK_EQUAL(o2[0], 10);
193 BOOST_CHECK_EQUAL(o2[1], 11);
194 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
195 BOOST_CHECK_EQUAL(
int(i3), 10);
199 i1.setDataValidity(ctk::DataValidity::faulty);
202 i3.setDataValidity(ctk::DataValidity::faulty);
208 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
209 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
210 BOOST_CHECK_EQUAL(
int(o1), 120);
211 BOOST_CHECK_EQUAL(o2[0], 10);
212 BOOST_CHECK_EQUAL(o2[1], 11);
213 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::faulty);
214 BOOST_CHECK_EQUAL(
int(i3), 10);
218 i1.setDataValidity(ctk::DataValidity::ok);
223 BOOST_CHECK(i3.readNonBlocking() ==
false);
224 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
225 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
226 BOOST_CHECK_EQUAL(
int(o1), 122);
227 BOOST_CHECK_EQUAL(o2[0], 10);
228 BOOST_CHECK_EQUAL(o2[1], 11);
229 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::faulty);
230 BOOST_CHECK_EQUAL(
int(i3), 10);
234 i3.setDataValidity(ctk::DataValidity::ok);
240 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::ok);
241 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::ok);
242 BOOST_CHECK_EQUAL(
int(o1), 122);
243 BOOST_CHECK_EQUAL(o2[0], 10);
244 BOOST_CHECK_EQUAL(o2[1], 11);
245 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
246 BOOST_CHECK_EQUAL(
int(i3), 10);
253 BOOST_CHECK(oStat.dataValidity() == ctk::DataValidity::faulty);
259 std::cout <<
"testWithFanOut" << std::endl;
264 auto Ai2 = test.
getArray<
int>(
"A/i2");
267 auto Ao2 = test.
getArray<
int>(
"A/o2");
275 Ai1.setDataValidity(ctk::DataValidity::faulty);
280 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::faulty);
281 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::faulty);
282 BOOST_CHECK_EQUAL(
int(Ao1), 1);
283 BOOST_CHECK_EQUAL(Ao2[0], 0);
284 BOOST_CHECK_EQUAL(Ao2[1], 0);
285 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::faulty);
286 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::faulty);
287 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 1);
288 BOOST_CHECK_EQUAL(app.
b.
o2[0], 0);
289 BOOST_CHECK_EQUAL(app.
b.
o2[1], 0);
290 BOOST_CHECK(app.
b.
i1.dataValidity() == ctk::DataValidity::faulty);
291 BOOST_CHECK_EQUAL(
int(app.
b.
i1), 1);
296 Ai2.setDataValidity(ctk::DataValidity::faulty);
301 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::faulty);
302 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::faulty);
303 BOOST_CHECK_EQUAL(
int(Ao1), 1);
304 BOOST_CHECK_EQUAL(Ao2[0], 2);
305 BOOST_CHECK_EQUAL(Ao2[1], 3);
306 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::faulty);
307 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::faulty);
308 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 1);
309 BOOST_CHECK_EQUAL(app.
b.
o2[0], 2);
310 BOOST_CHECK_EQUAL(app.
b.
o2[1], 3);
311 BOOST_CHECK(app.
b.
i2.dataValidity() == ctk::DataValidity::faulty);
312 BOOST_CHECK_EQUAL(app.
b.
i2[0], 2);
313 BOOST_CHECK_EQUAL(app.
b.
i2[1], 3);
318 Ai2.setDataValidity(ctk::DataValidity::ok);
323 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::faulty);
324 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::faulty);
325 BOOST_CHECK_EQUAL(
int(Ao1), 1);
326 BOOST_CHECK_EQUAL(Ao2[0], 4);
327 BOOST_CHECK_EQUAL(Ao2[1], 5);
328 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::faulty);
329 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::faulty);
330 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 1);
331 BOOST_CHECK_EQUAL(app.
b.
o2[0], 4);
332 BOOST_CHECK_EQUAL(app.
b.
o2[1], 5);
333 BOOST_CHECK(app.
b.
i2.dataValidity() == ctk::DataValidity::ok);
334 BOOST_CHECK_EQUAL(app.
b.
i2[0], 4);
335 BOOST_CHECK_EQUAL(app.
b.
i2[1], 5);
339 Ai1.setDataValidity(ctk::DataValidity::ok);
344 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::ok);
345 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::ok);
346 BOOST_CHECK_EQUAL(
int(Ao1), 6);
347 BOOST_CHECK_EQUAL(Ao2[0], 4);
348 BOOST_CHECK_EQUAL(Ao2[1], 5);
349 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::ok);
350 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::ok);
351 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 6);
352 BOOST_CHECK_EQUAL(app.
b.
o2[0], 4);
353 BOOST_CHECK_EQUAL(app.
b.
o2[1], 5);
354 BOOST_CHECK(app.
b.
i1.dataValidity() == ctk::DataValidity::ok);
355 BOOST_CHECK_EQUAL(
int(app.
b.
i1), 6);
368 using ctk::ApplicationModule::ApplicationModule;
389 using ctk::ApplicationModule::ApplicationModule;
392 using ctk::VariableGroup::VariableGroup;
394 } m1VarsFromCS{
this,
"../m1",
""};
400 result =
static_cast<int>(m1VarsFromCS.result);
477 BOOST_FIXTURE_TEST_SUITE(data_validity_propagation, FixtureTestFacility)
482 std::cout <<
"testThreadedFanout" << std::endl;
483 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
484 auto m1_result = test.getScalar<
int>(
"m1/Module1_result");
485 auto m2_result = test.getScalar<
int>(
"m2/Module2_result");
487 threadedFanoutInput = 20;
488 threadedFanoutInput.write();
490 auto consumingFanoutSource =
492 consumingFanoutSource = 10;
493 consumingFanoutSource.write();
498 pollRegister.write();
500 test.stepApplication();
504 BOOST_CHECK_EQUAL(m1_result, 35);
505 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
507 BOOST_CHECK_EQUAL(m2_result, 35);
508 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
510 threadedFanoutInput = 10;
511 threadedFanoutInput.setDataValidity(ctk::DataValidity::faulty);
512 threadedFanoutInput.write();
513 test.stepApplication();
517 BOOST_CHECK_EQUAL(m1_result, 25);
518 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
519 BOOST_CHECK_EQUAL(m2_result, 25);
520 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
522 threadedFanoutInput = 40;
523 threadedFanoutInput.setDataValidity(ctk::DataValidity::ok);
524 threadedFanoutInput.write();
525 test.stepApplication();
529 BOOST_CHECK_EQUAL(m1_result, 55);
530 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
531 BOOST_CHECK_EQUAL(m2_result, 55);
532 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
538 std::cout <<
"testInvalidTrigger" << std::endl;
540 auto deviceRegister =
543 deviceRegister.write();
545 auto trigger = test.getVoid(
"trigger");
546 auto result = test.getScalar<
int>(
"/m1/i3");
552 test.stepApplication();
555 BOOST_CHECK_EQUAL(result, 20);
556 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
561 deviceRegister.write();
562 trigger.setDataValidity(ctk::DataValidity::faulty);
565 test.stepApplication();
568 BOOST_CHECK_EQUAL(result, 30);
569 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
574 deviceRegister.write();
576 trigger.setDataValidity(ctk::DataValidity::ok);
579 test.stepApplication();
582 BOOST_CHECK_EQUAL(result, 50);
583 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
586 BOOST_AUTO_TEST_SUITE_END()
593 : device1DummyBackend(boost::dynamic_pointer_cast<
ctk::ExceptionDummy>(
595 device2DummyBackend(boost::dynamic_pointer_cast<
ctk::ExceptionDummy>(
597 device1Status.replace(test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
599 device2Status.replace(test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
602 device1DummyBackend->open();
603 device2DummyBackend->open();
610 static const int DEFAULT = 1234567;
611 test.setScalarDefault(
"m1/o1", DEFAULT);
613 test.runApplication();
618 auto m1o1 = device1DummyBackend->getRegisterAccessor<
int>(
"m1/o1", 1, 0, {});
623 device1DummyBackend->throwExceptionRead =
false;
624 device2DummyBackend->throwExceptionWrite =
false;
637 BOOST_AUTO_TEST_SUITE(data_validity_propagation_noTestFacility)
640 std::cout <<
"testDeviceReadFailure" << std::endl;
643 auto consumingFanoutSource =
648 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
649 auto result = test.getScalar<
int>(
"m1/Module1_result");
651 threadedFanoutInput = 10000;
652 consumingFanoutSource = 1000;
653 consumingFanoutSource.write();
655 pollRegister.write();
659 threadedFanoutInput.write();
661 CHECK_TIMEOUT((result.readLatest(), result == 11001), 10000);
662 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
666 threadedFanoutInput = 20000;
668 pollRegister.write();
670 device2DummyBackend->throwExceptionRead =
true;
672 threadedFanoutInput.write();
676 BOOST_CHECK_EQUAL(result, 21001);
677 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
684 threadedFanoutInput = 30000;
685 threadedFanoutInput.write();
688 BOOST_CHECK_EQUAL(result, 31001);
689 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
694 device2DummyBackend->throwExceptionRead =
false;
697 threadedFanoutInput = 40000;
698 threadedFanoutInput.write();
702 BOOST_CHECK_EQUAL(result, 41000);
703 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
709 std::cout <<
"testReadDeviceWithTrigger" << std::endl;
712 auto trigger = test.getVoid(
"trigger");
713 auto fromDevice = test.getScalar<
int>(
"/m1/i3");
716 BOOST_CHECK_EQUAL(fromDevice, 0);
718 auto deviceRegister =
721 deviceRegister.write();
727 BOOST_CHECK_EQUAL(fromDevice, 30);
728 BOOST_CHECK(fromDevice.dataValidity() == ctk::DataValidity::ok);
733 deviceRegister.write();
735 device1DummyBackend->throwExceptionRead =
true;
740 BOOST_CHECK_EQUAL(fromDevice, 30);
741 BOOST_CHECK(fromDevice.dataValidity() == ctk::DataValidity::faulty);
744 device1DummyBackend->throwExceptionRead =
false;
748 while((
void)device1Status.read(), device1Status == 1) {
755 BOOST_CHECK_EQUAL(fromDevice, 10);
756 BOOST_CHECK(fromDevice.dataValidity() == ctk::DataValidity::ok);
762 std::cout <<
"testConsumingFanout" << std::endl;
765 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
766 auto fromConsumingFanout = test.getScalar<
int>(
"m1/i1");
767 auto result = test.getScalar<
int>(
"m1/Module1_result");
768 fromConsumingFanout.read();
771 auto pollRegisterSource =
773 pollRegisterSource = 100;
774 pollRegisterSource.write();
776 threadedFanoutInput = 10;
778 auto consumingFanoutSource =
780 consumingFanoutSource = 1;
781 consumingFanoutSource.write();
785 threadedFanoutInput.write();
788 BOOST_CHECK_EQUAL(result, 111);
789 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
791 fromConsumingFanout.read();
792 BOOST_CHECK_EQUAL(fromConsumingFanout, 1);
793 BOOST_CHECK(fromConsumingFanout.dataValidity() == ctk::DataValidity::ok);
797 consumingFanoutSource = 0;
798 consumingFanoutSource.write();
800 device1DummyBackend->throwExceptionRead =
true;
801 threadedFanoutInput = 20;
802 threadedFanoutInput.write();
805 BOOST_CHECK_EQUAL(result, 121);
806 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
809 BOOST_CHECK_EQUAL(fromConsumingFanout, 1);
810 BOOST_CHECK(fromConsumingFanout.dataValidity() == ctk::DataValidity::faulty);
814 device1DummyBackend->throwExceptionRead =
false;
818 while((
void)device1Status.read(), device1Status == 1) {
822 threadedFanoutInput = 30;
823 threadedFanoutInput.write();
826 BOOST_CHECK_EQUAL(result, 130);
827 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
830 BOOST_CHECK_EQUAL(fromConsumingFanout, 0);
831 BOOST_CHECK(fromConsumingFanout.dataValidity() == ctk::DataValidity::ok);
837 std::cout <<
"testDataFlowOnDeviceException" << std::endl;
839 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
840 auto m1_result = test.getScalar<
int>(
"m1/Module1_result");
841 auto m2_result = test.getScalar<
int>(
"m2/Module2_result");
843 auto consumingFanoutSource = ctk::ScalarRegisterAccessor<int>(
844 device1DummyBackend->getRegisterAccessor<
int>(
"/m1/i1.DUMMY_WRITEABLE", 0, 0, {}));
845 consumingFanoutSource = 1000;
846 consumingFanoutSource.write();
848 auto pollRegister = ctk::ScalarRegisterAccessor<int>(
849 device2DummyBackend->getRegisterAccessor<
int>(
"/m1/i2.DUMMY_WRITEABLE", 0, 0, {}));
851 pollRegister.write();
859 threadedFanoutInput = 1;
863 threadedFanoutInput.write();
866 BOOST_CHECK_EQUAL(m1_result, 1101);
867 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
870 BOOST_CHECK_EQUAL(m2_result, 1101);
871 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
875 threadedFanoutInput.setDataValidity(ctk::DataValidity::faulty);
876 threadedFanoutInput.write();
879 BOOST_CHECK_EQUAL(m1_result, 1101);
880 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
883 BOOST_CHECK_EQUAL(m2_result, 1101);
884 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
886 auto deviceStatus = test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
893 device2DummyBackend->throwExceptionRead =
true;
895 pollRegister.write();
896 threadedFanoutInput = 0;
897 threadedFanoutInput.write();
905 BOOST_CHECK_EQUAL(m1_result, 1100);
906 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
909 BOOST_CHECK_EQUAL(m2_result, 1100);
910 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
914 device2DummyBackend->throwExceptionRead =
false;
918 BOOST_CHECK(deviceStatus == 0);
920 BOOST_CHECK(deviceStatus.readNonBlocking() ==
false);
925 pollRegister.write();
926 threadedFanoutInput = 2;
927 threadedFanoutInput.write();
930 BOOST_CHECK_EQUAL(m1_result, 1302);
932 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
934 BOOST_CHECK(m1_result.readNonBlocking() ==
false);
938 BOOST_CHECK_EQUAL(m2_result, 1302);
939 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
940 BOOST_CHECK(m2_result.readNonBlocking() ==
false);
944 threadedFanoutInput = 3;
945 threadedFanoutInput.setDataValidity(ctk::DataValidity::ok);
946 threadedFanoutInput.write();
949 BOOST_CHECK_EQUAL(m1_result, 1303);
950 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
951 BOOST_CHECK(m1_result.readNonBlocking() ==
false);
954 BOOST_CHECK_EQUAL(m2_result, 1303);
955 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
956 BOOST_CHECK(m1_result.readNonBlocking() ==
false);
959 BOOST_AUTO_TEST_SUITE_END()
966 using ctk::ApplicationModule::ApplicationModule;
974 result = pushTypeInputFromCS + pollInputFromDevice;
1003 std::cout <<
"testDataValidPropagationOnException" << std::endl;
1005 boost::shared_ptr<ctk::ExceptionDummy> device2DummyBackend(boost::dynamic_pointer_cast<ctk::ExceptionDummy>(
1012 auto pollRegister = device2.getScalarRegisterAccessor<
int>(
"/m1/i2.DUMMY_WRITEABLE");
1015 pollRegister.write();
1018 test.runApplication();
1020 auto pushInput = test.getScalar<
int>(
"module/o1");
1021 auto result = test.getScalar<
int>(
"module/Module3_result");
1023 auto deviceStatus = test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
1030 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
1035 pollRegister.write();
1037 pushInput.setDataValidity(ctk::DataValidity::faulty);
1038 device2DummyBackend->throwExceptionRead =
true;
1043 BOOST_CHECK(result.readLatest() ==
false);
1046 BOOST_CHECK_EQUAL(result, 21);
1047 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1053 pushInput.setDataValidity(ctk::DataValidity::ok);
1056 BOOST_CHECK_EQUAL(result, 31);
1057 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1060 device2DummyBackend->throwExceptionRead =
false;
1067 pollRegister.write();
1070 BOOST_CHECK_EQUAL(result, 43);
1071 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
1073 BOOST_CHECK(result.readLatest() ==
false);
1078 pollRegister.write();
1080 device2DummyBackend->throwExceptionRead =
true;
1084 BOOST_CHECK(result.readLatest() ==
false);
1086 BOOST_CHECK_EQUAL(result, 53);
1087 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1094 pushInput.setDataValidity(ctk::DataValidity::faulty);
1097 BOOST_CHECK_EQUAL(result, 63);
1098 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1101 device2DummyBackend->throwExceptionRead =
false;
1108 pollRegister.write();
1111 BOOST_CHECK_EQUAL(result, 75);
1112 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1116 pushInput.setDataValidity(ctk::DataValidity::ok);
1118 pollRegister.write();
1121 BOOST_CHECK_EQUAL(result, 86);
1122 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
1124 BOOST_CHECK(result.readLatest() ==
false);
1130 using ctk::ApplicationModule::ApplicationModule;
1148 std::cout <<
"testWriteIfDifferent" << std::endl;
1153 auto o1 = test.getScalar<
int>(
"/A/o1");
1154 auto o2 = test.getArray<
int>(
"/A/o2");
1156 test.runApplication();
1161 BOOST_TEST(o1.readLatest());
1162 BOOST_TEST(o1.dataValidity() == ctk::DataValidity::ok);
1163 BOOST_TEST(
int(o1) == 42);
1165 app.
a.
o2 = {48, 59};
1167 BOOST_TEST(o2.readLatest());
1168 BOOST_TEST(o2.dataValidity() == ctk::DataValidity::ok);
1169 BOOST_TEST(std::vector<int>(o2) == std::vector<int>({48, 59}));
1174 BOOST_TEST(o1.readNonBlocking());
1175 BOOST_TEST(o1.dataValidity() == ctk::DataValidity::faulty);
1176 BOOST_TEST(
int(o1) == 42);
1180 BOOST_TEST(o2.readNonBlocking());
1181 BOOST_TEST(o2.dataValidity() == ctk::DataValidity::faulty);
1182 BOOST_TEST(std::vector<int>(o2) == std::vector<int>({48, 59}));
1187 BOOST_TEST(o1.readNonBlocking());
1188 BOOST_TEST(o1.dataValidity() == ctk::DataValidity::ok);
1189 BOOST_TEST(
int(o1) == 42);
1192 BOOST_TEST(o2.readNonBlocking());
1193 BOOST_TEST(o2.dataValidity() == ctk::DataValidity::ok);
1194 BOOST_TEST(std::vector<int>(o2) == std::vector<int>({48, 59}));
#define CHECK_EQUAL_TIMEOUT(left, right, maxMilliseconds)
void debugMakeConnections()
Enable debug output for the ConnectionMaker.
void shutdown() override
This will remove the global pointer to the instance and allows creating another instance afterwards.
void decrementDataFaultCounter() override
Decrement the fault counter and set the data validity flag to ok if the counter has reached 0.
void incrementDataFaultCounter() override
Set the data validity flag to fault and increment the fault counter.
void writeIfDifferent(const std::vector< UserType > &newValue, VersionNumber versionNumber, DataValidity validity)=delete
bool write(ChimeraTK::VersionNumber versionNumber)=delete
void readAll(bool includeReturnChannels=false)
Read all readable variables in the group.
ChimeraTK::ReadAnyGroup readAnyGroup()
Create a ChimeraTK::ReadAnyGroup for all readable variables in this Module.
void writeAll(bool includeReturnChannels=false)
Just call write() on all writable variables in the group.
bool write(ChimeraTK::VersionNumber versionNumber)=delete
void writeIfDifferent(UserType newValue, VersionNumber versionNumber, DataValidity validity)=delete
Helper class to facilitate tests of applications based on ApplicationCore.
ChimeraTK::OneDRegisterAccessor< T > getArray(const ChimeraTK::RegisterPath &name) const
Obtain an array-type process variable from the application, which is published to the control system.
void stepApplication(bool waitForDeviceInitialisation=true) const
Perform a "step" of the application.
ChimeraTK::ScalarRegisterAccessor< T > getScalar(const ChimeraTK::RegisterPath &name) const
Obtain a scalar process variable from the application, which is published to the control system.
void runApplication() const
Start the application in testable mode.
std::string escapeName(const std::string &name, bool allowDotsAndSlashes)
Convert all characters which are not allowed in variable or module names into underscores followed by...
InvalidityTracer application module.
BOOST_AUTO_TEST_CASE(testDirectConnections)
BOOST_FIXTURE_TEST_CASE(testDeviceReadFailure, FixtureNoTestableMode)
Convenience class for output array accessors (always UpdateMode::push)
Convenience class for output scalar accessors (always UpdateMode::push)
Special ScalarOutput which represents a status which can be aggregated by the StatusAggregator.
ChimeraTK::ScalarRegisterAccessor< int > device1Status
boost::shared_ptr< ctk::ExceptionDummy > device1DummyBackend
ChimeraTK::ScalarRegisterAccessor< int > device2Status
boost::shared_ptr< ctk::ExceptionDummy > device2DummyBackend
boost::shared_ptr< ctk::ExceptionDummy > device2DummyBackend
boost::shared_ptr< ctk::ExceptionDummy > device1DummyBackend
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
ctk::ScalarPollInput< int > fromConsumingFanout
ctk::ScalarPollInput< int > fromDevice
ctk::ScalarPushInput< int > fromThreadedFanout
ctk::ScalarOutput< int > result
ctk::ScalarPushInput< int > result
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
~TestApplication1() override
~TestApplication2() override
static constexpr char const * ExceptionDummyCDD2
~TestApplication3() override
static constexpr char const * ExceptionDummyCDD1
ctk::DeviceModule device2
ctk::DeviceModule device1
~TestApplication4() override
ctk::DeviceModule device2
static constexpr char const * ExceptionDummyCDD2
~TestApplication5() override
ctk::ScalarOutput< int > o1
ctk::ArrayPushInput< int > i2
ctk::ScalarPushInputWB< int > i3
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
ctk::ScalarPushInput< int > i1
ctk::ArrayOutput< int > o2
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
ctk::ScalarPushInput< int > o1
ctk::ArrayPushInput< int > o2
ctk::ScalarPushInputWB< int > i3
ctk::ScalarPushInput< int > i1
ctk::ArrayPushInput< int > i2
ctk::ScalarOutput< int > o1
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
ctk::ArrayOutput< int > o2
#define CHECK_TIMEOUT(condition, maxMilliseconds)