1 #define TRACE_NAME "RequestSender_t"
3 #include "artdaq/DAQrate/RequestSender.hh"
5 #define BOOST_TEST_MODULE RequestSender_t
9 #include "artdaq/DAQrate/detail/RoutingPacket.hh"
10 #include "cetlib/quiet_unit_test.hpp"
11 #include "cetlib_except/exception.h"
13 BOOST_AUTO_TEST_SUITE(RequestSender_test)
15 #define TRACE_REQUIRE_EQUAL(l, r) \
20 TLOG(TLVL_DEBUG) << __LINE__ << ": Checking if " << #l << " (" << l << ") equals " << #r << " (" << r << ")...YES!"; \
24 TLOG(TLVL_ERROR) << __LINE__ << ": Checking if " << #l << " (" << l << ") equals " << #r << " (" << r << ")...NO!"; \
26 BOOST_REQUIRE_EQUAL(l, r); \
29 BOOST_AUTO_TEST_CASE(Construct)
31 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
32 metricMan->initialize(fhicl::ParameterSet());
33 metricMan->do_start();
34 TLOG(TLVL_INFO) <<
"Construct Test Case BEGIN";
35 fhicl::ParameterSet pset;
38 TLOG(TLVL_INFO) <<
"Construct Test Case END";
41 BOOST_AUTO_TEST_CASE(Tokens)
43 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
44 metricMan->initialize(fhicl::ParameterSet());
45 metricMan->do_start();
46 TLOG(TLVL_INFO) <<
"Tokens Test Case BEGIN";
47 const int TOKEN_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
48 TLOG(TLVL_DEBUG) <<
"Opening token listener socket";
51 fhicl::ParameterSet token_pset;
52 token_pset.put(
"routing_token_port", TOKEN_PORT);
53 token_pset.put(
"use_routing_master",
true);
54 fhicl::ParameterSet pset;
55 pset.put(
"routing_token_config", token_pset);
60 BOOST_REQUIRE(token_socket != -1);
61 if (token_socket == -1)
63 TLOG(TLVL_ERROR) <<
"Token listener socket was not opened successfully.";
64 BOOST_REQUIRE_EQUAL(
false,
true);
68 TLOG(TLVL_DEBUG) <<
"Accepting new connection on token_socket";
70 socklen_t arglen =
sizeof(addr);
71 auto conn_sock = accept(token_socket, (
struct sockaddr*)&addr, &arglen);
73 t.SendRoutingToken(120, 130);
79 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
82 TRACE_REQUIRE_EQUAL(buff.
rank, 0);
85 t.SendRoutingToken(335, 17);
90 TRACE_REQUIRE_EQUAL(buff.
header, TOKEN_MAGIC);
93 TRACE_REQUIRE_EQUAL(buff.
rank, 13);
97 TLOG(TLVL_INFO) <<
"Tokens Test Case END";
100 BOOST_AUTO_TEST_CASE(Requests)
102 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
103 metricMan->initialize(fhicl::ParameterSet());
104 metricMan->do_start();
105 TLOG(TLVL_INFO) <<
"Requests Test Case BEGIN";
106 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
107 const int DELAY_TIME = 100;
109 const std::string MULTICAST_IP =
"227.28.12.28";
111 const std::string MULTICAST_IP =
"localhost";
113 fhicl::ParameterSet pset;
114 pset.put(
"request_port", REQUEST_PORT);
115 pset.put(
"request_delay_ms", DELAY_TIME);
116 pset.put(
"send_requests",
true);
117 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),
188 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
191 for (
auto& buffer : pkt_buffer)
193 TRACE_REQUIRE_EQUAL(buffer.isValid(),
true);
194 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
195 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
200 TLOG(TLVL_ERROR) <<
"Invalid header received";
201 BOOST_REQUIRE_EQUAL(
false,
true);
207 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
208 BOOST_REQUIRE_EQUAL(
false,
true);
214 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
215 BOOST_REQUIRE_EQUAL(
false,
true);
220 start_time = std::chrono::steady_clock::now();
222 t.AddRequest(2, 0x20);
223 rv = poll(ufds, 1, 1000);
226 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
228 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
229 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
230 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
231 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
233 recv(request_socket, &buffer[0], buffer.size(), 0);
235 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
236 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);
253 TLOG(TLVL_ERROR) <<
"Invalid header received";
254 BOOST_REQUIRE_EQUAL(
false,
true);
260 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
261 BOOST_REQUIRE_EQUAL(
false,
true);
267 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
268 BOOST_REQUIRE_EQUAL(
false,
true);
271 rv = poll(ufds, 1, 1000);
274 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
276 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
277 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
278 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
279 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
281 recv(request_socket, &buffer[0], buffer.size(), 0);
283 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
284 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
289 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
292 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
293 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
294 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
295 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
296 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
297 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
301 TLOG(TLVL_ERROR) <<
"Invalid header received";
302 BOOST_REQUIRE_EQUAL(
false,
true);
308 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
309 BOOST_REQUIRE_EQUAL(
false,
true);
315 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
316 BOOST_REQUIRE_EQUAL(
false,
true);
322 t.AddRequest(3, 0x30);
323 start_time = std::chrono::steady_clock::now();
324 rv = poll(ufds, 1, 1000);
327 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
329 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
330 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
331 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
332 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
334 recv(request_socket, &buffer[0], buffer.size(), 0);
336 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
337 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
342 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
345 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
346 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
347 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
351 TLOG(TLVL_ERROR) <<
"Invalid header received";
352 BOOST_REQUIRE_EQUAL(
false,
true);
358 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
359 BOOST_REQUIRE_EQUAL(
false,
true);
365 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
366 BOOST_REQUIRE_EQUAL(
false,
true);
370 close(request_socket);
371 TLOG(TLVL_INFO) <<
"Requests Test Case END";
375 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)
static void CleanUpGlobals()
Clean up statically-allocated Manager class instances.
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.