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.
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.
Convenience class for output scalar accessors (always UpdateMode::push)
Convenience class for output scalar accessors with return channel ("read back") (always UpdateMode::p...
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)