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);
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.rank, 0);
00081
00082 my_rank = 13;
00083 t.SendRoutingToken(335);
00084
00085 sts = read(conn_sock, &buff, sizeof(artdaq::detail::RoutingToken));
00086
00087 TRACE_REQUIRE_EQUAL(sts, sizeof(artdaq::detail::RoutingToken));
00088 TRACE_REQUIRE_EQUAL(buff.header, TOKEN_MAGIC);
00089 TRACE_REQUIRE_EQUAL(buff.new_slots_free, 335);
00090 TRACE_REQUIRE_EQUAL(buff.rank, 13);
00091
00092 close(conn_sock);
00093 close(token_socket);
00094 TLOG(TLVL_INFO) << "Tokens Test Case END";
00095 }
00096
00097 BOOST_AUTO_TEST_CASE(Requests)
00098 {
00099 artdaq::configureMessageFacility("RequestSender_t", true, true);
00100 metricMan->initialize(fhicl::ParameterSet());
00101 metricMan->do_start();
00102 TLOG(TLVL_INFO) << "Requests Test Case BEGIN" ;
00103 const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
00104 const int DELAY_TIME = 100;
00105 #if 0
00106 const std::string MULTICAST_IP = "227.28.12.28";
00107 #else
00108 const std::string MULTICAST_IP = "localhost";
00109 #endif
00110 fhicl::ParameterSet pset;
00111 pset.put("request_port", REQUEST_PORT);
00112 pset.put("request_delay_ms", DELAY_TIME);
00113 pset.put("send_requests", true);
00114 pset.put("request_address", MULTICAST_IP);
00115 artdaq::RequestSender t(pset);
00116
00117
00118 TLOG(TLVL_DEBUG) << "Opening request listener socket" ;
00119 auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
00120
00121 struct sockaddr_in si_me_request;
00122
00123 int yes = 1;
00124 if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
00125 {
00126 TLOG(TLVL_ERROR) << "Unable to set reuse on request socket" ;
00127 BOOST_REQUIRE_EQUAL(true, false);
00128 return;
00129 }
00130 memset(&si_me_request, 0, sizeof(si_me_request));
00131 si_me_request.sin_family = AF_INET;
00132 si_me_request.sin_port = htons(REQUEST_PORT);
00133 si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
00134 if (bind(request_socket, (struct sockaddr *)&si_me_request, sizeof(si_me_request)) == -1)
00135 {
00136 TLOG(TLVL_ERROR) << "Cannot bind request socket to port " << REQUEST_PORT ;
00137 BOOST_REQUIRE_EQUAL(true, false);
00138 return;
00139 }
00140
00141 if (MULTICAST_IP != "localhost")
00142 {
00143 struct ip_mreq mreq;
00144 int sts = ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
00145 if (sts == -1)
00146 {
00147 TLOG(TLVL_ERROR) << "Unable to resolve multicast request address" ;
00148 BOOST_REQUIRE_EQUAL(true, false);
00149 return;
00150 }
00151 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
00152 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
00153 {
00154 TLOG(TLVL_ERROR) << "Unable to join multicast group" ;
00155 BOOST_REQUIRE_EQUAL(true, false);
00156 return;
00157 }
00158 }
00159
00160 TLOG(TLVL_DEBUG) << "Sending request" ;
00161 auto start_time = std::chrono::steady_clock::now();
00162 t.AddRequest(0, 0x10);
00163 struct pollfd ufds[1];
00164
00165 TLOG(TLVL_DEBUG) << "Receiving Request" ;
00166 ufds[0].fd = request_socket;
00167 ufds[0].events = POLLIN | POLLPRI;
00168 int rv = poll(ufds, 1, 10000);
00169 if (rv > 0)
00170 {
00171 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00172 {
00173 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00174 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00175 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00176 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00177 artdaq::detail::RequestHeader hdr_buffer;
00178 recv(request_socket, &buffer[0], buffer.size(), 0);
00179 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00180 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00181 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00182 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::Normal));
00183 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 1);
00184 if (hdr_buffer.isValid())
00185 {
00186
00187 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00188 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00189
00190 for (auto& buffer : pkt_buffer)
00191 {
00192 TRACE_REQUIRE_EQUAL(buffer.isValid(), true);
00193 TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
00194 TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
00195 }
00196 }
00197 else
00198 {
00199 TLOG(TLVL_ERROR) << "Invalid header received" ;
00200 BOOST_REQUIRE_EQUAL(false, true);
00201 return;
00202 }
00203 }
00204 else
00205 {
00206 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00207 BOOST_REQUIRE_EQUAL(false, true);
00208 return;
00209 }
00210 }
00211 else
00212 {
00213 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00214 BOOST_REQUIRE_EQUAL(false, true);
00215 return;
00216 }
00217
00218
00219 start_time = std::chrono::steady_clock::now();
00220 t.SetRequestMode(artdaq::detail::RequestMessageMode::EndOfRun);
00221 t.AddRequest(2, 0x20);
00222 rv = poll(ufds, 1, 1000);
00223 if (rv > 0)
00224 {
00225 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00226 {
00227 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00228 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00229 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00230 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00231 artdaq::detail::RequestHeader hdr_buffer;
00232 recv(request_socket, &buffer[0], buffer.size(), 0);
00233 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00234 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00235 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00236 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
00237 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 2);
00238 if (hdr_buffer.isValid())
00239 {
00240
00241 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00242 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00243
00244 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
00245 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
00246 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
00247 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(), true);
00248 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
00249 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
00250
00251 }
00252 else
00253 {
00254 TLOG(TLVL_ERROR) << "Invalid header received" ;
00255 BOOST_REQUIRE_EQUAL(false, true);
00256 return;
00257 }
00258 }
00259 else
00260 {
00261 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00262 BOOST_REQUIRE_EQUAL(false, true);
00263 return;
00264 }
00265 }
00266 else
00267 {
00268 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00269 BOOST_REQUIRE_EQUAL(false, true);
00270 return;
00271 }
00272 rv = poll(ufds, 1, 1000);
00273 if (rv > 0)
00274 {
00275 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00276 {
00277 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00278 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00279 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00280 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00281 artdaq::detail::RequestHeader hdr_buffer;
00282 recv(request_socket, &buffer[0], buffer.size(), 0);
00283 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00284 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00285 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00286 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
00287 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 2);
00288 if (hdr_buffer.isValid())
00289 {
00290
00291 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00292 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00293
00294 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
00295 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
00296 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
00297 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(), true);
00298 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
00299 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
00300
00301 }
00302 else
00303 {
00304 TLOG(TLVL_ERROR) << "Invalid header received" ;
00305 BOOST_REQUIRE_EQUAL(false, true);
00306 return;
00307 }
00308 }
00309 else
00310 {
00311 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00312 BOOST_REQUIRE_EQUAL(false, true);
00313 return;
00314 }
00315 }
00316 else
00317 {
00318 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00319 BOOST_REQUIRE_EQUAL(false, true);
00320 return;
00321 }
00322
00323 t.RemoveRequest(0);
00324 t.RemoveRequest(2);
00325 t.AddRequest(3, 0x30);
00326 start_time = std::chrono::steady_clock::now();
00327 rv = poll(ufds, 1, 1000);
00328 if (rv > 0)
00329 {
00330 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
00331 {
00332 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
00333 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
00334 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
00335 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
00336 artdaq::detail::RequestHeader hdr_buffer;
00337 recv(request_socket, &buffer[0], buffer.size(), 0);
00338 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
00339 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
00340 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
00341 static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
00342 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 1);
00343 if (hdr_buffer.isValid())
00344 {
00345
00346 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
00347 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
00348
00349 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
00350 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
00351 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
00352
00353 }
00354 else
00355 {
00356 TLOG(TLVL_ERROR) << "Invalid header received" ;
00357 BOOST_REQUIRE_EQUAL(false, true);
00358 return;
00359 }
00360 }
00361 else
00362 {
00363 TLOG(TLVL_ERROR) << "Wrong event type from poll" ;
00364 BOOST_REQUIRE_EQUAL(false, true);
00365 return;
00366 }
00367 }
00368 else
00369 {
00370 TLOG(TLVL_ERROR) << "Timeout occured waiting for request" ;
00371 BOOST_REQUIRE_EQUAL(false, true);
00372 return;
00373 }
00374
00375 close(request_socket);
00376 TLOG(TLVL_INFO) << "Requests Test Case END";
00377 artdaq::Globals::CleanUpGlobals();
00378 }
00379
00380 BOOST_AUTO_TEST_SUITE_END()