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;
113 auto i2 = test.
getArray<
int>(
"/t1/i2");
116 auto o2 = test.
getArray<
int>(
"/t1/o2");
117 auto oStat = test.
getArray<
int>(
"/t1/oStat");
123 i1.setDataValidity(ctk::DataValidity::faulty);
129 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
130 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
131 BOOST_CHECK(oStat.dataValidity() == ctk::DataValidity::faulty);
132 BOOST_CHECK_EQUAL(
int(o1), 1);
133 BOOST_CHECK_EQUAL(o2[0], 0);
134 BOOST_CHECK_EQUAL(o2[1], 0);
138 BOOST_CHECK(i1.dataValidity() == ctk::DataValidity::faulty);
143 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
144 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
145 BOOST_CHECK_EQUAL(
int(o1), 42);
146 BOOST_CHECK_EQUAL(o2[0], 0);
147 BOOST_CHECK_EQUAL(o2[1], 0);
152 BOOST_CHECK(i2.dataValidity() == ctk::DataValidity::ok);
157 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
158 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
159 BOOST_CHECK_EQUAL(
int(o1), 42);
160 BOOST_CHECK_EQUAL(o2[0], 10);
161 BOOST_CHECK_EQUAL(o2[1], 11);
164 BOOST_CHECK(i3.readNonBlocking() ==
false);
165 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
172 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
173 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
174 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
175 BOOST_CHECK_EQUAL(
int(o1), 42);
176 BOOST_CHECK_EQUAL(o2[0], 10);
177 BOOST_CHECK_EQUAL(o2[1], 11);
178 BOOST_CHECK_EQUAL(
int(i3), 10);
182 i1.setDataValidity(ctk::DataValidity::ok);
187 BOOST_CHECK(i3.readNonBlocking() ==
false);
188 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::ok);
189 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::ok);
190 BOOST_CHECK_EQUAL(
int(o1), 3);
191 BOOST_CHECK_EQUAL(o2[0], 10);
192 BOOST_CHECK_EQUAL(o2[1], 11);
193 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
194 BOOST_CHECK_EQUAL(
int(i3), 10);
198 i1.setDataValidity(ctk::DataValidity::faulty);
201 i3.setDataValidity(ctk::DataValidity::faulty);
207 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
208 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
209 BOOST_CHECK_EQUAL(
int(o1), 120);
210 BOOST_CHECK_EQUAL(o2[0], 10);
211 BOOST_CHECK_EQUAL(o2[1], 11);
212 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::faulty);
213 BOOST_CHECK_EQUAL(
int(i3), 10);
217 i1.setDataValidity(ctk::DataValidity::ok);
222 BOOST_CHECK(i3.readNonBlocking() ==
false);
223 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::faulty);
224 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::faulty);
225 BOOST_CHECK_EQUAL(
int(o1), 122);
226 BOOST_CHECK_EQUAL(o2[0], 10);
227 BOOST_CHECK_EQUAL(o2[1], 11);
228 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::faulty);
229 BOOST_CHECK_EQUAL(
int(i3), 10);
233 i3.setDataValidity(ctk::DataValidity::ok);
239 BOOST_CHECK(o1.dataValidity() == ctk::DataValidity::ok);
240 BOOST_CHECK(o2.dataValidity() == ctk::DataValidity::ok);
241 BOOST_CHECK_EQUAL(
int(o1), 122);
242 BOOST_CHECK_EQUAL(o2[0], 10);
243 BOOST_CHECK_EQUAL(o2[1], 11);
244 BOOST_CHECK(i3.dataValidity() == ctk::DataValidity::ok);
245 BOOST_CHECK_EQUAL(
int(i3), 10);
252 BOOST_CHECK(oStat.dataValidity() == ctk::DataValidity::faulty);
258 std::cout <<
"testWithFanOut" << std::endl;
263 auto Ai2 = test.
getArray<
int>(
"A/i2");
266 auto Ao2 = test.
getArray<
int>(
"A/o2");
274 Ai1.setDataValidity(ctk::DataValidity::faulty);
279 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::faulty);
280 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::faulty);
281 BOOST_CHECK_EQUAL(
int(Ao1), 1);
282 BOOST_CHECK_EQUAL(Ao2[0], 0);
283 BOOST_CHECK_EQUAL(Ao2[1], 0);
284 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::faulty);
285 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::faulty);
286 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 1);
287 BOOST_CHECK_EQUAL(app.
b.
o2[0], 0);
288 BOOST_CHECK_EQUAL(app.
b.
o2[1], 0);
289 BOOST_CHECK(app.
b.
i1.dataValidity() == ctk::DataValidity::faulty);
290 BOOST_CHECK_EQUAL(
int(app.
b.
i1), 1);
295 Ai2.setDataValidity(ctk::DataValidity::faulty);
300 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::faulty);
301 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::faulty);
302 BOOST_CHECK_EQUAL(
int(Ao1), 1);
303 BOOST_CHECK_EQUAL(Ao2[0], 2);
304 BOOST_CHECK_EQUAL(Ao2[1], 3);
305 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::faulty);
306 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::faulty);
307 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 1);
308 BOOST_CHECK_EQUAL(app.
b.
o2[0], 2);
309 BOOST_CHECK_EQUAL(app.
b.
o2[1], 3);
310 BOOST_CHECK(app.
b.
i2.dataValidity() == ctk::DataValidity::faulty);
311 BOOST_CHECK_EQUAL(app.
b.
i2[0], 2);
312 BOOST_CHECK_EQUAL(app.
b.
i2[1], 3);
317 Ai2.setDataValidity(ctk::DataValidity::ok);
322 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::faulty);
323 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::faulty);
324 BOOST_CHECK_EQUAL(
int(Ao1), 1);
325 BOOST_CHECK_EQUAL(Ao2[0], 4);
326 BOOST_CHECK_EQUAL(Ao2[1], 5);
327 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::faulty);
328 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::faulty);
329 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 1);
330 BOOST_CHECK_EQUAL(app.
b.
o2[0], 4);
331 BOOST_CHECK_EQUAL(app.
b.
o2[1], 5);
332 BOOST_CHECK(app.
b.
i2.dataValidity() == ctk::DataValidity::ok);
333 BOOST_CHECK_EQUAL(app.
b.
i2[0], 4);
334 BOOST_CHECK_EQUAL(app.
b.
i2[1], 5);
338 Ai1.setDataValidity(ctk::DataValidity::ok);
343 BOOST_CHECK(Ao1.dataValidity() == ctk::DataValidity::ok);
344 BOOST_CHECK(Ao2.dataValidity() == ctk::DataValidity::ok);
345 BOOST_CHECK_EQUAL(
int(Ao1), 6);
346 BOOST_CHECK_EQUAL(Ao2[0], 4);
347 BOOST_CHECK_EQUAL(Ao2[1], 5);
348 BOOST_CHECK(app.
b.
o1.dataValidity() == ctk::DataValidity::ok);
349 BOOST_CHECK(app.
b.
o2.dataValidity() == ctk::DataValidity::ok);
350 BOOST_CHECK_EQUAL(
int(app.
b.
o1), 6);
351 BOOST_CHECK_EQUAL(app.
b.
o2[0], 4);
352 BOOST_CHECK_EQUAL(app.
b.
o2[1], 5);
353 BOOST_CHECK(app.
b.
i1.dataValidity() == ctk::DataValidity::ok);
354 BOOST_CHECK_EQUAL(
int(app.
b.
i1), 6);
367 using ctk::ApplicationModule::ApplicationModule;
388 using ctk::ApplicationModule::ApplicationModule;
391 using ctk::VariableGroup::VariableGroup;
393 } m1VarsFromCS{
this,
"../m1",
""};
399 result =
static_cast<int>(m1VarsFromCS.result);
476 BOOST_FIXTURE_TEST_SUITE(data_validity_propagation, FixtureTestFacility)
481 std::cout <<
"testThreadedFanout" << std::endl;
482 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
483 auto m1_result = test.getScalar<
int>(
"m1/Module1_result");
484 auto m2_result = test.getScalar<
int>(
"m2/Module2_result");
486 threadedFanoutInput = 20;
487 threadedFanoutInput.write();
489 auto consumingFanoutSource =
491 consumingFanoutSource = 10;
492 consumingFanoutSource.write();
497 pollRegister.write();
499 test.stepApplication();
503 BOOST_CHECK_EQUAL(m1_result, 35);
504 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
506 BOOST_CHECK_EQUAL(m2_result, 35);
507 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
509 threadedFanoutInput = 10;
510 threadedFanoutInput.setDataValidity(ctk::DataValidity::faulty);
511 threadedFanoutInput.write();
512 test.stepApplication();
516 BOOST_CHECK_EQUAL(m1_result, 25);
517 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
518 BOOST_CHECK_EQUAL(m2_result, 25);
519 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
521 threadedFanoutInput = 40;
522 threadedFanoutInput.setDataValidity(ctk::DataValidity::ok);
523 threadedFanoutInput.write();
524 test.stepApplication();
528 BOOST_CHECK_EQUAL(m1_result, 55);
529 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
530 BOOST_CHECK_EQUAL(m2_result, 55);
531 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
537 std::cout <<
"testInvalidTrigger" << std::endl;
539 auto deviceRegister =
542 deviceRegister.write();
544 auto trigger = test.getVoid(
"trigger");
545 auto result = test.getScalar<
int>(
"/m1/i3");
551 test.stepApplication();
554 BOOST_CHECK_EQUAL(result, 20);
555 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
560 deviceRegister.write();
561 trigger.setDataValidity(ctk::DataValidity::faulty);
564 test.stepApplication();
567 BOOST_CHECK_EQUAL(result, 30);
568 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
573 deviceRegister.write();
575 trigger.setDataValidity(ctk::DataValidity::ok);
578 test.stepApplication();
581 BOOST_CHECK_EQUAL(result, 50);
582 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
585 BOOST_AUTO_TEST_SUITE_END()
592 : device1DummyBackend(boost::dynamic_pointer_cast<
ctk::ExceptionDummy>(
594 device2DummyBackend(boost::dynamic_pointer_cast<
ctk::ExceptionDummy>(
596 device1Status.replace(test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
598 device2Status.replace(test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
601 device1DummyBackend->open();
602 device2DummyBackend->open();
609 static const int DEFAULT = 1234567;
610 test.setScalarDefault(
"m1/o1", DEFAULT);
612 test.runApplication();
617 auto m1o1 = device1DummyBackend->getRegisterAccessor<
int>(
"m1/o1", 1, 0, {});
622 device1DummyBackend->throwExceptionRead =
false;
623 device2DummyBackend->throwExceptionWrite =
false;
636 BOOST_AUTO_TEST_SUITE(data_validity_propagation_noTestFacility)
639 std::cout <<
"testDeviceReadFailure" << std::endl;
642 auto consumingFanoutSource =
647 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
648 auto result = test.getScalar<
int>(
"m1/Module1_result");
650 threadedFanoutInput = 10000;
651 consumingFanoutSource = 1000;
652 consumingFanoutSource.write();
654 pollRegister.write();
658 threadedFanoutInput.write();
660 CHECK_TIMEOUT((result.readLatest(), result == 11001), 10000);
661 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
665 threadedFanoutInput = 20000;
667 pollRegister.write();
669 device2DummyBackend->throwExceptionRead =
true;
671 threadedFanoutInput.write();
675 BOOST_CHECK_EQUAL(result, 21001);
676 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
683 threadedFanoutInput = 30000;
684 threadedFanoutInput.write();
687 BOOST_CHECK_EQUAL(result, 31001);
688 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
693 device2DummyBackend->throwExceptionRead =
false;
696 threadedFanoutInput = 40000;
697 threadedFanoutInput.write();
701 BOOST_CHECK_EQUAL(result, 41000);
702 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
708 std::cout <<
"testReadDeviceWithTrigger" << std::endl;
711 auto trigger = test.getVoid(
"trigger");
712 auto fromDevice = test.getScalar<
int>(
"/m1/i3");
715 BOOST_CHECK_EQUAL(fromDevice, 0);
717 auto deviceRegister =
720 deviceRegister.write();
726 BOOST_CHECK_EQUAL(fromDevice, 30);
727 BOOST_CHECK(fromDevice.dataValidity() == ctk::DataValidity::ok);
732 deviceRegister.write();
734 device1DummyBackend->throwExceptionRead =
true;
739 BOOST_CHECK_EQUAL(fromDevice, 30);
740 BOOST_CHECK(fromDevice.dataValidity() == ctk::DataValidity::faulty);
743 device1DummyBackend->throwExceptionRead =
false;
747 while((
void)device1Status.read(), device1Status == 1) {
754 BOOST_CHECK_EQUAL(fromDevice, 10);
755 BOOST_CHECK(fromDevice.dataValidity() == ctk::DataValidity::ok);
761 std::cout <<
"testConsumingFanout" << std::endl;
764 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
765 auto fromConsumingFanout = test.getScalar<
int>(
"m1/i1");
766 auto result = test.getScalar<
int>(
"m1/Module1_result");
767 fromConsumingFanout.read();
770 auto pollRegisterSource =
772 pollRegisterSource = 100;
773 pollRegisterSource.write();
775 threadedFanoutInput = 10;
777 auto consumingFanoutSource =
779 consumingFanoutSource = 1;
780 consumingFanoutSource.write();
784 threadedFanoutInput.write();
787 BOOST_CHECK_EQUAL(result, 111);
788 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
790 fromConsumingFanout.read();
791 BOOST_CHECK_EQUAL(fromConsumingFanout, 1);
792 BOOST_CHECK(fromConsumingFanout.dataValidity() == ctk::DataValidity::ok);
796 consumingFanoutSource = 0;
797 consumingFanoutSource.write();
799 device1DummyBackend->throwExceptionRead =
true;
800 threadedFanoutInput = 20;
801 threadedFanoutInput.write();
804 BOOST_CHECK_EQUAL(result, 121);
805 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
808 BOOST_CHECK_EQUAL(fromConsumingFanout, 1);
809 BOOST_CHECK(fromConsumingFanout.dataValidity() == ctk::DataValidity::faulty);
813 device1DummyBackend->throwExceptionRead =
false;
817 while((
void)device1Status.read(), device1Status == 1) {
821 threadedFanoutInput = 30;
822 threadedFanoutInput.write();
825 BOOST_CHECK_EQUAL(result, 130);
826 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
829 BOOST_CHECK_EQUAL(fromConsumingFanout, 0);
830 BOOST_CHECK(fromConsumingFanout.dataValidity() == ctk::DataValidity::ok);
836 std::cout <<
"testDataFlowOnDeviceException" << std::endl;
838 auto threadedFanoutInput = test.getScalar<
int>(
"m1/o1");
839 auto m1_result = test.getScalar<
int>(
"m1/Module1_result");
840 auto m2_result = test.getScalar<
int>(
"m2/Module2_result");
842 auto consumingFanoutSource = ctk::ScalarRegisterAccessor<int>(
843 device1DummyBackend->getRegisterAccessor<
int>(
"/m1/i1.DUMMY_WRITEABLE", 0, 0, {}));
844 consumingFanoutSource = 1000;
845 consumingFanoutSource.write();
847 auto pollRegister = ctk::ScalarRegisterAccessor<int>(
848 device2DummyBackend->getRegisterAccessor<
int>(
"/m1/i2.DUMMY_WRITEABLE", 0, 0, {}));
850 pollRegister.write();
858 threadedFanoutInput = 1;
862 threadedFanoutInput.write();
865 BOOST_CHECK_EQUAL(m1_result, 1101);
866 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
869 BOOST_CHECK_EQUAL(m2_result, 1101);
870 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
874 threadedFanoutInput.setDataValidity(ctk::DataValidity::faulty);
875 threadedFanoutInput.write();
878 BOOST_CHECK_EQUAL(m1_result, 1101);
879 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
882 BOOST_CHECK_EQUAL(m2_result, 1101);
883 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
885 auto deviceStatus = test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
892 device2DummyBackend->throwExceptionRead =
true;
894 pollRegister.write();
895 threadedFanoutInput = 0;
896 threadedFanoutInput.write();
904 BOOST_CHECK_EQUAL(m1_result, 1100);
905 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
908 BOOST_CHECK_EQUAL(m2_result, 1100);
909 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
913 device2DummyBackend->throwExceptionRead =
false;
917 BOOST_CHECK(deviceStatus == 0);
919 BOOST_CHECK(deviceStatus.readNonBlocking() ==
false);
924 pollRegister.write();
925 threadedFanoutInput = 2;
926 threadedFanoutInput.write();
929 BOOST_CHECK_EQUAL(m1_result, 1302);
931 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
933 BOOST_CHECK(m1_result.readNonBlocking() ==
false);
937 BOOST_CHECK_EQUAL(m2_result, 1302);
938 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
939 BOOST_CHECK(m2_result.readNonBlocking() ==
false);
943 threadedFanoutInput = 3;
944 threadedFanoutInput.setDataValidity(ctk::DataValidity::ok);
945 threadedFanoutInput.write();
948 BOOST_CHECK_EQUAL(m1_result, 1303);
949 BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
950 BOOST_CHECK(m1_result.readNonBlocking() ==
false);
953 BOOST_CHECK_EQUAL(m2_result, 1303);
954 BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
955 BOOST_CHECK(m1_result.readNonBlocking() ==
false);
958 BOOST_AUTO_TEST_SUITE_END()
965 using ctk::ApplicationModule::ApplicationModule;
973 result = pushTypeInputFromCS + pollInputFromDevice;
1002 std::cout <<
"testDataValidPropagationOnException" << std::endl;
1004 boost::shared_ptr<ctk::ExceptionDummy> device2DummyBackend(boost::dynamic_pointer_cast<ctk::ExceptionDummy>(
1011 auto pollRegister = device2.getScalarRegisterAccessor<
int>(
"/m1/i2.DUMMY_WRITEABLE");
1014 pollRegister.write();
1017 test.runApplication();
1019 auto pushInput = test.getScalar<
int>(
"module/o1");
1020 auto result = test.getScalar<
int>(
"module/Module3_result");
1022 auto deviceStatus = test.getScalar<int32_t>(ctk::RegisterPath(
"/Devices") /
1029 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
1034 pollRegister.write();
1036 pushInput.setDataValidity(ctk::DataValidity::faulty);
1037 device2DummyBackend->throwExceptionRead =
true;
1042 BOOST_CHECK(result.readLatest() ==
false);
1045 BOOST_CHECK_EQUAL(result, 21);
1046 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1052 pushInput.setDataValidity(ctk::DataValidity::ok);
1055 BOOST_CHECK_EQUAL(result, 31);
1056 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1059 device2DummyBackend->throwExceptionRead =
false;
1066 pollRegister.write();
1069 BOOST_CHECK_EQUAL(result, 43);
1070 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
1072 BOOST_CHECK(result.readLatest() ==
false);
1077 pollRegister.write();
1079 device2DummyBackend->throwExceptionRead =
true;
1083 BOOST_CHECK(result.readLatest() ==
false);
1085 BOOST_CHECK_EQUAL(result, 53);
1086 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1093 pushInput.setDataValidity(ctk::DataValidity::faulty);
1096 BOOST_CHECK_EQUAL(result, 63);
1097 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1100 device2DummyBackend->throwExceptionRead =
false;
1107 pollRegister.write();
1110 BOOST_CHECK_EQUAL(result, 75);
1111 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
1115 pushInput.setDataValidity(ctk::DataValidity::ok);
1117 pollRegister.write();
1120 BOOST_CHECK_EQUAL(result, 86);
1121 BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
1123 BOOST_CHECK(result.readLatest() ==
false);
1129 using ctk::ApplicationModule::ApplicationModule;
1147 std::cout <<
"testWriteIfDifferent" << std::endl;
1152 auto o1 = test.getScalar<
int>(
"/A/o1");
1153 auto o2 = test.getArray<
int>(
"/A/o2");
1155 test.runApplication();
1160 BOOST_TEST(o1.readLatest());
1161 BOOST_TEST(o1.dataValidity() == ctk::DataValidity::ok);
1162 BOOST_TEST(
int(o1) == 42);
1164 app.
a.
o2 = {48, 59};
1166 BOOST_TEST(o2.readLatest());
1167 BOOST_TEST(o2.dataValidity() == ctk::DataValidity::ok);
1168 BOOST_TEST(std::vector<int>(o2) == std::vector<int>({48, 59}));
1173 BOOST_TEST(o1.readNonBlocking());
1174 BOOST_TEST(o1.dataValidity() == ctk::DataValidity::faulty);
1175 BOOST_TEST(
int(o1) == 42);
1179 BOOST_TEST(o2.readNonBlocking());
1180 BOOST_TEST(o2.dataValidity() == ctk::DataValidity::faulty);
1181 BOOST_TEST(std::vector<int>(o2) == std::vector<int>({48, 59}));
1186 BOOST_TEST(o1.readNonBlocking());
1187 BOOST_TEST(o1.dataValidity() == ctk::DataValidity::ok);
1188 BOOST_TEST(
int(o1) == 42);
1191 BOOST_TEST(o2.readNonBlocking());
1192 BOOST_TEST(o2.dataValidity() == ctk::DataValidity::ok);
1193 BOOST_TEST(std::vector<int>(o2) == std::vector<int>({48, 59}));
#define CHECK_EQUAL_TIMEOUT(left, right, maxMilliseconds)
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
Convenience class for output array accessors (always UpdateMode::push)
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
Convenience class for output scalar accessors (always UpdateMode::push)
Special ScalarOutput which represents a status which can be aggregated by the StatusAggregator.
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)
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)