1 #define TRACE_NAME "RequestSender_t"
3 #include "artdaq/DAQrate/detail/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";
42 BOOST_AUTO_TEST_CASE(Requests)
44 artdaq::configureMessageFacility(
"RequestSender_t",
true,
true);
45 metricMan->initialize(fhicl::ParameterSet());
46 metricMan->do_start();
47 TLOG(TLVL_INFO) <<
"Requests Test Case BEGIN";
48 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
49 const int DELAY_TIME = 100;
51 const std::string MULTICAST_IP =
"227.28.12.28";
53 const std::string MULTICAST_IP =
"localhost";
55 fhicl::ParameterSet pset;
56 pset.put(
"request_port", REQUEST_PORT);
57 pset.put(
"request_delay_ms", DELAY_TIME);
58 pset.put(
"send_requests",
true);
59 pset.put(
"request_address", MULTICAST_IP);
62 TLOG(TLVL_DEBUG) <<
"Opening request listener socket";
63 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
65 struct sockaddr_in si_me_request;
68 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(yes)) < 0)
70 TLOG(TLVL_ERROR) <<
"Unable to set reuse on request socket";
71 BOOST_REQUIRE_EQUAL(
true,
false);
74 memset(&si_me_request, 0,
sizeof(si_me_request));
75 si_me_request.sin_family = AF_INET;
76 si_me_request.sin_port = htons(REQUEST_PORT);
77 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
78 if (bind(request_socket, reinterpret_cast<struct sockaddr*>(&si_me_request),
sizeof(si_me_request)) == -1)
80 TLOG(TLVL_ERROR) <<
"Cannot bind request socket to port " << REQUEST_PORT;
81 BOOST_REQUIRE_EQUAL(
true,
false);
85 if (MULTICAST_IP !=
"localhost")
88 int sts =
ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
91 TLOG(TLVL_ERROR) <<
"Unable to resolve multicast request address";
92 BOOST_REQUIRE_EQUAL(
true,
false);
95 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
96 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0)
98 TLOG(TLVL_ERROR) <<
"Unable to join multicast group";
99 BOOST_REQUIRE_EQUAL(
true,
false);
104 TLOG(TLVL_DEBUG) <<
"Sending request";
105 auto start_time = std::chrono::steady_clock::now();
106 t.AddRequest(0, 0x10);
107 struct pollfd ufds[1];
109 TLOG(TLVL_DEBUG) <<
"Receiving Request";
110 ufds[0].fd = request_socket;
111 ufds[0].events = POLLIN | POLLPRI;
112 int rv = poll(ufds, 1, 10000);
115 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
117 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
118 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
119 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
120 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
122 recv(request_socket, &buffer[0], buffer.size(), 0);
124 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
125 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
130 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
133 for (
auto& buffer : pkt_buffer)
135 TRACE_REQUIRE_EQUAL(buffer.isValid(),
true);
136 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
137 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
142 TLOG(TLVL_ERROR) <<
"Invalid header received";
143 BOOST_REQUIRE_EQUAL(
false,
true);
149 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
150 BOOST_REQUIRE_EQUAL(
false,
true);
156 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
157 BOOST_REQUIRE_EQUAL(
false,
true);
162 start_time = std::chrono::steady_clock::now();
164 t.AddRequest(2, 0x20);
165 rv = poll(ufds, 1, 1000);
168 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
170 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
171 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
172 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
173 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
175 recv(request_socket, &buffer[0], buffer.size(), 0);
177 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
178 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
183 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
186 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
187 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
188 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
189 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
190 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
191 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
195 TLOG(TLVL_ERROR) <<
"Invalid header received";
196 BOOST_REQUIRE_EQUAL(
false,
true);
202 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
203 BOOST_REQUIRE_EQUAL(
false,
true);
209 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
210 BOOST_REQUIRE_EQUAL(
false,
true);
213 rv = poll(ufds, 1, 1000);
216 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
218 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
219 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
220 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
221 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
223 recv(request_socket, &buffer[0], buffer.size(), 0);
225 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
226 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
231 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
234 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
235 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
236 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
237 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(),
true);
238 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
239 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
243 TLOG(TLVL_ERROR) <<
"Invalid header received";
244 BOOST_REQUIRE_EQUAL(
false,
true);
250 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
251 BOOST_REQUIRE_EQUAL(
false,
true);
257 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
258 BOOST_REQUIRE_EQUAL(
false,
true);
264 t.AddRequest(3, 0x30);
265 start_time = std::chrono::steady_clock::now();
266 rv = poll(ufds, 1, 1000);
269 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
271 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
272 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
273 TLOG(TLVL_TRACE) <<
"Recieved packet on Request channel";
274 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
276 recv(request_socket, &buffer[0], buffer.size(), 0);
278 TRACE_REQUIRE_EQUAL(hdr_buffer.
isValid(),
true);
279 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.
mode),
284 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.
packet_count);
287 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(),
true);
288 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
289 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
293 TLOG(TLVL_ERROR) <<
"Invalid header received";
294 BOOST_REQUIRE_EQUAL(
false,
true);
300 TLOG(TLVL_ERROR) <<
"Wrong event type from poll";
301 BOOST_REQUIRE_EQUAL(
false,
true);
307 TLOG(TLVL_ERROR) <<
"Timeout occured waiting for request";
308 BOOST_REQUIRE_EQUAL(
false,
true);
312 close(request_socket);
313 TLOG(TLVL_INFO) <<
"Requests Test Case END";
317 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. ...
The RequestPacket contains information about a single data request.