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