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);
78 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
80 TRACE_REQUIRE_EQUAL(buff.
rank, 0);
83 t.SendRoutingToken(335);
88 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
90 TRACE_REQUIRE_EQUAL(buff.
rank, 13);
94 TLOG(TLVL_INFO) <<
"Tokens Test Case END";
97 BOOST_AUTO_TEST_CASE(Requests)
99 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
100 metricMan->initialize(fhicl::ParameterSet());
101 metricMan->do_start();
102 TLOG(TLVL_INFO) <<
"Requests Test Case BEGIN" ;
103 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
104 const int DELAY_TIME = 100;
106 const std::string MULTICAST_IP =
"227.28.12.28";
108 const std::string MULTICAST_IP =
"localhost";
110 fhicl::ParameterSet pset;
111 pset.put(
"request_port", REQUEST_PORT);
112 pset.put(
"request_delay_ms", DELAY_TIME);
113 pset.put(
"send_requests",
true);
114 pset.put(
"request_address", MULTICAST_IP);
118 TLOG(TLVL_DEBUG) <<
"Opening request listener socket" ;
119 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
121 struct sockaddr_in si_me_request;
124 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
126 TLOG(TLVL_ERROR) <<
"Unable to set reuse on request socket" ;
127 BOOST_REQUIRE_EQUAL(
true,
false);
130 memset(&si_me_request, 0,
sizeof(si_me_request));
131 si_me_request.sin_family = AF_INET;
132 si_me_request.sin_port = htons(REQUEST_PORT);
133 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
134 if (bind(request_socket, (
struct sockaddr *)&si_me_request,
sizeof(si_me_request)) == -1)
136 TLOG(TLVL_ERROR) <<
"Cannot bind request socket to port " << REQUEST_PORT ;
137 BOOST_REQUIRE_EQUAL(
true,
false);
141 if (MULTICAST_IP !=
"localhost")
144 int sts =
ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
147 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast request address" ;
148 BOOST_REQUIRE_EQUAL(
true,
false);
151 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
152 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
154 TLOG(TLVL_ERROR) <<
"Unable to join multicast group" ;
155 BOOST_REQUIRE_EQUAL(
true,
false);
160 TLOG(TLVL_DEBUG) <<
"Sending request" ;
161 auto start_time = std::chrono::steady_clock::now();
162 t.AddRequest(0, 0x10);
163 struct pollfd ufds[1];
165 TLOG(TLVL_DEBUG) <<
"Receiving Request" ;
166 ufds[0].fd = request_socket;
167 ufds[0].events = POLLIN | POLLPRI;
168 int rv = poll(ufds, 1, 10000);
171 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
173 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
174 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
175 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
176 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
178 recv(request_socket, &buffer[0], buffer.size(), 0);
180 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
181 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
187 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
190 for (
auto& buffer : pkt_buffer)
192 TRACE_REQUIRE_EQUAL(buffer.isValid(),
true);
193 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
194 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
199 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
200 BOOST_REQUIRE_EQUAL(
false,
true);
206 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
207 BOOST_REQUIRE_EQUAL(
false,
true);
213 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
214 BOOST_REQUIRE_EQUAL(
false,
true);
219 start_time = std::chrono::steady_clock::now();
221 t.AddRequest(2, 0x20);
222 rv = poll(ufds, 1, 1000);
225 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
227 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
228 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
229 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
230 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
232 recv(request_socket, &buffer[0], buffer.size(), 0);
234 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
235 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
241 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
244 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
245 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
246 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
247 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
248 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
249 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
254 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
255 BOOST_REQUIRE_EQUAL(
false,
true);
261 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
262 BOOST_REQUIRE_EQUAL(
false,
true);
268 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
269 BOOST_REQUIRE_EQUAL(
false,
true);
272 rv = poll(ufds, 1, 1000);
275 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
277 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
278 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
279 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
280 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
282 recv(request_socket, &buffer[0], buffer.size(), 0);
284 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
285 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
291 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
294 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
295 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
296 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
297 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
298 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
299 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
304 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
305 BOOST_REQUIRE_EQUAL(
false,
true);
311 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
312 BOOST_REQUIRE_EQUAL(
false,
true);
318 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
319 BOOST_REQUIRE_EQUAL(
false,
true);
325 t.AddRequest(3, 0x30);
326 start_time = std::chrono::steady_clock::now();
327 rv = poll(ufds, 1, 1000);
330 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
332 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
333 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
334 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
335 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
337 recv(request_socket, &buffer[0], buffer.size(), 0);
339 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
340 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
346 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
349 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
350 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
351 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
356 TLOG(TLVL_ERROR) <<
"Invalid header received" ;
357 BOOST_REQUIRE_EQUAL(
false,
true);
363 TLOG(TLVL_ERROR) <<
"Wrong event type from poll" ;
364 BOOST_REQUIRE_EQUAL(
false,
true);
370 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request" ;
371 BOOST_REQUIRE_EQUAL(
false,
true);
375 close(request_socket);
376 TLOG(TLVL_INFO) <<
"Requests Test Case END";
377 artdaq::Globals::CleanUpGlobals();
380 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.