1 #define TRACE_NAME "RequestSender_t"
3 #include "artdaq/DAQrate/RequestSender.hh"
5 #define BOOST_TEST_MODULE RequestSender_t
6 #include "cetlib/quiet_unit_test.hpp"
7 #include "cetlib_except/exception.h"
9 #include "artdaq/DAQrate/detail/RoutingPacket.hh"
14 BOOST_AUTO_TEST_SUITE(RequestSender_test)
16 #define TRACE_REQUIRE_EQUAL(l,r) do { \
18 TLOG(TLVL_DEBUG) << __LINE__ << ": Checking if " << #l << " (" << std::to_string(l) << ") equals " << #r << " (" << std::to_string(r) << ")...YES!" ; \
22 TLOG(TLVL_ERROR) << __LINE__ << ": Checking if " << #l << " (" << std::to_string(l) << ") equals " << #r << " (" << std::to_string(r) << ")...NO!" ; \
24 BOOST_REQUIRE_EQUAL(l, r); \
27 BOOST_AUTO_TEST_CASE(Construct)
29 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
30 TLOG(TLVL_INFO) <<
"Construct Test Case BEGIN" ;
31 fhicl::ParameterSet pset;
34 TLOG(TLVL_INFO) <<
"Construct Test Case END";
37 BOOST_AUTO_TEST_CASE(Tokens)
39 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
40 TLOG(TLVL_INFO) <<
"Tokens Test Case BEGIN" ;
41 const int TOKEN_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
42 TLOG(TLVL_DEBUG) <<
"Opening token listener socket" ;
45 fhicl::ParameterSet token_pset;
46 token_pset.put(
"routing_token_port", TOKEN_PORT);
47 token_pset.put(
"use_routing_master",
true);
48 fhicl::ParameterSet pset;
49 pset.put(
"routing_token_config", token_pset);
55 BOOST_REQUIRE(token_socket != -1);
56 if (token_socket == -1)
58 TLOG(TLVL_ERROR) <<
"Token listener socket was not opened successfully." ;
59 BOOST_REQUIRE_EQUAL(
false,
true);
63 TLOG(TLVL_DEBUG) <<
"Accepting new connection on token_socket" ;
65 socklen_t arglen =
sizeof(addr);
66 auto conn_sock = accept(token_socket, (
struct sockaddr*)&addr, &arglen);
68 t.SendRoutingToken(120);
74 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
76 TRACE_REQUIRE_EQUAL(buff.
rank, 0);
79 t.SendRoutingToken(335);
84 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
86 TRACE_REQUIRE_EQUAL(buff.
rank, 13);
90 TLOG(TLVL_INFO) <<
"Tokens Test Case END";
93 BOOST_AUTO_TEST_CASE(Requests)
95 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
96 TLOG(TLVL_INFO) <<
"Requests Test Case BEGIN" ;
97 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
98 const int DELAY_TIME = 100;
100 const std::string MULTICAST_IP =
"227.28.12.28";
102 const std::string MULTICAST_IP =
"localhost";
104 fhicl::ParameterSet pset;
105 pset.put(
"request_port", REQUEST_PORT);
106 pset.put(
"request_delay_ms", DELAY_TIME);
107 pset.put(
"send_requests",
true);
108 pset.put(
"request_address", MULTICAST_IP);
112 TLOG(TLVL_DEBUG) <<
"Opening request listener socket" ;
113 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
115 struct sockaddr_in si_me_request;
118 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
120 TLOG(TLVL_ERROR) <<
"Unable to set reuse on request socket" ;
121 BOOST_REQUIRE_EQUAL(
true,
false);
124 memset(&si_me_request, 0,
sizeof(si_me_request));
125 si_me_request.sin_family = AF_INET;
126 si_me_request.sin_port = htons(REQUEST_PORT);
127 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
128 if (bind(request_socket, (
struct sockaddr *)&si_me_request,
sizeof(si_me_request)) == -1)
130 TLOG(TLVL_ERROR) <<
"Cannot bind request socket to port " << std::to_string(REQUEST_PORT) ;
131 BOOST_REQUIRE_EQUAL(
true,
false);
135 if (MULTICAST_IP !=
"localhost")
138 int sts =
ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
141 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast request address" ;
142 BOOST_REQUIRE_EQUAL(
true,
false);
145 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
146 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
148 TLOG(TLVL_ERROR) <<
"Unable to join multicast group" ;
149 BOOST_REQUIRE_EQUAL(
true,
false);
154 TLOG(TLVL_DEBUG) <<
"Sending request" ;
155 auto start_time = std::chrono::steady_clock::now();
156 t.AddRequest(0, 0x10);
157 struct pollfd ufds[1];
159 TLOG(TLVL_DEBUG) <<
"Receiving Request" ;
160 ufds[0].fd = request_socket;
161 ufds[0].events = POLLIN | POLLPRI;
162 int rv = poll(ufds, 1, 10000);
165 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
167 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
168 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
169 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
171 recv(request_socket, &hdr_buffer,
sizeof(hdr_buffer), 0);
172 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
173 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
179 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
182 for (
auto& buffer : pkt_buffer)
184 TRACE_REQUIRE_EQUAL(buffer.isValid(),
true);
185 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
186 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
191 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
192 BOOST_REQUIRE_EQUAL(
false,
true);
198 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
199 BOOST_REQUIRE_EQUAL(
false,
true);
205 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
206 BOOST_REQUIRE_EQUAL(
false,
true);
211 start_time = std::chrono::steady_clock::now();
213 t.AddRequest(2, 0x20);
214 rv = poll(ufds, 1, 1000);
217 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
219 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
220 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
221 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
223 auto sts = recv(request_socket, &hdr_buffer,
sizeof(hdr_buffer), 0);
224 TRACE_REQUIRE_EQUAL(sts,
sizeof(hdr_buffer));
225 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
226 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
232 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);
246 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
247 BOOST_REQUIRE_EQUAL(
false,
true);
253 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
254 BOOST_REQUIRE_EQUAL(
false,
true);
260 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
261 BOOST_REQUIRE_EQUAL(
false,
true);
264 rv = poll(ufds, 1, 1000);
267 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
269 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
270 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
271 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
273 recv(request_socket, &hdr_buffer,
sizeof(hdr_buffer), 0);
274 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
275 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
281 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
284 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
285 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
286 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
287 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
288 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
289 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
294 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
295 BOOST_REQUIRE_EQUAL(
false,
true);
301 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
302 BOOST_REQUIRE_EQUAL(
false,
true);
308 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
309 BOOST_REQUIRE_EQUAL(
false,
true);
315 t.AddRequest(3, 0x30);
316 start_time = std::chrono::steady_clock::now();
317 rv = poll(ufds, 1, 1000);
320 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
322 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
323 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
324 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
326 recv(request_socket, &hdr_buffer,
sizeof(hdr_buffer), 0);
327 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
328 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
334 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
337 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
338 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
339 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
344 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
345 BOOST_REQUIRE_EQUAL(
false,
true);
351 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
352 BOOST_REQUIRE_EQUAL(
false,
true);
358 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
359 BOOST_REQUIRE_EQUAL(
false,
true);
363 close(request_socket);
364 TLOG(TLVL_INFO) <<
"Requests Test Case END";
367 BOOST_AUTO_TEST_SUITE_END()
int ResolveHost(char const *host_in, in_addr &addr)
Convert a string hostname to a in_addr suitable for socket communication.
End of Run mode (Used to end request processing on receiver)
The RequestSender contains methods used to send data requests and Routing tokens. ...
unsigned new_slots_free
The number of slots free in the token sender (usually 1)
The RoutingToken contains the magic bytes, the rank of the token sender, and the number of slots free...
int TCP_listen_fd(int port, int rcvbuf)
Create a TCP listening socket on the given port and INADDR_ANY, with the given receive buffer...
The RequestPacket contains information about a single data request.
int rank
The rank from which the RoutingToken came.
uint32_t header
The magic bytes that help validate the RoutingToken.