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_manager",
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, reinterpret_cast<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";
101 BOOST_AUTO_TEST_CASE(Requests)
103 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
104 metricMan->initialize(fhicl::ParameterSet());
105 metricMan->do_start();
106 TLOG(TLVL_INFO) <<
"Requests Test Case BEGIN";
107 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
108 const int DELAY_TIME = 100;
110 const std::string MULTICAST_IP =
"227.28.12.28";
112 const std::string MULTICAST_IP =
"localhost";
114 fhicl::ParameterSet pset;
115 pset.put(
"request_port", REQUEST_PORT);
116 pset.put(
"request_delay_ms", DELAY_TIME);
117 pset.put(
"send_requests",
true);
118 pset.put(
"request_address", MULTICAST_IP);
121 TLOG(TLVL_DEBUG) <<
"Opening request listener socket";
122 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
124 struct sockaddr_in si_me_request;
127 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
129 TLOG(TLVL_ERROR) <<
"Unable to set reuse on request socket";
130 BOOST_REQUIRE_EQUAL(
true,
false);
133 memset(&si_me_request, 0,
sizeof(si_me_request));
134 si_me_request.sin_family = AF_INET;
135 si_me_request.sin_port = htons(REQUEST_PORT);
136 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
137 if (bind(request_socket, reinterpret_cast<struct sockaddr*>(&si_me_request),
sizeof(si_me_request)) == -1)
139 TLOG(TLVL_ERROR) <<
"Cannot bind request socket to port " << REQUEST_PORT;
140 BOOST_REQUIRE_EQUAL(
true,
false);
144 if (MULTICAST_IP !=
"localhost")
147 int sts =
ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
150 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast request address";
151 BOOST_REQUIRE_EQUAL(
true,
false);
154 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
155 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
157 TLOG(TLVL_ERROR) <<
"Unable to join multicast group";
158 BOOST_REQUIRE_EQUAL(
true,
false);
163 TLOG(TLVL_DEBUG) <<
"Sending request";
164 auto start_time = std::chrono::steady_clock::now();
165 t.AddRequest(0, 0x10);
166 struct pollfd ufds[1];
168 TLOG(TLVL_DEBUG) <<
"Receiving Request";
169 ufds[0].fd = request_socket;
170 ufds[0].events = POLLIN | POLLPRI;
171 int rv = poll(ufds, 1, 10000);
174 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
176 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
177 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
178 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
179 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
181 recv(request_socket, &buffer[0], buffer.size(), 0);
183 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
184 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),
242 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
245 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
246 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
247 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
248 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
249 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
250 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),
290 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
293 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
294 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
295 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
296 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
297 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
298 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
302 TLOG(TLVL_ERROR) <<
"Invalid header received";
303 BOOST_REQUIRE_EQUAL(
false,
true);
309 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
310 BOOST_REQUIRE_EQUAL(
false,
true);
316 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
317 BOOST_REQUIRE_EQUAL(
false,
true);
323 t.AddRequest(3, 0x30);
324 start_time = std::chrono::steady_clock::now();
325 rv = poll(ufds, 1, 1000);
328 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
330 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
331 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
332 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
333 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
335 recv(request_socket, &buffer[0], buffer.size(), 0);
337 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
338 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
343 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
346 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
347 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
348 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
352 TLOG(TLVL_ERROR) <<
"Invalid header received";
353 BOOST_REQUIRE_EQUAL(
false,
true);
359 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
360 BOOST_REQUIRE_EQUAL(
false,
true);
366 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
367 BOOST_REQUIRE_EQUAL(
false,
true);
371 close(request_socket);
372 TLOG(TLVL_INFO) <<
"Requests Test Case END";
376 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.