1 #define BOOST_TEST_MODULE RequestSender_t
2 #include "boost/test/unit_test.hpp"
5 #define TRACE_NAME "RequestSender_t"
7 #include "artdaq-core/Utilities/configureMessageFacility.hh"
10 #include "artdaq/DAQrate/detail/RequestSender.hh"
11 #include "artdaq/DAQrate/detail/RoutingPacket.hh"
15 BOOST_AUTO_TEST_SUITE(RequestSender_test)
17 #define TRACE_REQUIRE_EQUAL(l, r) \
22 TLOG(TLVL_DEBUG) << __LINE__ << ": Checking if " << #l << " (" << (l) << ") equals " << #r << " (" << (r) << ")...YES!"; \
26 TLOG(TLVL_ERROR) << __LINE__ << ": Checking if " << #l << " (" << (l) << ") equals " << #r << " (" << (r) << ")...NO!"; \
28 BOOST_REQUIRE_EQUAL((l), (r)); \
33 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
34 metricMan->initialize(fhicl::ParameterSet());
35 metricMan->do_start();
36 TLOG(TLVL_INFO) <<
"Construct Test Case BEGIN";
37 fhicl::ParameterSet pset;
40 TLOG(TLVL_INFO) <<
"Construct Test Case END";
46 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
47 metricMan->initialize(fhicl::ParameterSet());
48 metricMan->do_start();
49 TLOG(TLVL_INFO) <<
"Requests Test Case BEGIN";
50 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
51 const int DELAY_TIME = 100;
53 const std::string MULTICAST_IP =
"227.28.12.28";
55 const std::string MULTICAST_IP =
"localhost";
57 fhicl::ParameterSet pset;
58 pset.put(
"request_port", REQUEST_PORT);
59 pset.put(
"request_delay_ms", DELAY_TIME);
60 pset.put(
"send_requests",
true);
61 pset.put(
"request_address", MULTICAST_IP);
64 TLOG(TLVL_DEBUG) <<
"Opening request listener socket";
65 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
67 struct sockaddr_in si_me_request;
70 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
72 TLOG(TLVL_ERROR) <<
"Unable to set reuse on request socket";
73 BOOST_REQUIRE_EQUAL(
true,
false);
76 memset(&si_me_request, 0,
sizeof(si_me_request));
77 si_me_request.sin_family = AF_INET;
78 si_me_request.sin_port = htons(REQUEST_PORT);
79 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
80 if (bind(request_socket, reinterpret_cast<struct sockaddr*>(&si_me_request),
sizeof(si_me_request)) == -1)
82 TLOG(TLVL_ERROR) <<
"Cannot bind request socket to port " << REQUEST_PORT;
83 BOOST_REQUIRE_EQUAL(
true,
false);
87 if (MULTICAST_IP !=
"localhost")
90 int sts =
ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
93 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast request address";
94 BOOST_REQUIRE_EQUAL(
true,
false);
97 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
98 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
100 TLOG(TLVL_ERROR) <<
"Unable to join multicast group";
101 BOOST_REQUIRE_EQUAL(
true,
false);
106 TLOG(TLVL_DEBUG) <<
"Sending request";
107 auto start_time = std::chrono::steady_clock::now();
109 struct pollfd ufds[1];
111 TLOG(TLVL_DEBUG) <<
"Receiving Request";
112 ufds[0].fd = request_socket;
113 ufds[0].events = POLLIN | POLLPRI;
114 int rv = poll(ufds, 1, 10000);
117 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
119 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
120 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
121 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
122 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
124 recv(request_socket, &buffer[0], buffer.size(), 0);
126 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
127 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
132 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
135 for (
auto& buffer : pkt_buffer)
137 TRACE_REQUIRE_EQUAL(buffer.isValid(),
true);
138 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
139 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
144 TLOG(TLVL_ERROR) <<
"Invalid header received";
145 BOOST_REQUIRE_EQUAL(
false,
true);
151 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
152 BOOST_REQUIRE_EQUAL(
false,
true);
158 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
159 BOOST_REQUIRE_EQUAL(
false,
true);
164 start_time = std::chrono::steady_clock::now();
167 rv = poll(ufds, 1, 1000);
170 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
172 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
173 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
174 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
175 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
177 recv(request_socket, &buffer[0], buffer.size(), 0);
179 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
180 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
185 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
188 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
189 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
190 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
191 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
192 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
193 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
197 TLOG(TLVL_ERROR) <<
"Invalid header received";
198 BOOST_REQUIRE_EQUAL(
false,
true);
204 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
205 BOOST_REQUIRE_EQUAL(
false,
true);
211 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
212 BOOST_REQUIRE_EQUAL(
false,
true);
215 rv = poll(ufds, 1, 1000);
218 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
220 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
221 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
222 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
223 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
225 recv(request_socket, &buffer[0], buffer.size(), 0);
227 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
228 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
233 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
236 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
237 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
238 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
239 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
240 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
241 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
245 TLOG(TLVL_ERROR) <<
"Invalid header received";
246 BOOST_REQUIRE_EQUAL(
false,
true);
252 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
253 BOOST_REQUIRE_EQUAL(
false,
true);
259 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
260 BOOST_REQUIRE_EQUAL(
false,
true);
267 start_time = std::chrono::steady_clock::now();
268 rv = poll(ufds, 1, 1000);
271 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
273 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
274 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
275 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
276 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
278 recv(request_socket, &buffer[0], buffer.size(), 0);
280 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
281 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
286 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
289 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
290 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
291 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
295 TLOG(TLVL_ERROR) <<
"Invalid header received";
296 BOOST_REQUIRE_EQUAL(
false,
true);
302 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
303 BOOST_REQUIRE_EQUAL(
false,
true);
309 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
310 BOOST_REQUIRE_EQUAL(
false,
true);
314 close(request_socket);
315 TLOG(TLVL_INFO) <<
"Requests Test Case END";
319 BOOST_AUTO_TEST_SUITE_END()
void RemoveRequest(Fragment::sequence_id_t seqID)
Remove a request from the request list.
int ResolveHost(char const *host_in, in_addr &addr)
Convert a string hostname to a in_addr suitable for socket communication.
detail::RequestMessageMode GetRequestMode() const
Get the mode for RequestMessages.
End of Run mode (Used to end request processing on receiver)
static void CleanUpGlobals()
Clean up statically-allocated Manager class instances.
The RequestSender contains methods used to send data requests and Routing tokens. ...
void SetRequestMode(detail::RequestMessageMode mode)
Set the mode for RequestMessages. Used to indicate when RequestSender should enter "EndOfRun" mode...
The RequestPacket contains information about a single data request.
void AddRequest(Fragment::sequence_id_t seqID, Fragment::timestamp_t timestamp)
Add a request to the request list.