Line data Source code
1 : /**
2 : * @file Receiver_test.cxx Receiver class Unit Tests
3 : *
4 : * This is part of the DUNE DAQ Application Framework, copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 :
9 : #include "CallbackAdapter.hpp"
10 : #include "ipm/Receiver.hpp"
11 :
12 : #define BOOST_TEST_MODULE Receiver_test // NOLINT
13 :
14 : #include "boost/test/unit_test.hpp"
15 :
16 : #include <string>
17 : #include <vector>
18 :
19 : using namespace dunedaq::ipm;
20 :
21 : BOOST_AUTO_TEST_SUITE(Receiver_test)
22 :
23 : namespace {
24 :
25 : class ReceiverImpl : public Receiver
26 : {
27 :
28 : public:
29 : static const message_size_t s_bytes_on_each_receive = 10;
30 :
31 2 : ReceiverImpl()
32 2 : : m_can_receive(false)
33 : {
34 2 : }
35 :
36 1 : void register_callback(std::function<void(Response&)> callback) override
37 : {
38 1 : m_callback_adapter.set_callback(callback);
39 1 : }
40 2 : void unregister_callback() override { m_callback_adapter.clear_callback(); }
41 :
42 2 : std::string connect_for_receives(const nlohmann::json& /* connection_info */) override
43 : {
44 2 : m_can_receive = true;
45 2 : m_callback_adapter.set_receiver(this);
46 2 : return "";
47 : }
48 29786 : bool can_receive() const noexcept override { return m_can_receive; }
49 1 : void sabotage_my_receiving_ability()
50 : {
51 1 : unregister_callback();
52 1 : m_can_receive = false;
53 1 : }
54 :
55 : protected:
56 29781 : Receiver::Response receive_(const duration_t& /* timeout */, bool /*no_tmoexcept_mode*/) override
57 : {
58 29781 : Receiver::Response output;
59 29781 : output.data = std::vector<char>(s_bytes_on_each_receive, 'A');
60 29781 : output.metadata = "";
61 29781 : return output;
62 0 : }
63 :
64 : private:
65 : bool m_can_receive;
66 : CallbackAdapter m_callback_adapter;
67 : };
68 :
69 : } // namespace ""
70 :
71 2 : BOOST_AUTO_TEST_CASE(CopyAndMoveSemantics)
72 : {
73 1 : BOOST_REQUIRE(!std::is_copy_constructible_v<ReceiverImpl>);
74 1 : BOOST_REQUIRE(!std::is_copy_assignable_v<ReceiverImpl>);
75 1 : BOOST_REQUIRE(!std::is_move_constructible_v<ReceiverImpl>);
76 1 : BOOST_REQUIRE(!std::is_move_assignable_v<ReceiverImpl>);
77 1 : }
78 :
79 2 : BOOST_AUTO_TEST_CASE(Timeouts)
80 : {
81 1 : BOOST_REQUIRE_EQUAL(Receiver::s_no_block.count(), 0);
82 1 : BOOST_REQUIRE_GT(Receiver::s_block.count(), 3600000); // "Blocking" must be at least an hour!
83 1 : }
84 :
85 2 : BOOST_AUTO_TEST_CASE(StatusChecks)
86 : {
87 1 : ReceiverImpl the_receiver;
88 :
89 1 : BOOST_REQUIRE(!the_receiver.can_receive());
90 :
91 1 : nlohmann::json j;
92 1 : the_receiver.connect_for_receives(j);
93 1 : BOOST_REQUIRE(the_receiver.can_receive());
94 :
95 1 : BOOST_REQUIRE_NO_THROW(the_receiver.receive(Receiver::s_no_block));
96 1 : BOOST_REQUIRE_NO_THROW(the_receiver.receive(Receiver::s_no_block, ReceiverImpl::s_bytes_on_each_receive));
97 :
98 3 : BOOST_REQUIRE_EXCEPTION(the_receiver.receive(Receiver::s_no_block, ReceiverImpl::s_bytes_on_each_receive - 1),
99 : dunedaq::ipm::UnexpectedNumberOfBytes,
100 : [&](dunedaq::ipm::UnexpectedNumberOfBytes) { return true; });
101 :
102 1 : the_receiver.sabotage_my_receiving_ability();
103 1 : BOOST_REQUIRE(!the_receiver.can_receive());
104 :
105 3 : BOOST_REQUIRE_EXCEPTION(the_receiver.receive(Receiver::s_no_block),
106 : dunedaq::ipm::KnownStateForbidsReceive,
107 : [&](dunedaq::ipm::KnownStateForbidsReceive) { return true; });
108 1 : }
109 :
110 2 : BOOST_AUTO_TEST_CASE(Callback)
111 : {
112 1 : ReceiverImpl the_receiver;
113 :
114 1 : nlohmann::json j;
115 1 : the_receiver.connect_for_receives(j);
116 1 : BOOST_REQUIRE(the_receiver.can_receive());
117 :
118 1 : std::atomic<size_t> callback_call_count = 0;
119 29778 : auto callback_fun = [&](Receiver::Response&) { callback_call_count++; }; // NOLINT
120 :
121 1 : the_receiver.register_callback(callback_fun);
122 1 : usleep(10000);
123 1 : the_receiver.unregister_callback();
124 :
125 1 : BOOST_REQUIRE_GT(callback_call_count, 0);
126 1 : }
127 :
128 : BOOST_AUTO_TEST_SUITE_END()
|