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 << " (" << l << ") equals " << #r << " (" << r << ")...YES!" ; \
22 TLOG(TLVL_ERROR) << __LINE__ << ": Checking if " << #l << " (" << l << ") equals " << #r << " (" << r << ")...NO!" ; \
24 BOOST_REQUIRE_EQUAL(l, r); \
27 BOOST_AUTO_TEST_CASE(Construct)
29 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
30 metricMan->initialize(fhicl::ParameterSet());
31 metricMan->do_start();
32 TLOG(TLVL_INFO) <<
"Construct Test Case BEGIN" ;
33 fhicl::ParameterSet pset;
36 TLOG(TLVL_INFO) <<
"Construct Test Case END";
39 BOOST_AUTO_TEST_CASE(Tokens)
41 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
42 metricMan->initialize(fhicl::ParameterSet());
43 metricMan->do_start();
44 TLOG(TLVL_INFO) <<
"Tokens Test Case BEGIN" ;
45 const int TOKEN_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
46 TLOG(TLVL_DEBUG) <<
"Opening token listener socket" ;
49 fhicl::ParameterSet token_pset;
50 token_pset.put(
"routing_token_port", TOKEN_PORT);
51 token_pset.put(
"use_routing_master",
true);
52 fhicl::ParameterSet pset;
53 pset.put(
"routing_token_config", token_pset);
59 BOOST_REQUIRE(token_socket != -1);
60 if (token_socket == -1)
62 TLOG(TLVL_ERROR) <<
"Token listener socket was not opened successfully." ;
63 BOOST_REQUIRE_EQUAL(
false,
true);
67 TLOG(TLVL_DEBUG) <<
"Accepting new connection on token_socket" ;
69 socklen_t arglen =
sizeof(addr);
70 auto conn_sock = accept(token_socket, (
struct sockaddr*)&addr, &arglen);
72 t.SendRoutingToken(120, 130);
78 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
81 TRACE_REQUIRE_EQUAL(buff.
rank, 0);
84 t.SendRoutingToken(335, 17);
89 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
92 TRACE_REQUIRE_EQUAL(buff.
rank, 13);
96 TLOG(TLVL_INFO) <<
"Tokens Test Case END";
99 BOOST_AUTO_TEST_CASE(Requests)
101 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
102 metricMan->initialize(fhicl::ParameterSet());
103 metricMan->do_start();
104 TLOG(TLVL_INFO) <<
"Requests Test Case BEGIN" ;
105 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
106 const int DELAY_TIME = 100;
108 const std::string MULTICAST_IP =
"227.28.12.28";
110 const std::string MULTICAST_IP =
"localhost";
112 fhicl::ParameterSet pset;
113 pset.put(
"request_port", REQUEST_PORT);
114 pset.put(
"request_delay_ms", DELAY_TIME);
115 pset.put(
"send_requests",
true);
116 pset.put(
"request_address", MULTICAST_IP);
120 TLOG(TLVL_DEBUG) <<
"Opening request listener socket" ;
121 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
123 struct sockaddr_in si_me_request;
126 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
128 TLOG(TLVL_ERROR) <<
"Unable to set reuse on request socket" ;
129 BOOST_REQUIRE_EQUAL(
true,
false);
132 memset(&si_me_request, 0,
sizeof(si_me_request));
133 si_me_request.sin_family = AF_INET;
134 si_me_request.sin_port = htons(REQUEST_PORT);
135 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
136 if (bind(request_socket, (
struct sockaddr *)&si_me_request,
sizeof(si_me_request)) == -1)
138 TLOG(TLVL_ERROR) <<
"Cannot bind request socket to port " << REQUEST_PORT ;
139 BOOST_REQUIRE_EQUAL(
true,
false);
143 if (MULTICAST_IP !=
"localhost")
146 int sts =
ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
149 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast request address" ;
150 BOOST_REQUIRE_EQUAL(
true,
false);
153 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
154 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
156 TLOG(TLVL_ERROR) <<
"Unable to join multicast group" ;
157 BOOST_REQUIRE_EQUAL(
true,
false);
162 TLOG(TLVL_DEBUG) <<
"Sending request" ;
163 auto start_time = std::chrono::steady_clock::now();
164 t.AddRequest(0, 0x10);
165 struct pollfd ufds[1];
167 TLOG(TLVL_DEBUG) <<
"Receiving Request" ;
168 ufds[0].fd = request_socket;
169 ufds[0].events = POLLIN | POLLPRI;
170 int rv = poll(ufds, 1, 10000);
173 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
175 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
176 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
177 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
178 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
180 recv(request_socket, &buffer[0], buffer.size(), 0);
182 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
183 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
189 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
192 for (
auto& buffer : pkt_buffer)
194 TRACE_REQUIRE_EQUAL(buffer.isValid(),
true);
195 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
196 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
201 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
202 BOOST_REQUIRE_EQUAL(
false,
true);
208 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
209 BOOST_REQUIRE_EQUAL(
false,
true);
215 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
216 BOOST_REQUIRE_EQUAL(
false,
true);
221 start_time = std::chrono::steady_clock::now();
223 t.AddRequest(2, 0x20);
224 rv = poll(ufds, 1, 1000);
227 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
229 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
230 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
231 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
232 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
234 recv(request_socket, &buffer[0], buffer.size(), 0);
236 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
237 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
243 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
246 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
247 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
248 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
249 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
250 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
251 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
256 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
257 BOOST_REQUIRE_EQUAL(
false,
true);
263 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
264 BOOST_REQUIRE_EQUAL(
false,
true);
270 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
271 BOOST_REQUIRE_EQUAL(
false,
true);
274 rv = poll(ufds, 1, 1000);
277 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
279 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
280 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
281 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
282 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
284 recv(request_socket, &buffer[0], buffer.size(), 0);
286 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
287 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
293 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
296 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
297 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
298 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
299 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
300 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
301 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
306 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
307 BOOST_REQUIRE_EQUAL(
false,
true);
313 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
314 BOOST_REQUIRE_EQUAL(
false,
true);
320 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
321 BOOST_REQUIRE_EQUAL(
false,
true);
327 t.AddRequest(3, 0x30);
328 start_time = std::chrono::steady_clock::now();
329 rv = poll(ufds, 1, 1000);
332 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
334 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
335 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
336 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
337 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
339 recv(request_socket, &buffer[0], buffer.size(), 0);
341 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
342 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
348 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
351 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
352 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
353 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
358 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
359 BOOST_REQUIRE_EQUAL(
false,
true);
365 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
366 BOOST_REQUIRE_EQUAL(
false,
true);
372 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
373 BOOST_REQUIRE_EQUAL(
false,
true);
377 close(request_socket);
378 TLOG(TLVL_INFO) <<
"Requests Test Case END";
379 artdaq::Globals::CleanUpGlobals();
382 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.
unsigned run_number
The Run with which this token should be associated.
uint32_t header
The magic bytes that help validate the RoutingToken.