5#include <ChimeraTK/DeviceBackend.h>
6#include <ChimeraTK/ReadAnyGroup.h>
7#include <ChimeraTK/SharedDummyBackend.h>
8#include <ChimeraTK/TransferElement.h>
9#include <ChimeraTK/VoidRegisterAccessor.h>
11#include <boost/smart_ptr/shared_ptr.hpp>
13#define BOOST_TEST_MODULE reverseRecoveryTest
23#include <ChimeraTK/BackendFactory.h>
24#include <ChimeraTK/Device.h>
26#include <boost/test/included/unit_test.hpp>
33 using ctk::ApplicationModule::ApplicationModule;
49 std::cout <<
"testDirectThreadedFanOutWithReturn" << std::endl;
51 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
56 std::atomic<bool> up{
false};
66 dev.open(
"baseDevice");
69 dev.write<int32_t>(
"/readWrite", 4);
70 dev.write<int32_t>(
"/writeOnlyRB.DUMMY_WRITEABLE", 8);
71 dev.write<int32_t>(
"/secondReadWrite", 16);
85 auto taggedReadWriteCs = test.
getScalar<int32_t>(
"/taggedReadWrite");
86 auto taggedWriteOnlyCs = test.
getScalar<int32_t>(
"/taggedWriteOnly");
87 auto untagged = test.
getScalar<int32_t>(
"/untagged");
91 BOOST_TEST(dev.read<int32_t>(
"/readWrite") == 4);
92 BOOST_TEST(dev.read<int32_t>(
"/writeOnlyRB") == 8);
98 BOOST_TEST(dev.read<int32_t>(
"/secondReadWrite") == 36);
101 taggedReadWriteCs.setAndWrite(48);
102 taggedWriteOnlyCs.setAndWrite(96);
103 untagged.setAndWrite(128);
109 dev.write<int32_t>(
"/readWrite", 3);
110 dev.write<int32_t>(
"/writeOnlyRB.DUMMY_WRITEABLE", 7);
111 dev.write<int32_t>(
"/secondReadWrite", 15);
112 devModule.reportException(
"Trigger device recovery");
124 CHECK_EQUAL_TIMEOUT((taggedReadWriteCs.readLatest(), int32_t(taggedReadWriteCs)), 3, 2000);
134 std::cout <<
"testThreadedFanOutWithReturnOnlyRecoverValue" << std::endl;
135 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
138 dev.open(
"baseDevice");
141 dev.write<int32_t>(
"/readWrite", 4);
146 std::atomic<bool> up{
false};
150 app.mod.doMainLoop = [&]() {
169 dev.write<int32_t>(
"/readWrite", 8);
170 devModule.reportException(
"Trigger device recovery");
186 std::cout <<
"testConstantFeederInversion" << std::endl;
188 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
191 dev.open(
"baseDevice");
194 dev.write<int32_t>(
"/readWrite", 4);
199 std::atomic<bool> up{
false};
203 app.mod.doMainLoop = [&]() {
210 app.optimiseUnmappedVariables({
"/taggedReadWrite"});
217 devModule.reportException(
"Trigger device recovery");
232 std::cout <<
"testFeedingFanOutWithExplicitAccessor" << std::endl;
234 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
237 dev.open(
"baseDevice");
240 dev.write<int32_t>(
"/readWrite", 4);
245 std::atomic<bool> up{
false};
249 app.mod.doMainLoop = [&]() {
263 deviceInput.setAndWrite(44);
268 dev.write<int32_t>(
"/readWrite", 111);
270 devModule.reportException(
"Trigger device recovery");
285 std::cout <<
"testFanOutWithExplicitAccessor02" << std::endl;
286 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
289 dev.open(
"baseDevice");
292 dev.write<int32_t>(
"/readWrite", 4);
297 std::atomic<bool> up{
false};
301 app.mod.doMainLoop = [&]() {
308 app.optimiseUnmappedVariables({
"/taggedReadWrite"});
316 deviceInput.setAndWrite(44);
321 dev.write<int32_t>(
"/readWrite", 111);
323 devModule.reportException(
"Trigger device recovery");
336 std::cout <<
"testFanOutWithExplicitAccessor03" << std::endl;
337 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
340 dev.open(
"baseDevice");
343 dev.write<int32_t>(
"/readWrite", 4);
348 std::atomic<bool> up{
false};
352 app.mod.doMainLoop = [&]() {
359 app.optimiseUnmappedVariables({
"/taggedReadWrite"});
367 deviceInput.setAndWrite(44);
372 dev.write<int32_t>(
"/readWrite", 111);
374 devModule.reportException(
"Trigger device recovery");
389 std::cout <<
"testReverseRecoveryFromApp" << std::endl;
391 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
394 dev.open(
"baseDevice");
397 dev.write<int32_t>(
"/secondReadWrite", 815);
403 std::atomic<bool> up{
false};
407 app.mod.doMainLoop = [&]() {
421 auto untagged = test.
getScalar<int32_t>(
"/untagged");
423 BOOST_TEST(dev.read<int32_t>(
"/secondReadWrite") == 815);
425 deviceInput.setAndWrite(128);
428 dev.write<int32_t>(
"/secondReadWrite", 3);
429 devModule.reportException(
"Trigger device recovery");
443 std::cout <<
"testReverseRecoveryFromAppDirect" << std::endl;
445 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
448 dev.open(
"baseDevice");
451 dev.write<int32_t>(
"/secondReadWrite", 815);
456 std::atomic<bool> up{
false};
460 app.mod.doMainLoop = [&]() {
467 app.optimiseUnmappedVariables({
"/untagged"});
474 auto untagged = test.
getScalar<int32_t>(
"/untagged");
476 BOOST_TEST(dev.read<int32_t>(
"/secondReadWrite") == 815);
478 deviceInput.setAndWrite(128);
481 dev.write<int32_t>(
"/secondReadWrite", 3);
482 devModule.reportException(
"Trigger device recovery");
497 std::cout <<
"testReverseRecoveryFromCS" << std::endl;
500 std::atomic<bool> up{
false};
524 std::cout <<
"testReverseRecoveryWithAdditionalInput" << std::endl;
526 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
536 std::atomic<bool> up{
false};
537 std::atomic<bool> up2{
false};
544 mod2.doMainLoop = [&]() {
565 std::cout <<
"testReverseRecoveryPromotingDeviceWoToFeeder" << std::endl;
568 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
575 dev.open(
"baseDevice");
576 dev.write<int32_t>(
"/writeOnlyRB.DUMMY_WRITEABLE", 8);
586 std::this_thread::sleep_for(std::chrono::seconds(1));
588 BOOST_TEST(dev.read<int32_t>(
"/writeOnlyRB") == 8);
595 std::cout <<
"testReverseRecoveryNetworkWoOptimized" << std::endl;
598 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
602 std::atomic<bool> up{
false};
608 dev.open(
"baseDevice");
609 dev.write<int32_t>(
"/writeOnlyRB.DUMMY_WRITEABLE", 8);
634 std::cout <<
"testReverseRecoveryBitAccessorFanOut" << std::endl;
637 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
644 dev.open(
"baseDevice");
645 dev.write<int32_t>(
"/readWrite", 0x7fff);
654 std::this_thread::sleep_for(std::chrono::seconds(1));
656 BOOST_TEST(dev.read<int32_t>(
"/readWrite") == 0x7FFF);
663 std::cout <<
"testReverseRecoveryBitAccessorFanOut" << std::endl;
666 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
673 dev.open(
"baseDevice");
674 dev.write<int32_t>(
"/readWrite", 0x7fff);
686 std::this_thread::sleep_for(std::chrono::seconds(1));
688 BOOST_TEST(dev.read<int32_t>(
"/readWrite") == 0x7FFF);
695 std::cout <<
"testReverseRecoveryBitAccessorMultipleInModule" << std::endl;
698 ctk::BackendFactory::getInstance().setDMapFilePath(
"testTagged.dmap");
714 dev.open(
"baseDevice");
715 dev.write<int32_t>(
"/readWrite", 0x7fff);
717 std::atomic<bool> up{
false};
728 test.
getVoid(
"/trigger").write();
733 BOOST_TEST(dev.read<int32_t>(
"/readWrite") == 0x7FFF);
#define CHECK_EQUAL_TIMEOUT(left, right, maxMilliseconds)
void debugMakeConnections()
Enable debug output for the ConnectionMaker.
void optimiseUnmappedVariables(const std::set< std::string > &names) override
void shutdown() override
This will remove the global pointer to the instance and allows creating another instance afterwards.
Convenience class for output scalar accessors (always UpdateMode::push)
Convenience class for output scalar accessors with return channel ("read back") (always UpdateMode::p...
Helper class to facilitate tests of applications based on ApplicationCore.
TYPE readScalar(const std::string &name)
Convenience function to read the latest value of a scalar process variable in a single call.
ChimeraTK::VoidRegisterAccessor getVoid(const ChimeraTK::RegisterPath &name) const
Obtain a void process variable from the application, which is published to the control system.
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.
void setScalarDefault(const ChimeraTK::RegisterPath &name, const T &value)
Set default value for scalar process variable.
InvalidityTracer application module.
std::function< void()> doMainLoop
void mainLoop() final
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
ExternalMainLoopModule mod
~TestApplication() override
BOOST_AUTO_TEST_CASE(testDirectThreadedFanOutWithReturn)