00001 #define TRACE_NAME "RequestSender_t"
00002
00003 #include "artdaq/DAQrate/RequestSender.hh"
00004
00005 #define BOOST_TEST_MODULE RequestSender_t
00006 #include "cetlib/quiet_unit_test.hpp"
00007 #include "cetlib_except/exception.h"
00008 #include "artdaq/DAQdata/TCP_listen_fd.hh"
00009 #include "artdaq/DAQrate/detail/RoutingPacket.hh"
00010 #include "artdaq/DAQdata/TCPConnect.hh"
00011 #include <sys/poll.h>
00012
00013
00014 BOOST_AUTO_TEST_SUITE(RequestSender_test)
00015
00016 #define TRACE_REQUIRE_EQUAL(l,r) do { \
00017 if(l == r) { \
00018 TLOG(TLVL_DEBUG) << __LINE__ << ": Checking if " << #l << " (" << l << ") equals " << #r << " (" << r << ")...YES!" ; \
00019 } \
00020 else \
00021 { \
00022 TLOG(TLVL_ERROR) << __LINE__ << ": Checking if " << #l << " (" << l << ") equals " << #r << " (" << r << ")...NO!" ; \
00023 } \
00024 BOOST_REQUIRE_EQUAL(l, r); \
00025 } while(0)
00026
00027 BOOST_AUTO_TEST_CASE(Construct)
00028 {
00029 artdaq::configureMessageFacility("RequestSender_t", true, true);
00030 metricMan->initialize(fhicl::ParameterSet());
00031 metricMan->do_start();
00032 TLOG(TLVL_INFO) << "Construct Test Case BEGIN" ;
00033 fhicl::ParameterSet pset;
00034 artdaq::RequestSender t(pset);
00035 BOOST_REQUIRE_EQUAL(t.GetRequestMode(), artdaq::detail::RequestMessageMode::Normal);
00036 TLOG(TLVL_INFO) << "Construct Test Case END";
00037 }
00038
00039 BOOST_AUTO_TEST_CASE(Tokens)
00040 {
00041 artdaq::configureMessageFacility("RequestSender_t", true, true);
00042 metricMan->initialize(fhicl::ParameterSet());
00043 metricMan->do_start();
00044 TLOG(TLVL_INFO) << "Tokens Test Case BEGIN" ;
00045 const int TOKEN_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
00046 TLOG(TLVL_DEBUG) << "Opening token listener socket" ;
00047 auto token_socket = TCP_listen_fd(TOKEN_PORT, 3 * sizeof(artdaq::detail::RoutingToken));
00048
00049 fhicl::ParameterSet token_pset;
00050 token_pset.put("routing_token_port", TOKEN_PORT);
00051 token_pset.put("use_routing_master", true);
00052 fhicl::ParameterSet pset;
00053 pset.put("routing_token_config", token_pset);
00054 artdaq::RequestSender t(pset);
00055
00056 my_rank = 0;
00057
00058
00059 BOOST_REQUIRE(token_socket != -1);
00060 if (token_socket == -1)
00061 {
00062 TLOG(TLVL_ERROR) << "Token listener socket was not opened successfully." ;
00063 BOOST_REQUIRE_EQUAL(false, true);
00064 return;
00065 }
00066
00067 TLOG(TLVL_DEBUG) << "Accepting new connection on token_socket" ;
00068 sockaddr_in addr;
00069 socklen_t arglen = sizeof(addr);
00070 auto conn_sock = accept(token_socket, (struct sockaddr*)&addr, &arglen);
00071
00072 t.SendRoutingToken(120, 130);
00073
00074 artdaq::detail::RoutingToken buff;
00075 auto sts = read(conn_sock, &buff, sizeof(artdaq::detail::RoutingToken));
00076
00077 TRACE_REQUIRE_EQUAL(sts, sizeof(artdaq::detail::RoutingToken));
00078 TRACE_REQUIRE_EQUAL(buff.header, TOKEN_MAGIC);
00079 TRACE_REQUIRE_EQUAL(buff.new_slots_free, 120);
00080 TRACE_REQUIRE_EQUAL(buff.run_number, 130);
00081 TRACE_REQUIRE_EQUAL(buff.rank, 0);
00082
00083 my_rank = 13;
00084 t.SendRoutingToken(335, 17);
00085
00086 sts = read(conn_sock, &buff, sizeof(artdaq::detail::RoutingToken));
00087
00088 TRACE_REQUIRE_EQUAL(sts, sizeof(artdaq::detail::RoutingToken));
00089 TRACE_REQUIRE_EQUAL(buff.header, TOKEN_MAGIC);
00090 TRACE_REQUIRE_EQUAL(buff.new_slots_free, 335);
00091 TRACE_REQUIRE_EQUAL(buff.run_number, 17);
00092 TRACE_REQUIRE_EQUAL(buff.rank, 13);
00093
00094 close(conn_sock);
00095 close(token_socket);
00096 TLOG(TLVL_INFO) << "Tokens Test Case END";
00097 }
00098
00099 BOOST_AUTO_TEST_CASE(Requests)
00100 {
00101 artdaq::configureMessageFacility("RequestSender_t", true, true);
00102 metricMan->initialize(fhicl::ParameterSet());
00103 metricMan->do_start();
00104 TLOG(TLVL_INFO) << "Requests Test Case BEGIN" ;
00105 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
00106 const int DELAY_TIME = 100;
00107 #if 0
00108 const std::string MULTICAST_IP = "227.28.12.28";
00109 #else
00110 const std::string MULTICAST_IP = "localhost";
00111 #endif
00112 fhicl::ParameterSet pset;
00113 pset.put("request_port", REQUEST_PORT);
00114 pset.put("request_delay_ms", DELAY_TIME);
00115 pset.put("send_requests", true);
00116 pset.put("request_address", MULTICAST_IP);
00117 artdaq::RequestSender t(pset);
00118
00119
00120 TLOG(TLVL_DEBUG) << "Opening request listener socket" ;
00121 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
00122
00123 struct sockaddr_in si_me_request;
00124
00125 int yes = 1;
00126 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
00127 {
00128 TLOG(TLVL_ERROR) << "Unable to set reuse on request socket" ;
00129 BOOST_REQUIRE_EQUAL(true, false);
00130 return;
00131 }
00132 memset(&si_me_request, 0, sizeof(si_me_request));
00133 si_me_request.sin_family = AF_INET;
00134 si_me_request.sin_port = htons(REQUEST_PORT);
00135 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
00136 if (bind(request_socket, (struct sockaddr *)&si_me_request, sizeof(si_me_request)) == -1)
00137 {
00138 TLOG(TLVL_ERROR) << "Cannot bind request socket to port " << REQUEST_PORT ;
00139 BOOST_REQUIRE_EQUAL(true, false);
00140 return;
00141 }
00142
00143 if (MULTICAST_IP != "localhost")
00144 {
00145 struct ip_mreq mreq;
00146 int sts = ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
00147 if (sts == -1)
00148 {
00149 TLOG(TLVL_ERROR) << "Unable to resolve multicast request address" ;
00150 BOOST_REQUIRE_EQUAL(true, false);
00151 return;
00152 }
00153 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
00154 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
00155 {
00156 TLOG(TLVL_ERROR) << "Unable to join multicast group" ;
00157 BOOST_REQUIRE_EQUAL(true, false);
00158 return;
00159 }
00160 }
00161
00162 TLOG(TLVL_DEBUG) << "Sending request" ;
00163 auto start_time = std::chrono::steady_clock::now();
00164 t.AddRequest(0, 0x10);
00165 struct pollfd ufds[1];
00166
00167 TLOG(TLVL_DEBUG) << "Receiving Request" ;
00168 ufds[0].fd = request_socket;
00169 ufds[0].events = POLLIN | POLLPRI;
00170 int rv = poll(ufds, 1, 10000);
00171 if (rv > 0)
00172 {
00173 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00174 {
00175 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00176 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00177 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00178 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00179 artdaq::detail::RequestHeader hdr_buffer;
00180 recv(request_socket, &buffer[0], buffer.size(), 0);
00181 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00182 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00183 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00184 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::Normal));
00185 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 1);
00186 if (hdr_buffer.isValid())
00187 {
00188
00189 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00190 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00191
00192 for (auto& buffer : pkt_buffer)
00193 {
00194 TRACE_REQUIRE_EQUAL(buffer.isValid(), true);
00195 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
00196 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
00197 }
00198 }
00199 else
00200 {
00201 TLOG(TLVL_ERROR) << "Invalid header received" ;
00202 BOOST_REQUIRE_EQUAL(false, true);
00203 return;
00204 }
00205 }
00206 else
00207 {
00208 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00209 BOOST_REQUIRE_EQUAL(false, true);
00210 return;
00211 }
00212 }
00213 else
00214 {
00215 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00216 BOOST_REQUIRE_EQUAL(false, true);
00217 return;
00218 }
00219
00220
00221 start_time = std::chrono::steady_clock::now();
00222 t.SetRequestMode(artdaq::detail::RequestMessageMode::EndOfRun);
00223 t.AddRequest(2, 0x20);
00224 rv = poll(ufds, 1, 1000);
00225 if (rv > 0)
00226 {
00227 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00228 {
00229 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00230 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00231 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00232 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00233 artdaq::detail::RequestHeader hdr_buffer;
00234 recv(request_socket, &buffer[0], buffer.size(), 0);
00235 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00236 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00237 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00238 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
00239 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 2);
00240 if (hdr_buffer.isValid())
00241 {
00242
00243 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00244 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00245
00246 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
00247 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
00248 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
00249 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(), true);
00250 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
00251 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
00252
00253 }
00254 else
00255 {
00256 TLOG(TLVL_ERROR) << "Invalid header received" ;
00257 BOOST_REQUIRE_EQUAL(false, true);
00258 return;
00259 }
00260 }
00261 else
00262 {
00263 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00264 BOOST_REQUIRE_EQUAL(false, true);
00265 return;
00266 }
00267 }
00268 else
00269 {
00270 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00271 BOOST_REQUIRE_EQUAL(false, true);
00272 return;
00273 }
00274 rv = poll(ufds, 1, 1000);
00275 if (rv > 0)
00276 {
00277 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00278 {
00279 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00280 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00281 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00282 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00283 artdaq::detail::RequestHeader hdr_buffer;
00284 recv(request_socket, &buffer[0], buffer.size(), 0);
00285 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00286 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00287 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00288 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
00289 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 2);
00290 if (hdr_buffer.isValid())
00291 {
00292
00293 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00294 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00295
00296 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
00297 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
00298 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
00299 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(), true);
00300 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
00301 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
00302
00303 }
00304 else
00305 {
00306 TLOG(TLVL_ERROR) << "Invalid header received" ;
00307 BOOST_REQUIRE_EQUAL(false, true);
00308 return;
00309 }
00310 }
00311 else
00312 {
00313 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00314 BOOST_REQUIRE_EQUAL(false, true);
00315 return;
00316 }
00317 }
00318 else
00319 {
00320 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00321 BOOST_REQUIRE_EQUAL(false, true);
00322 return;
00323 }
00324
00325 t.RemoveRequest(0);
00326 t.RemoveRequest(2);
00327 t.AddRequest(3, 0x30);
00328 start_time = std::chrono::steady_clock::now();
00329 rv = poll(ufds, 1, 1000);
00330 if (rv > 0)
00331 {
00332 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00333 {
00334 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00335 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00336 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00337 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00338 artdaq::detail::RequestHeader hdr_buffer;
00339 recv(request_socket, &buffer[0], buffer.size(), 0);
00340 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00341 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00342 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00343 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
00344 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 1);
00345 if (hdr_buffer.isValid())
00346 {
00347
00348 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00349 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00350
00351 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
00352 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
00353 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
00354
00355 }
00356 else
00357 {
00358 TLOG(TLVL_ERROR) << "Invalid header received" ;
00359 BOOST_REQUIRE_EQUAL(false, true);
00360 return;
00361 }
00362 }
00363 else
00364 {
00365 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00366 BOOST_REQUIRE_EQUAL(false, true);
00367 return;
00368 }
00369 }
00370 else
00371 {
00372 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00373 BOOST_REQUIRE_EQUAL(false, true);
00374 return;
00375 }
00376
00377 close(request_socket);
00378 TLOG(TLVL_INFO) << "Requests Test Case END";
00379 artdaq::Globals::CleanUpGlobals();
00380 }
00381
00382 BOOST_AUTO_TEST_SUITE_END()