From 5f5ada9d6bde5df7dd019e7e55ee5745e432133d Mon Sep 17 00:00:00 2001 From: Martin Hierholzer <martin.hierholzer@desy.de> Date: Wed, 28 Sep 2022 15:04:57 +0200 Subject: [PATCH] fix testVersionPropagation --- tests/CMakeLists.txt | 1 + .../executables_src/testExceptionHandling.cc | 4 +- .../executables_src/testVersionPropagation.cc | 68 ++-- tests/include/fixtures.h | 294 +++++++++++------- tests/test_with_push.map | 6 + 5 files changed, 238 insertions(+), 135 deletions(-) create mode 100644 tests/test_with_push.map diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e549c3ea..2ecc1f46 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,6 +15,7 @@ endforeach( testExecutableSrcFile ) # copy config files FILE( COPY ${CMAKE_CURRENT_SOURCE_DIR}/test.map DESTINATION ${PROJECT_BINARY_DIR}/tests) +FILE( COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_with_push.map DESTINATION ${PROJECT_BINARY_DIR}/tests) FILE( COPY ${CMAKE_CURRENT_SOURCE_DIR}/test.xlmap DESTINATION ${PROJECT_BINARY_DIR}/tests) FILE( COPY ${CMAKE_CURRENT_SOURCE_DIR}/test2.map DESTINATION ${PROJECT_BINARY_DIR}/tests) FILE( COPY ${CMAKE_CURRENT_SOURCE_DIR}/test3.map DESTINATION ${PROJECT_BINARY_DIR}/tests) diff --git a/tests/executables_src/testExceptionHandling.cc b/tests/executables_src/testExceptionHandling.cc index 3a1dd582..6a888f5a 100644 --- a/tests/executables_src/testExceptionHandling.cc +++ b/tests/executables_src/testExceptionHandling.cc @@ -56,7 +56,7 @@ BOOST_FIXTURE_TEST_CASE(B_2_1, Fixture) { deviceBackend->throwExceptionOpen = true; deviceBackend->throwExceptionRead = true; - application.pollModule.pollInput.read(); // causes device exception + application.group1.pollModule.pollInput.read(); // causes device exception CHECK_TIMEOUT(status.readNonBlocking() == true, 10000); CHECK_TIMEOUT(message.readNonBlocking() == true, 10000); @@ -518,7 +518,7 @@ BOOST_FIXTURE_TEST_CASE(B_2_2_5, Fixture) { // Go to exception state, report it explicitly ctk::VersionNumber someVersionBeforeReporting = {}; deviceBackend->throwExceptionOpen = true; // required to make sure device stays down - application.device.reportException("explicit report by test"); + application.group1.device.reportException("explicit report by test"); deviceBackend->setException(); // FIXME: should this be called by reportException()?? ctk::VersionNumber someVersionAfterReporting = {}; diff --git a/tests/executables_src/testVersionPropagation.cc b/tests/executables_src/testVersionPropagation.cc index 4f74dd48..891273de 100644 --- a/tests/executables_src/testVersionPropagation.cc +++ b/tests/executables_src/testVersionPropagation.cc @@ -19,51 +19,67 @@ using Fixture = fixture_with_poll_and_push_input<false>; BOOST_FIXTURE_TEST_SUITE(versionPropagation, Fixture) +/*********************************************************************************************************************/ + BOOST_AUTO_TEST_CASE(versionPropagation_testPolledRead) { std::cout << "versionPropagation_testPolledRead" << std::endl; - auto moduleVersion = application.pollModule.getCurrentVersionNumber(); + auto moduleVersion = application.group1.pollModule.getCurrentVersionNumber(); auto pollVariableVersion = pollVariable.getVersionNumber(); + application.group1.outputModule.setCurrentVersionNumber({}); + outputVariable.write(); pollVariable.read(); - BOOST_CHECK(pollVariable.getVersionNumber() > pollVariableVersion); - BOOST_CHECK(moduleVersion == application.pollModule.getCurrentVersionNumber()); + assert(pollVariable.getVersionNumber() > pollVariableVersion); + BOOST_CHECK(moduleVersion == application.group1.pollModule.getCurrentVersionNumber()); } +/*********************************************************************************************************************/ + BOOST_AUTO_TEST_CASE(versionPropagation_testPolledReadNonBlocking) { std::cout << "versionPropagation_testPolledReadNonBlocking" << std::endl; - auto moduleVersion = application.pollModule.getCurrentVersionNumber(); + auto moduleVersion = application.group1.pollModule.getCurrentVersionNumber(); auto pollVariableVersion = pollVariable.getVersionNumber(); + application.group1.outputModule.setCurrentVersionNumber({}); + outputVariable.write(); pollVariable.readNonBlocking(); - BOOST_CHECK(pollVariable.getVersionNumber() > pollVariableVersion); - BOOST_CHECK(moduleVersion == application.pollModule.getCurrentVersionNumber()); + assert(pollVariable.getVersionNumber() > pollVariableVersion); + BOOST_CHECK(moduleVersion == application.group1.pollModule.getCurrentVersionNumber()); } +/*********************************************************************************************************************/ + BOOST_AUTO_TEST_CASE(versionPropagation_testPolledReadLatest) { std::cout << "versionPropagation_testPolledReadLatest" << std::endl; - auto moduleVersion = application.pollModule.getCurrentVersionNumber(); + auto moduleVersion = application.group1.pollModule.getCurrentVersionNumber(); auto pollVariableVersion = pollVariable.getVersionNumber(); + application.group1.outputModule.setCurrentVersionNumber({}); + outputVariable.write(); pollVariable.readLatest(); - BOOST_CHECK(pollVariable.getVersionNumber() > pollVariableVersion); - BOOST_CHECK(moduleVersion == application.pollModule.getCurrentVersionNumber()); + assert(pollVariable.getVersionNumber() > pollVariableVersion); + BOOST_CHECK(moduleVersion == application.group1.pollModule.getCurrentVersionNumber()); } +/*********************************************************************************************************************/ + BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeRead) { std::cout << "versionPropagation_testPushTypeRead" << std::endl; // Make sure we pop out any stray values in the pushInput before test start: CHECK_TIMEOUT(pushVariable.readLatest() == false, 10000); ctk::VersionNumber nextVersionNumber = {}; - deviceBackend->triggerPush(ctk::RegisterPath("REG1/PUSH_READ"), nextVersionNumber); + interrupt.write(); pushVariable.read(); - BOOST_CHECK(pushVariable.getVersionNumber() == nextVersionNumber); - BOOST_CHECK(application.pushModule.getCurrentVersionNumber() == nextVersionNumber); + assert(pushVariable.getVersionNumber() > nextVersionNumber); + BOOST_CHECK(application.group1.pushModule.getCurrentVersionNumber() == pushVariable.getVersionNumber()); } +/*********************************************************************************************************************/ + BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeReadNonBlocking) { std::cout << "versionPropagation_testPushTypeReadNonBlocking" << std::endl; CHECK_TIMEOUT(pushVariable.readLatest() == false, 10000); @@ -75,15 +91,18 @@ BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeReadNonBlocking) { BOOST_CHECK(pushInputVersionNumber == pushVariable.getVersionNumber()); ctk::VersionNumber nextVersionNumber = {}; - auto moduleVersion = application.pushModule.getCurrentVersionNumber(); - deviceBackend->triggerPush(ctk::RegisterPath("REG1/PUSH_READ"), nextVersionNumber); - BOOST_CHECK_EQUAL(pushVariable.readNonBlocking(), true); - BOOST_CHECK(nextVersionNumber == pushVariable.getVersionNumber()); + auto moduleVersion = application.group1.pushModule.getCurrentVersionNumber(); + + interrupt.write(); + CHECK_TIMEOUT(pushVariable.readNonBlocking() == true, 10000); + BOOST_CHECK(pushVariable.getVersionNumber() > nextVersionNumber); // readNonBlocking will not propagete the version to the module - BOOST_CHECK(moduleVersion == application.pushModule.getCurrentVersionNumber()); + BOOST_CHECK(application.group1.pushModule.getCurrentVersionNumber() == moduleVersion); } +/*********************************************************************************************************************/ + BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeReadLatest) { std::cout << "versionPropagation_testPushTypeReadLatest" << std::endl; // Make sure we pop out any stray values in the pushInput before test start: @@ -96,13 +115,18 @@ BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeReadLatest) { BOOST_CHECK(pushInputVersionNumber == pushVariable.getVersionNumber()); ctk::VersionNumber nextVersionNumber = {}; - deviceBackend->triggerPush(ctk::RegisterPath("REG1/PUSH_READ"), nextVersionNumber); - auto moduleVersion = application.pushModule.getCurrentVersionNumber(); - BOOST_CHECK_EQUAL(pushVariable.readLatest(), true); - BOOST_CHECK(nextVersionNumber == pushVariable.getVersionNumber()); + auto moduleVersion = application.group1.pushModule.getCurrentVersionNumber(); + + interrupt.write(); + CHECK_TIMEOUT(pushVariable.readLatest() == true, 10000); + BOOST_CHECK(pushVariable.getVersionNumber() > nextVersionNumber); // readLatest will not propagete the version to the module - BOOST_CHECK(moduleVersion == application.pushModule.getCurrentVersionNumber()); + BOOST_CHECK(application.group1.pushModule.getCurrentVersionNumber() == moduleVersion); } +/*********************************************************************************************************************/ + BOOST_AUTO_TEST_SUITE_END() + +/*********************************************************************************************************************/ diff --git a/tests/include/fixtures.h b/tests/include/fixtures.h index 564b29e0..69b8413b 100644 --- a/tests/include/fixtures.h +++ b/tests/include/fixtures.h @@ -4,7 +4,6 @@ #include "Application.h" #include "ApplicationModule.h" -#include "check_timeout.h" #include "DeviceModule.h" #include "ScalarAccessor.h" #include "TestFacility.h" @@ -17,6 +16,7 @@ #include <future> +/**********************************************************************************************************************/ /**********************************************************************************************************************/ struct PollModule : ChimeraTK::ApplicationModule { @@ -32,7 +32,8 @@ struct PushModule : ChimeraTK::ApplicationModule { using ChimeraTK::ApplicationModule::ApplicationModule; struct : ChimeraTK::VariableGroup { using ChimeraTK::VariableGroup::VariableGroup; - ChimeraTK::ScalarPushInput<int> pushInput{this, "PUSH_READ", "", ""}; + ChimeraTK::ScalarPushInput<int> pushInput{this, "../REG1_PUSHED", "", ""}; + ChimeraTK::ScalarPushInput<int> pushInputCopy{this, "../REG1_PUSHED", "", ""}; } reg1{this, "REG1", ""}; std::promise<void> p; @@ -48,31 +49,44 @@ struct OutputModule : ChimeraTK::ApplicationModule { ChimeraTK::ScalarOutput<int> deviceRegister3{this, "REG3", "", "", {"DEVICE"}}; ChimeraTK::ScalarOutput<int> trigger{this, "trigger", "", ""}; // must not be connected to any device std::promise<void> p; + void prepare() override { deviceRegister.write(); } void mainLoop() override { p.set_value(); } }; /**********************************************************************************************************************/ struct DummyApplication : ChimeraTK::Application { - constexpr static const char* ExceptionDummyCDD1 = "(ExceptionDummy:1?map=test.map)"; - constexpr static const char* ExceptionDummyCDD2 = "(ExceptionDummy:2?map=test.map)"; - constexpr static const char* ExceptionDummyCDD3 = "(ExceptionDummy:3?map=test.map)"; + constexpr static const char* ExceptionDummyCDD1 = "(ExceptionDummy:1?map=test_with_push.map)"; + constexpr static const char* ExceptionDummyCDD2 = "(ExceptionDummy:2?map=test_with_push.map)"; + constexpr static const char* ExceptionDummyCDD3 = "(ExceptionDummy:3?map=test_with_push.map)"; - DummyApplication() : Application("DummyApplication") {} + DummyApplication() : Application("DummyApplication") { // debugMakeConnections(); + } ~DummyApplication() override { shutdown(); } - PushModule pushModule{this, "pushModule", "", ChimeraTK::TAGS{"DEV"}}; - PollModule pollModule{this, "pollModule", "", ChimeraTK::TAGS{"DEV"}}; - OutputModule outputModule{this, "outputModule", "", ChimeraTK::TAGS{"DEV"}}; - PushModule pushModule2{this, "pushModule2", "With TriggerFanOut", ChimeraTK::TAGS{"DEV2"}}; - PushModule pushModule3{this, "pushModule3", "With ThreadedFanOut", ChimeraTK::TAGS{"DEV2"}}; - PollModule pollModule2{this, "pollModule2", "", ChimeraTK::TAGS{"DEV2"}}; - OutputModule outputModule2{this, "outputModule2", "", ChimeraTK::TAGS{"DEV2"}}; - PollModule pollModule3{this, "pollModule3", "", ChimeraTK::TAGS{"DEV3"}}; - - ChimeraTK::DeviceModule device{this, ExceptionDummyCDD1}; - ChimeraTK::DeviceModule device2{this, ExceptionDummyCDD2}; - ChimeraTK::DeviceModule device3{this, ExceptionDummyCDD3}; + struct Group1 : ChimeraTK::ModuleGroup { + using ChimeraTK::ModuleGroup::ModuleGroup; + ChimeraTK::DeviceModule device{this, ExceptionDummyCDD1}; + PushModule pushModule{this, ".", ""}; + PollModule pollModule{this, ".", ""}; + OutputModule outputModule{this, ".", ""}; + } group1{this, "Group1", ""}; + + struct Group2 : ChimeraTK::ModuleGroup { + using ChimeraTK::ModuleGroup::ModuleGroup; + ChimeraTK::DeviceModule device2{this, ExceptionDummyCDD2}; + PushModule pushModule2{this, ".", "With TriggerFanOut"}; + PushModule pushModule3{this, ".", "With ThreadedFanOut"}; + PollModule pollModule2{this, ".", ""}; + OutputModule outputModule2{this, ".", ""}; + } group2{this, "Group2", ""}; + + struct Group3 : ChimeraTK::ModuleGroup { + using ChimeraTK::ModuleGroup::ModuleGroup; + ChimeraTK::DeviceModule device3{this, ExceptionDummyCDD3}; + PollModule pollModule3{this, ".", ""}; + } group3{this, "Group3", ""}; + /* ChimeraTK::ControlSystemModule cs; @@ -91,26 +105,85 @@ struct DummyApplication : ChimeraTK::Application { }*/ }; +/**********************************************************************************************************************/ /**********************************************************************************************************************/ template<bool enableTestFacility, bool addInitHandlers = false, bool breakSecondDeviceAtStart = false> struct fixture_with_poll_and_push_input { - fixture_with_poll_and_push_input() - : deviceBackend(boost::dynamic_pointer_cast<ChimeraTK::ExceptionDummy>( - ChimeraTK::BackendFactory::getInstance().createBackend(DummyApplication::ExceptionDummyCDD1))), - deviceBackend2(boost::dynamic_pointer_cast<ChimeraTK::ExceptionDummy>( - ChimeraTK::BackendFactory::getInstance().createBackend(DummyApplication::ExceptionDummyCDD2))), - deviceBackend3(boost::dynamic_pointer_cast<ChimeraTK::ExceptionDummy>( - ChimeraTK::BackendFactory::getInstance().createBackend(DummyApplication::ExceptionDummyCDD3))), - exceptionDummyRegister(deviceBackend->getRawAccessor("", "REG1")), - exceptionDummyRegister2(deviceBackend->getRawAccessor("", "REG2")), - exceptionDummyRegister3(deviceBackend->getRawAccessor("", "REG3")), - exceptionDummy2Register(deviceBackend2->getRawAccessor("", "REG1")) { + fixture_with_poll_and_push_input(); + + ~fixture_with_poll_and_push_input(); + + template<typename T> + auto read(ChimeraTK::DummyRegisterRawAccessor& accessor); + + template<typename T> + auto read(ChimeraTK::DummyRegisterRawAccessor&& accessor); + + template<typename T> + void write(ChimeraTK::DummyRegisterRawAccessor& accessor, T value); + + template<typename T> + void write(ChimeraTK::DummyRegisterRawAccessor&& accessor, T value); + + bool isDeviceInError(); + + boost::shared_ptr<ChimeraTK::ExceptionDummy> deviceBackend; + boost::shared_ptr<ChimeraTK::ExceptionDummy> deviceBackend2; + boost::shared_ptr<ChimeraTK::ExceptionDummy> deviceBackend3; + DummyApplication application; + ChimeraTK::TestFacility testFacitiy{application, enableTestFacility}; + + ChimeraTK::ScalarRegisterAccessor<int> status, status2; + ChimeraTK::VoidRegisterAccessor deviceBecameFunctional; + ChimeraTK::ScalarRegisterAccessor<std::string> message; + ChimeraTK::DummyRegisterRawAccessor exceptionDummyRegister; + ChimeraTK::DummyRegisterRawAccessor exceptionDummyRegister2; + ChimeraTK::DummyRegisterRawAccessor exceptionDummyRegister3; + ChimeraTK::DummyRegisterRawAccessor exceptionDummy2Register; + + ChimeraTK::ScalarPushInput<int>& pushVariable{application.group1.pushModule.reg1.pushInput}; + ChimeraTK::ScalarPollInput<int>& pollVariable{application.group1.pollModule.pollInput}; + ChimeraTK::ScalarOutput<int>& outputVariable{application.group1.outputModule.deviceRegister}; + ChimeraTK::ScalarOutput<int>& outputVariable2{application.group1.outputModule.deviceRegister2}; + ChimeraTK::ScalarOutput<int>& outputVariable3{application.group1.outputModule.deviceRegister3}; + + ChimeraTK::ScalarPushInput<int>& triggeredInput{application.group2.pushModule2.reg1.pushInput}; + ChimeraTK::ScalarPollInput<int>& pollVariable2{application.group2.pollModule2.pollInput}; + + ChimeraTK::ScalarPushInput<int>& pushVariable3{application.group2.pushModule3.reg1.pushInput}; + ChimeraTK::ScalarPushInput<int>& pushVariable3copy{application.group2.pushModule3.reg1.pushInputCopy}; + ChimeraTK::ScalarPollInput<int>& pollVariable3{application.group3.pollModule3.pollInput}; + + ChimeraTK::VoidRegisterAccessor interrupt; + + std::atomic<bool> initHandler1Throws{false}; + std::atomic<bool> initHandler2Throws{false}; + std::atomic<bool> initHandler1Called{false}; + std::atomic<bool> initHandler2Called{false}; +}; + +/**********************************************************************************************************************/ + +template<bool enableTestFacility, bool addInitHandlers, bool breakSecondDeviceAtStart> +fixture_with_poll_and_push_input<enableTestFacility, addInitHandlers, + breakSecondDeviceAtStart>::fixture_with_poll_and_push_input() +: deviceBackend(boost::dynamic_pointer_cast<ChimeraTK::ExceptionDummy>( + ChimeraTK::BackendFactory::getInstance().createBackend(DummyApplication::ExceptionDummyCDD1))), + deviceBackend2(boost::dynamic_pointer_cast<ChimeraTK::ExceptionDummy>( + ChimeraTK::BackendFactory::getInstance().createBackend(DummyApplication::ExceptionDummyCDD2))), + deviceBackend3(boost::dynamic_pointer_cast<ChimeraTK::ExceptionDummy>( + ChimeraTK::BackendFactory::getInstance().createBackend(DummyApplication::ExceptionDummyCDD3))), + exceptionDummyRegister(deviceBackend->getRawAccessor("", "REG1")), + exceptionDummyRegister2(deviceBackend->getRawAccessor("", "REG2")), + exceptionDummyRegister3(deviceBackend->getRawAccessor("", "REG3")), + exceptionDummy2Register(deviceBackend2->getRawAccessor("", "REG1")) { + try { deviceBackend2->throwExceptionOpen = breakSecondDeviceAtStart; if constexpr(addInitHandlers) { auto initHandler1 = [this](ChimeraTK::DeviceManager* dm) { - if(dm == &application.device.getDeviceManager()) { + if(dm == &application.group1.device.getDeviceManager()) { initHandler1Called = true; if(initHandler1Throws) { throw ChimeraTK::runtime_error("Init handler 1 throws by request"); @@ -118,113 +191,112 @@ struct fixture_with_poll_and_push_input { } }; auto initHandler2 = [this](ChimeraTK::DeviceManager* dm) { - if(dm == &application.device.getDeviceManager()) { + if(dm == &application.group1.device.getDeviceManager()) { initHandler2Called = true; if(initHandler2Throws) { throw ChimeraTK::runtime_error("Init handler 2 throws by request"); } } }; - application.device.addInitialisationHandler(initHandler1); - application.device.addInitialisationHandler(initHandler2); + application.group1.device.addInitialisationHandler(initHandler1); + application.group1.device.addInitialisationHandler(initHandler2); } testFacitiy.runApplication(); - status.replace(testFacitiy.getScalar<int>( - ChimeraTK::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "status")); - message.replace(testFacitiy.getScalar<std::string>( - ChimeraTK::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "status_message")); - deviceBecameFunctional.replace(testFacitiy.getScalar<int>( - ChimeraTK::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "deviceBecameFunctional")); + auto dm1 = ChimeraTK::Utilities::stripName(DummyApplication::ExceptionDummyCDD1, false); + auto dm2 = ChimeraTK::Utilities::stripName(DummyApplication::ExceptionDummyCDD2, false); + status.replace(testFacitiy.getScalar<int>(ChimeraTK::RegisterPath("/Devices") / dm1 / "status")); + message.replace(testFacitiy.getScalar<std::string>(ChimeraTK::RegisterPath("/Devices") / dm1 / "status_message")); + deviceBecameFunctional.replace( + testFacitiy.getVoid(ChimeraTK::RegisterPath("/Devices") / dm1 / "deviceBecameFunctional")); - status2.replace(testFacitiy.getScalar<int>( - ChimeraTK::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD2 / "status")); + status2.replace(testFacitiy.getScalar<int>(ChimeraTK::RegisterPath("/Devices") / dm2 / "status")); - pushVariable3copy.replace(testFacitiy.getScalar<int>("dev2_reg1_push_read")); + ChimeraTK::Device dev(DummyApplication::ExceptionDummyCDD1); + interrupt.replace(dev.getVoidRegisterAccessor("DUMMY_INTERRUPT_1_0")); - // wait until all modules have been properly started, to ensure the initial value propagation is complete - application.pollModule.p.get_future().wait(); - application.pushModule.p.get_future().wait(); - application.outputModule.p.get_future().wait(); + // wait until all modules have been properly started, to ensure the initial value propagation is complete + application.group1.pollModule.p.get_future().wait(); + application.group1.pushModule.p.get_future().wait(); + application.group1.outputModule.p.get_future().wait(); if(!breakSecondDeviceAtStart) { - application.outputModule2.p.get_future().wait(); - application.pollModule2.p.get_future().wait(); - application.pushModule2.p.get_future().wait(); + application.group2.outputModule2.p.get_future().wait(); + application.group2.pollModule2.p.get_future().wait(); + application.group2.pushModule2.p.get_future().wait(); } deviceBecameFunctional.read(); } - - ~fixture_with_poll_and_push_input() { - // make sure no exception throwing is still enabled from previous test - deviceBackend->throwExceptionOpen = false; - deviceBackend->throwExceptionRead = false; - deviceBackend->throwExceptionWrite = false; - deviceBackend2->throwExceptionOpen = false; - deviceBackend2->throwExceptionRead = false; - deviceBackend2->throwExceptionWrite = false; - deviceBackend3->throwExceptionOpen = false; - deviceBackend3->throwExceptionRead = false; - deviceBackend3->throwExceptionWrite = false; + catch(std::exception& e) { + std::cout << "Exception caught in constructor: " << e.what() << std::endl; + throw; } +} - template<typename T> - auto read(ChimeraTK::DummyRegisterRawAccessor& accessor) { - auto lock = accessor.getBufferLock(); - return static_cast<T>(accessor); - } - template<typename T> - auto read(ChimeraTK::DummyRegisterRawAccessor&& accessor) { - read<T>(accessor); - } +/**********************************************************************************************************************/ - template<typename T> - void write(ChimeraTK::DummyRegisterRawAccessor& accessor, T value) { - auto lock = accessor.getBufferLock(); - accessor = static_cast<int32_t>(value); - } - template<typename T> - void write(ChimeraTK::DummyRegisterRawAccessor&& accessor, T value) { - write(accessor, value); - } +template<bool enableTestFacility, bool addInitHandlers, bool breakSecondDeviceAtStart> +fixture_with_poll_and_push_input<enableTestFacility, addInitHandlers, + breakSecondDeviceAtStart>::~fixture_with_poll_and_push_input() { + // make sure no exception throwing is still enabled from previous test + deviceBackend->throwExceptionOpen = false; + deviceBackend->throwExceptionRead = false; + deviceBackend->throwExceptionWrite = false; + deviceBackend2->throwExceptionOpen = false; + deviceBackend2->throwExceptionRead = false; + deviceBackend2->throwExceptionWrite = false; + deviceBackend3->throwExceptionOpen = false; + deviceBackend3->throwExceptionRead = false; + deviceBackend3->throwExceptionWrite = false; +} - bool isDeviceInError() { - // By definition, the DeviceModule has finished the recovery procedure when the status is 0 again. - status.readLatest(); - return static_cast<int>(status); - } +/**********************************************************************************************************************/ - boost::shared_ptr<ChimeraTK::ExceptionDummy> deviceBackend; - boost::shared_ptr<ChimeraTK::ExceptionDummy> deviceBackend2; - boost::shared_ptr<ChimeraTK::ExceptionDummy> deviceBackend3; - DummyApplication application; - ChimeraTK::TestFacility testFacitiy{application, enableTestFacility}; +template<bool enableTestFacility, bool addInitHandlers, bool breakSecondDeviceAtStart> +bool fixture_with_poll_and_push_input<enableTestFacility, addInitHandlers, + breakSecondDeviceAtStart>::isDeviceInError() { + // By definition, the DeviceModule has finished the recovery procedure when the status is 0 again. + status.readLatest(); + return static_cast<int>(status); +} - ChimeraTK::ScalarRegisterAccessor<int> status, status2; - ChimeraTK::ScalarRegisterAccessor<int> deviceBecameFunctional; - ChimeraTK::ScalarRegisterAccessor<std::string> message; - ChimeraTK::DummyRegisterRawAccessor exceptionDummyRegister; - ChimeraTK::DummyRegisterRawAccessor exceptionDummyRegister2; - ChimeraTK::DummyRegisterRawAccessor exceptionDummyRegister3; - ChimeraTK::DummyRegisterRawAccessor exceptionDummy2Register; +/**********************************************************************************************************************/ - ChimeraTK::ScalarPushInput<int>& pushVariable{application.pushModule.reg1.pushInput}; - ChimeraTK::ScalarPollInput<int>& pollVariable{application.pollModule.pollInput}; - ChimeraTK::ScalarOutput<int>& outputVariable{application.outputModule.deviceRegister}; - ChimeraTK::ScalarOutput<int>& outputVariable2{application.outputModule.deviceRegister2}; - ChimeraTK::ScalarOutput<int>& outputVariable3{application.outputModule.deviceRegister3}; +template<bool enableTestFacility, bool addInitHandlers, bool breakSecondDeviceAtStart> +template<typename T> +auto fixture_with_poll_and_push_input<enableTestFacility, addInitHandlers, breakSecondDeviceAtStart>::read( + ChimeraTK::DummyRegisterRawAccessor& accessor) { + auto lock = accessor.getBufferLock(); + return static_cast<T>(accessor); +} - ChimeraTK::ScalarPushInput<int>& triggeredInput{application.pushModule2.reg1.pushInput}; - ChimeraTK::ScalarPollInput<int>& pollVariable2{application.pollModule2.pollInput}; +/**********************************************************************************************************************/ - ChimeraTK::ScalarPushInput<int>& pushVariable3{application.pushModule3.reg1.pushInput}; - ChimeraTK::ScalarRegisterAccessor<int> pushVariable3copy; - ChimeraTK::ScalarPollInput<int>& pollVariable3{application.pollModule3.pollInput}; +template<bool enableTestFacility, bool addInitHandlers, bool breakSecondDeviceAtStart> +template<typename T> +auto fixture_with_poll_and_push_input<enableTestFacility, addInitHandlers, breakSecondDeviceAtStart>::read( + ChimeraTK::DummyRegisterRawAccessor&& accessor) { + read<T>(accessor); +} - std::atomic<bool> initHandler1Throws{false}; - std::atomic<bool> initHandler2Throws{false}; - std::atomic<bool> initHandler1Called{false}; - std::atomic<bool> initHandler2Called{false}; -}; +/**********************************************************************************************************************/ + +template<bool enableTestFacility, bool addInitHandlers, bool breakSecondDeviceAtStart> +template<typename T> +void fixture_with_poll_and_push_input<enableTestFacility, addInitHandlers, breakSecondDeviceAtStart>::write( + ChimeraTK::DummyRegisterRawAccessor& accessor, T value) { + auto lock = accessor.getBufferLock(); + accessor = static_cast<int32_t>(value); +} /**********************************************************************************************************************/ + +template<bool enableTestFacility, bool addInitHandlers, bool breakSecondDeviceAtStart> +template<typename T> +void fixture_with_poll_and_push_input<enableTestFacility, addInitHandlers, breakSecondDeviceAtStart>::write( + ChimeraTK::DummyRegisterRawAccessor&& accessor, T value) { + write(accessor, value); +} + +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ diff --git a/tests/test_with_push.map b/tests/test_with_push.map new file mode 100644 index 00000000..e3786af0 --- /dev/null +++ b/tests/test_with_push.map @@ -0,0 +1,6 @@ +REG1 0x00000001 0x00000000 0x00000004 0 32 0 1 RW +REG2 0x00000001 0x00000004 0x00000004 0 32 0 1 RW +REG3 0x00000001 0x00000008 0x00000004 0 32 0 1 RW +REG4 0x00000001 0x0000000C 0x00000004 0 32 0 1 RW +AREA1 0x00000004 0x00000010 0x00000010 0 32 0 1 RW +REG1_PUSHED 0x00000001 0x00000000 0x00000004 0 32 0 1 INTERRUPT1:0 -- GitLab