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