ChimeraTK-DeviceAccess  03.18.00
testRebotHeartbeatCount.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2 // SPDX-License-Identifier: LGPL-3.0-or-later
3 
4 /**********************************************************************************************************************/
5 /* This file currently runs on real time, so it will take about a minute to finish! */
6 /* FIXME: Port this to virtual time */
7 /**********************************************************************************************************************/
8 
9 #define BOOST_TEST_DYN_LINK
10 #define BOOST_TEST_MODULE RebotHeartbeatCountTest
11 // Only after defining the name include the unit test header.
12 #include <boost/test/unit_test.hpp>
13 using namespace boost::unit_test_framework;
14 
15 #include "Device.h"
16 #include "RebotDummyServer.h"
18 
19 #include <boost/bind/bind.hpp>
20 #include <boost/thread.hpp>
21 
22 using namespace boost::unit_test_framework;
23 using namespace ChimeraTK;
24 using namespace ChimeraTK;
25 
26 // Create a test suite which holds all your tests.
27 BOOST_AUTO_TEST_SUITE(RebotHeartbeatCountTestSuite)
28 
29 // This test is for protocol version 1
30 BOOST_AUTO_TEST_CASE(testHeartbeat1) {
31  RebotDummyServer rebotServer(5001 /*port*/, "./mtcadummy_rebot.map", 1 /*protocol version*/);
32 
33  boost::thread serverThread(boost::bind(&RebotDummyServer::start, boost::ref(rebotServer)));
34 
35  Device d;
36  d.open("(rebot?ip=localhost&port=5001&map=mtcadummy_rebot.map)");
37  auto session = rebotServer.session();
38 
39  BOOST_CHECK(d.isFunctional() == true);
40 
41  BOOST_CHECK_EQUAL(session->_helloCount, 1);
42 
44  // We now have locked the mutex
45 
46  for(uint32_t i = 1; i < 5; ++i) {
47  d.write("BOARD.WORD_USER", 42);
48  testable_rebot_sleep::advance_until(boost::chrono::milliseconds(i * 2500));
49  }
50 
51  BOOST_CHECK_EQUAL(session->_helloCount, 1);
52 
53  for(uint32_t i = 1; i < 5; ++i) {
54  testable_rebot_sleep::advance_until(boost::chrono::milliseconds(i * 5000 + 10000));
55  BOOST_CHECK_EQUAL(session->_helloCount, i + 1);
56  }
57 
58  for(uint32_t i = 1; i < 5; ++i) {
59  [[maybe_unused]] auto result = d.read<int>("BOARD.WORD_USER");
60  testable_rebot_sleep::advance_until(boost::chrono::milliseconds(i * 2500 + 30000));
61  }
62 
63  BOOST_CHECK_EQUAL(session->_helloCount, 5);
64 
65  for(uint32_t i = 1; i < 5; ++i) {
66  testable_rebot_sleep::advance_until(boost::chrono::milliseconds(i * 5000 + 40000));
67  BOOST_CHECK_EQUAL(session->_helloCount, i + 5);
68  }
69 
70  // ****************
71  // FIXME
72  // This test freezes when advancing because the readout is the backend is not
73  // return, so it has been turned off.
74  // ****************
75 
76  // // Test error handling heartbeat loop.
77  //
78  // // Tell the server not to answer and advance the time so the another
79  // heartbeat is send.
80  // // This intentionally does not throw, because it's in anther thread. But it
81  // closes the backend. BOOST_CHECK(d.isOpened() == true);
82  //
83  // // std::cout << "setting rebot dummy server not to answer " << std::endl;
84  // rebotServer._dont_answer=true;
85  // std::cout << "advancing to 65000" << std::endl;
86  // testable_rebot_sleep::advance_until(boost::chrono::milliseconds(65000));
87  // std::cout << "If we are here everything is fine " << std::endl;
88  //
89  session.reset();
90 
91  BOOST_CHECK(d.isOpened() == true);
92  BOOST_CHECK(d.isFunctional() == true);
93  d.close();
94  BOOST_CHECK(d.isFunctional() == false);
95  BOOST_CHECK(d.isOpened() == false);
96 
97  // test, if device is not functinal after stopping server
98  d.open("(rebot?ip=localhost&port=5001&map=mtcadummy_rebot.map)");
99  BOOST_CHECK(d.isFunctional() == true);
100  rebotServer.stop();
101  testable_rebot_sleep::advance_until(boost::chrono::milliseconds(62505 + 2500));
102  BOOST_CHECK(d.isFunctional() == false);
103 
104  std::cout << "test done" << std::endl;
105  RebotSleepSynchroniser::_lock.unlock();
106 
107  // This is taking some time to run into a timeout, sometimes never finishes.
108  // So we take it out at the moment.
109  // Note: At this point the backend must have been closed, so the client
110  // connection of the server is no longer open. Otherwise we will block here
111  // forever.
112  // assert(d.isOpened() == false); // <-- This was wrong behaviour, backends must not close on their own!
113  BOOST_CHECK(d.isOpened());
114  rebotServer.stop();
115 
116  serverThread.join();
117 }
118 
119 BOOST_AUTO_TEST_SUITE_END()
RebotDummyServer.h
ChimeraTK::Device::close
void close()
Close the device.
Definition: Device.cc:66
ChimeraTK::Device::read
UserType read(const RegisterPath &registerPathName, const AccessModeFlags &flags=AccessModeFlags({})) const
Inefficient convenience function to read a single-word register without obtaining an accessor.
Definition: Device.h:293
ChimeraTK::RebotDummyServer
Definition: RebotDummyServer.h:82
ChimeraTK::RebotDummyServer::stop
void stop()
Definition: RebotDummyServer.cc:207
Device.h
ChimeraTK::testable_rebot_sleep::waitForClientTestableMode
void waitForClientTestableMode()
Definition: testableRebotSleep_testingImpl.h:145
ChimeraTK::Device
Class allows to read/write registers from device.
Definition: Device.h:39
ChimeraTK::Device::open
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition: Device.cc:58
testableRebotSleep_testingImpl.h
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(testHeartbeat1)
Definition: testRebotHeartbeatCount.cpp:30
ChimeraTK::testable_rebot_sleep::advance_until
void advance_until(boost::chrono::duration< Rep, Period > targetTimeRelativeMyEpoch)
Definition: testableRebotSleep_testingImpl.h:125
ChimeraTK::Device::isOpened
bool isOpened() const
Check if the device is currently opened.
Definition: Device.cc:73
ChimeraTK::RebotDummyServer::session
std::shared_ptr< RebotDummySession > session()
Definition: RebotDummyServer.h:92
ChimeraTK::Device::write
void write(const RegisterPath &registerPathName, UserType value, const AccessModeFlags &flags=AccessModeFlags({}))
Inefficient convenience function to write a single-word register without obtaining an accessor.
Definition: Device.h:314
ChimeraTK::Device::isFunctional
bool isFunctional() const
Return wether a device is working as intended, usually this means it is opened and does not have any ...
Definition: Device.cc:82
ChimeraTK
Definition: DummyBackend.h:16