Skip to content
Snippets Groups Projects
Commit d55d6000 authored by Christoph Kampmeyer's avatar Christoph Kampmeyer
Browse files

Merge branch 'wip/ckampm/wip-fix-compatibility-da'

parents 47754c98 cc5797a0
No related branches found
No related tags found
No related merge requests found
...@@ -557,6 +557,9 @@ struct Fixture_noTestableMode { ...@@ -557,6 +557,9 @@ struct Fixture_noTestableMode {
ChimeraTK::BackendFactory::getInstance().createBackend(TestApplication3::ExceptionDummyCDD1))), ChimeraTK::BackendFactory::getInstance().createBackend(TestApplication3::ExceptionDummyCDD1))),
device2DummyBackend(boost::dynamic_pointer_cast<ctk::ExceptionDummy>( device2DummyBackend(boost::dynamic_pointer_cast<ctk::ExceptionDummy>(
ChimeraTK::BackendFactory::getInstance().createBackend(TestApplication3::ExceptionDummyCDD2))) { ChimeraTK::BackendFactory::getInstance().createBackend(TestApplication3::ExceptionDummyCDD2))) {
auto device1Status =
test.getScalar<int32_t>(ctk::RegisterPath("/Devices") / TestApplication3::ExceptionDummyCDD1 / "status");
device1DummyBackend->open(); device1DummyBackend->open();
device2DummyBackend->open(); device2DummyBackend->open();
...@@ -567,6 +570,7 @@ struct Fixture_noTestableMode { ...@@ -567,6 +570,7 @@ struct Fixture_noTestableMode {
test.setScalarDefault("m1/o1", DEFAULT); test.setScalarDefault("m1/o1", DEFAULT);
test.runApplication(); test.runApplication();
CHECK_EQUAL_TIMEOUT((device1Status.readLatest(), device1Status), 0, 100000);
// Making sure the default is written to the device before proceeding. // Making sure the default is written to the device before proceeding.
auto m1o1 = device1DummyBackend->getRegisterAccessor<int>("m1/o1", 1, 0, false); auto m1o1 = device1DummyBackend->getRegisterAccessor<int>("m1/o1", 1, 0, false);
...@@ -594,6 +598,9 @@ BOOST_AUTO_TEST_CASE(testDeviceReadFailure) { ...@@ -594,6 +598,9 @@ BOOST_AUTO_TEST_CASE(testDeviceReadFailure) {
auto threadedFanoutInput = test.getScalar<int>("m1/o1"); auto threadedFanoutInput = test.getScalar<int>("m1/o1");
auto result = test.getScalar<int>("m1/Module1_result"); auto result = test.getScalar<int>("m1/Module1_result");
auto device2Status =
test.getScalar<int32_t>(ctk::RegisterPath("/Devices") / TestApplication3::ExceptionDummyCDD2 / "status");
threadedFanoutInput = 10000; threadedFanoutInput = 10000;
consumingFanoutSource = 1000; consumingFanoutSource = 1000;
pollRegister = 1; pollRegister = 1;
...@@ -607,29 +614,40 @@ BOOST_AUTO_TEST_CASE(testDeviceReadFailure) { ...@@ -607,29 +614,40 @@ BOOST_AUTO_TEST_CASE(testDeviceReadFailure) {
// -------------------------------------------------------------// // -------------------------------------------------------------//
// device module exception // device module exception
threadedFanoutInput = 20000;
pollRegister = 0; pollRegister = 0;
device2DummyBackend->throwExceptionRead = true; device2DummyBackend->throwExceptionRead = true;
threadedFanoutInput.write(); threadedFanoutInput.write();
// when the error detected the old value is written with faulty flag // The new value from the fanout input should have been propagated,
// the new value of the poll input is not seen, because it gets skipped
result.read(); result.read();
BOOST_CHECK_EQUAL(result, 11001); BOOST_CHECK_EQUAL(result, 21001);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
// -------------------------------------------------------------// // -------------------------------------------------------------//
threadedFanoutInput = 30000;
threadedFanoutInput.write();
// Further reads to the poll input are skipped
result.read();
BOOST_CHECK_EQUAL(result, 31001);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
// -------------------------------------------------------------//
// recovery from device module exception // recovery from device module exception
device2DummyBackend->throwExceptionRead = false; device2DummyBackend->throwExceptionRead = false;
// When the device recovers, the old value is written with ok flag CHECK_EQUAL_TIMEOUT((device2Status.readLatest(), device2Status), 0, 100000);
// It might be that the main loop does not write the value each time, so it has
// to be done once so the data does not stay invalid.
result.read();
BOOST_CHECK_EQUAL(result, 11001);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
// finally the loop runs though and propagates the new value threadedFanoutInput = 40000;
threadedFanoutInput.write();
result.read(); result.read();
BOOST_CHECK_EQUAL(result, 11000); // Now we expect also the last value written to the pollRegister being
// propagated and the DataValidity should be ok again.
BOOST_CHECK_EQUAL(result, 41000);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
} }
BOOST_AUTO_TEST_CASE(testReadDeviceWithTrigger) { BOOST_AUTO_TEST_CASE(testReadDeviceWithTrigger) {
...@@ -786,26 +804,16 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) { ...@@ -786,26 +804,16 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) {
// Now the device has to go into the error state // Now the device has to go into the error state
CHECK_EQUAL_TIMEOUT((deviceStatus.readLatest(), deviceStatus), 1, 10000); CHECK_EQUAL_TIMEOUT((deviceStatus.readLatest(), deviceStatus), 1, 10000);
// The data is propagated once more to make sure the invaldi flag goes through (in this case it already was invalid, but // The new value of the threadedFanoutInput should be propagated, the
// cannot be nown by the code, see testDataValidPropagationOnException. // pollRegister is skipped, see testDataValidPropagationOnException.
m1_result.read(); m1_result.read();
// FIXME: The correct behaviour according to the new spec is that the new value of threadedFanoutInput is already processed. BOOST_CHECK_EQUAL(m1_result, 1100);
//BOOST_CHECK_EQUAL(m1_result, 1100);
BOOST_CHECK_EQUAL(m1_result, 1101);
BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
m2_result.read(); m2_result.read();
// FIXME: The correct behaviour according to the new spec is that the new value of threadedFanoutInput is already processed. // Same for m2
//BOOST_CHECK_EQUAL(m2_result, 1100); BOOST_CHECK_EQUAL(m2_result, 1100);
BOOST_CHECK_EQUAL(m2_result, 1101);
BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
// Trigger the loop another time. Now the execution is blocked
threadedFanoutInput = 2;
threadedFanoutInput.write();
// The result of m1 must not be written out again. We can't test this at this safely here.
// Instead, we know that the next read after recovery will already contain the new data.
// ---------------------------------------------------------------------// // ---------------------------------------------------------------------//
// device exception recovery // device exception recovery
device2DummyBackend->throwExceptionRead = false; device2DummyBackend->throwExceptionRead = false;
...@@ -816,26 +824,14 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) { ...@@ -816,26 +824,14 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) {
// nothing else in the queue // nothing else in the queue
BOOST_CHECK(deviceStatus.readNonBlocking() == false); BOOST_CHECK(deviceStatus.readNonBlocking() == false);
/////////////////// FIXME: This is old behaviour and will go away with proper implementation of the spec////////////////// // ---------------------------------------------------------------------//
// Now both, threadedFanoutInput and pollRegister should propagate
// After recovering the old data has been written once, still with invalid because the fan input is still invalid pollRegister = 300;
m1_result.read(); threadedFanoutInput = 2;
BOOST_CHECK_EQUAL(m1_result, 1101); threadedFanoutInput.write();
BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
m2_result.read();
BOOST_CHECK_EQUAL(m2_result, 1101);
BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
// Now the data for threadedFanoutInput = 0 is propagated. In the new spec this was already done above
m1_result.read(); m1_result.read();
BOOST_CHECK_EQUAL(m1_result, 1200); BOOST_CHECK_EQUAL(m1_result, 1302);
m2_result.read();
BOOST_CHECK_EQUAL(m2_result, 1200);
/////////////////// END OF FIXME: old behaviour ///////////////////////////////////////////////////
m1_result.read(); // we know there must be exaclty one value being written. Wait for it.
BOOST_CHECK_EQUAL(m1_result, 1202);
// Data validity still faulty because the input from the fan is invalid // Data validity still faulty because the input from the fan is invalid
BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::faulty);
// again, nothing else in the queue // again, nothing else in the queue
...@@ -843,7 +839,7 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) { ...@@ -843,7 +839,7 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) {
// same for m2 // same for m2
m2_result.read(); m2_result.read();
BOOST_CHECK_EQUAL(m2_result, 1202); BOOST_CHECK_EQUAL(m2_result, 1302);
BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::faulty);
BOOST_CHECK(m2_result.readNonBlocking() == false); BOOST_CHECK(m2_result.readNonBlocking() == false);
...@@ -854,12 +850,12 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) { ...@@ -854,12 +850,12 @@ BOOST_AUTO_TEST_CASE(testDataFlowOnDeviceException) {
threadedFanoutInput.write(); threadedFanoutInput.write();
m1_result.read(); m1_result.read();
BOOST_CHECK_EQUAL(m1_result, 1203); BOOST_CHECK_EQUAL(m1_result, 1303);
BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok); BOOST_CHECK(m1_result.dataValidity() == ctk::DataValidity::ok);
BOOST_CHECK(m1_result.readNonBlocking() == false); BOOST_CHECK(m1_result.readNonBlocking() == false);
m2_result.read(); m2_result.read();
BOOST_CHECK_EQUAL(m2_result, 1203); BOOST_CHECK_EQUAL(m2_result, 1303);
BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok); BOOST_CHECK(m2_result.dataValidity() == ctk::DataValidity::ok);
BOOST_CHECK(m1_result.readNonBlocking() == false); BOOST_CHECK(m1_result.readNonBlocking() == false);
} }
...@@ -936,45 +932,80 @@ BOOST_AUTO_TEST_CASE(testDataValidPropagationOnException) { ...@@ -936,45 +932,80 @@ BOOST_AUTO_TEST_CASE(testDataValidPropagationOnException) {
device2DummyBackend->throwExceptionRead = true; device2DummyBackend->throwExceptionRead = true;
pushInput.write(); pushInput.write();
// Output should be rewritten exactly once and the data valditity should be propagated
CHECK_EQUAL_TIMEOUT((deviceStatus.readLatest(), deviceStatus), 1, 10000); CHECK_EQUAL_TIMEOUT((deviceStatus.readLatest(), deviceStatus), 1, 10000);
result.read(); result.read();
BOOST_CHECK(result.readLatest() == false); BOOST_CHECK(result.readLatest() == false);
// FIXME: This is olde behaviour: // The new data from the pushInput and the DataValidity::faulty should have been propagated to the outout,
BOOST_CHECK_EQUAL(result, 11); // the pollRegister should be skipped (Exceptionhandling spec B.2.2.3), so we don't expect the latest assigned value of 2
// According to the new spec the new value for the push input should have been propagated already: BOOST_CHECK_EQUAL(result, 21);
//BOOST_CHECK_EQUAL(result, 21);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
// triggering once more does not produce any output until the device has recovered // Writeing the pushInput should still trigger module execution and
// update the result value. Result validity should still be faulty because
// the device still has the exception
pushInput = 30; pushInput = 30;
pushInput.setDataValidity(ctk::DataValidity::ok); pushInput.setDataValidity(ctk::DataValidity::ok);
pushInput.write(); pushInput.write();
// just a short sleep, waiting for nothing. We will test below that there was nothing when the device recovers result.read();
sleep(1); BOOST_CHECK_EQUAL(result, 31);
BOOST_CHECK(result.readLatest() == false); BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
// let the device recover
device2DummyBackend->throwExceptionRead = false;
CHECK_EQUAL_TIMEOUT((deviceStatus.readLatest(), deviceStatus), 0, 10000);
// Everything should be back to normal, also the value of the pollRegister
// should be reflected in the output
pushInput = 40;
pollRegister = 3; pollRegister = 3;
device2DummyBackend->throwExceptionRead = false; // let the device recover pushInput.write();
result.read();
BOOST_CHECK_EQUAL(result, 43);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
// nothing more in the queue
BOOST_CHECK(result.readLatest() == false);
// the 2 from the poll register is never seen... // Check if we get faulty output from the exception alone,
// keep pushInput ok
pollRegister = 4;
pushInput = 50;
device2DummyBackend->throwExceptionRead = true;
// /////////////////////////// FIXME: old behaviour. This will go away with the new spec pushInput.write();
// The original data is written again, still with faulty as the push input was faulty as well
result.read(); result.read();
BOOST_CHECK_EQUAL(result, 11); BOOST_CHECK(result.readLatest() == false);
// The new data from the pushInput, the device exception should yield DataValidity::faulty at the outout,
BOOST_CHECK_EQUAL(result, 53);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
// The 20 at the push input is propagated (together with its faulty flag). It already sees the new value from the poll type
// It's good that this goes away. This combination was never at the souces at the same time. // Also set pushInputValidity to faulty
pushInput = 60;
pushInput.setDataValidity(ctk::DataValidity::faulty);
pushInput.write();
result.read(); result.read();
BOOST_CHECK_EQUAL(result, 23); BOOST_CHECK_EQUAL(result, 63);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty); BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
// /////////////////////////// END OF FIXME: old behaviour // let the device recover
device2DummyBackend->throwExceptionRead = false;
CHECK_EQUAL_TIMEOUT((deviceStatus.readLatest(), deviceStatus), 0, 10000);
// The new pollRegister value should now be reflected in the result,
// but it's still faulty from the pushInput
pushInput = 70;
pollRegister = 5;
pushInput.write();
result.read();
BOOST_CHECK_EQUAL(result, 75);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::faulty);
// The new, good value arrives // MAke pushInput ok, everything should be back to normal
pushInput = 80;
pushInput.setDataValidity(ctk::DataValidity::ok);
pollRegister = 6;
pushInput.write();
result.read(); result.read();
BOOST_CHECK_EQUAL(result, 33); BOOST_CHECK_EQUAL(result, 86);
BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok); BOOST_CHECK(result.dataValidity() == ctk::DataValidity::ok);
// nothing more in the queue // nothing more in the queue
BOOST_CHECK(result.readLatest() == false); BOOST_CHECK(result.readLatest() == false);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment