LCOV - code coverage report
Current view: top level - test/DAQrate - RequestSender_t.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 73.2 % 194 142
Test Date: 2025-09-04 00:45:34 Functions: 49.5 % 91 45

            Line data    Source code
       1              : #define BOOST_TEST_MODULE RequestSender_t
       2              : #include "boost/test/unit_test.hpp"
       3              : 
       4              : #include "tracemf.h"
       5              : #define TRACE_NAME "RequestSender_t"
       6              : 
       7              : #include "artdaq-core/Utilities/configureMessageFacility.hh"
       8              : #include "artdaq/DAQdata/TCPConnect.hh"
       9              : #include "artdaq/DAQdata/TCP_listen_fd.hh"
      10              : #include "artdaq/DAQrate/detail/RequestSender.hh"
      11              : #include "artdaq/DAQrate/detail/RoutingPacket.hh"
      12              : 
      13              : #include <sys/poll.h>
      14              : 
      15              : BOOST_AUTO_TEST_SUITE(RequestSender_test)
      16              : 
      17              : #define TRACE_REQUIRE_EQUAL(l, r)                                                                                                    \
      18              :         do                                                                                                                               \
      19              :         {                                                                                                                                \
      20              :                 if ((l) == (r))                                                                                                              \
      21              :                 {                                                                                                                            \
      22              :                         TLOG(TLVL_DEBUG) << __LINE__ << ": Checking if " << #l << " (" << (l) << ") equals " << #r << " (" << (r) << ")...YES!"; \
      23              :                 }                                                                                                                            \
      24              :                 else                                                                                                                         \
      25              :                 {                                                                                                                            \
      26              :                         TLOG(TLVL_ERROR) << __LINE__ << ": Checking if " << #l << " (" << (l) << ") equals " << #r << " (" << (r) << ")...NO!";  \
      27              :                 }                                                                                                                            \
      28              :                 BOOST_REQUIRE_EQUAL((l), (r));                                                                                               \
      29              :         } while (0)
      30              : 
      31            2 : BOOST_AUTO_TEST_CASE(Construct)
      32              : {
      33            1 :         artdaq::configureMessageFacility("RequestSender_t", true, true);
      34            2 :         metricMan->initialize(fhicl::ParameterSet());
      35            1 :         metricMan->do_start();
      36            3 :         TLOG(TLVL_INFO) << "Construct Test Case BEGIN";
      37            1 :         fhicl::ParameterSet pset;
      38            1 :         artdaq::RequestSender t(pset);
      39            1 :         BOOST_REQUIRE_EQUAL(t.GetRequestMode(), artdaq::detail::RequestMessageMode::Normal);
      40            3 :         TLOG(TLVL_INFO) << "Construct Test Case END";
      41            1 : }
      42              : 
      43              : // NOLINTNEXTLINE(readability-function-size)
      44            2 : BOOST_AUTO_TEST_CASE(Requests)
      45              : {
      46            1 :         artdaq::configureMessageFacility("RequestSender_t", true, true);
      47            2 :         metricMan->initialize(fhicl::ParameterSet());
      48            1 :         metricMan->do_start();
      49            3 :         TLOG(TLVL_INFO) << "Requests Test Case BEGIN";
      50            1 :         const int REQUEST_PORT = (artdaq::Globals::SeedAndRandom() % (32768 - 1024)) + 1024;
      51            1 :         const int DELAY_TIME = 100;
      52              : #if 0
      53              :         const std::string MULTICAST_IP = "227.28.12.28";
      54              : #else
      55            1 :         const std::string MULTICAST_IP = "localhost";
      56              : #endif
      57            1 :         fhicl::ParameterSet pset;
      58            2 :         pset.put("request_port", REQUEST_PORT);
      59            1 :         pset.put("request_delay_ms", DELAY_TIME);
      60            3 :         pset.put("send_requests", true);
      61            1 :         pset.put("request_address", MULTICAST_IP);
      62            1 :         artdaq::RequestSender t(pset);
      63              : 
      64            3 :         TLOG(TLVL_DEBUG) << "Opening request listener socket";
      65            1 :         auto request_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
      66              : 
      67              :         struct sockaddr_in si_me_request;
      68              : 
      69            1 :         int yes = 1;
      70            1 :         if (setsockopt(request_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
      71              :         {
      72            0 :                 TLOG(TLVL_ERROR) << "Unable to set reuse on request socket";
      73            0 :                 BOOST_REQUIRE_EQUAL(true, false);
      74            0 :                 return;
      75              :         }
      76            1 :         memset(&si_me_request, 0, sizeof(si_me_request));
      77            1 :         si_me_request.sin_family = AF_INET;
      78            1 :         si_me_request.sin_port = htons(REQUEST_PORT);
      79            1 :         si_me_request.sin_addr.s_addr = htonl(INADDR_ANY);
      80            1 :         if (bind(request_socket, reinterpret_cast<struct sockaddr*>(&si_me_request), sizeof(si_me_request)) == -1)  // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
      81              :         {
      82            0 :                 TLOG(TLVL_ERROR) << "Cannot bind request socket to port " << REQUEST_PORT;
      83            0 :                 BOOST_REQUIRE_EQUAL(true, false);
      84            0 :                 return;
      85              :         }
      86              : 
      87            1 :         if (MULTICAST_IP != "localhost")
      88              :         {
      89              :                 struct ip_mreq mreq;
      90            0 :                 int sts = ResolveHost(MULTICAST_IP.c_str(), mreq.imr_multiaddr);
      91            0 :                 if (sts == -1)
      92              :                 {
      93            0 :                         TLOG(TLVL_ERROR) << "Unable to resolve multicast request address";
      94            0 :                         BOOST_REQUIRE_EQUAL(true, false);
      95            0 :                         return;
      96              :                 }
      97            0 :                 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
      98            0 :                 if (setsockopt(request_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
      99              :                 {
     100            0 :                         TLOG(TLVL_ERROR) << "Unable to join multicast group";
     101            0 :                         BOOST_REQUIRE_EQUAL(true, false);
     102            0 :                         return;
     103              :                 }
     104              :         }
     105              : 
     106            3 :         TLOG(TLVL_DEBUG) << "Sending request";
     107            1 :         auto start_time = std::chrono::steady_clock::now();
     108            1 :         t.AddRequest(0, 0x10);
     109              :         struct pollfd ufds[1];
     110              : 
     111            3 :         TLOG(TLVL_DEBUG) << "Receiving Request";
     112            1 :         ufds[0].fd = request_socket;
     113            1 :         ufds[0].events = POLLIN | POLLPRI;
     114            1 :         int rv = poll(ufds, 1, 10000);
     115            1 :         if (rv > 0)
     116              :         {
     117            1 :                 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
     118              :                 {
     119            1 :                         auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
     120            1 :                         BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
     121            2 :                         TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
     122            1 :                         std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
     123            1 :                         artdaq::detail::RequestHeader hdr_buffer;
     124            1 :                         recv(request_socket, &buffer[0], buffer.size(), 0);
     125            1 :                         memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
     126            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
     127            4 :                         TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
     128              :                                             static_cast<uint8_t>(artdaq::detail::RequestMessageMode::Normal));
     129            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 1);
     130            1 :                         if (hdr_buffer.isValid())
     131              :                         {
     132            1 :                                 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
     133            1 :                                 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
     134              : 
     135            2 :                                 for (auto& buffer : pkt_buffer)
     136              :                                 {
     137            4 :                                         TRACE_REQUIRE_EQUAL(buffer.isValid(), true);
     138            4 :                                         TRACE_REQUIRE_EQUAL(buffer.sequence_id, 0);
     139            4 :                                         TRACE_REQUIRE_EQUAL(buffer.timestamp, 0x10);
     140              :                                 }
     141            1 :                         }
     142              :                         else
     143              :                         {
     144            0 :                                 TLOG(TLVL_ERROR) << "Invalid header received";
     145            0 :                                 BOOST_REQUIRE_EQUAL(false, true);
     146            0 :                                 return;
     147              :                         }
     148            2 :                 }
     149              :                 else
     150              :                 {
     151            0 :                         TLOG(TLVL_ERROR) << "Wrong event type from poll";
     152            0 :                         BOOST_REQUIRE_EQUAL(false, true);
     153            0 :                         return;
     154              :                 }
     155              :         }
     156              :         else
     157              :         {
     158            0 :                 TLOG(TLVL_ERROR) << "Timeout occured waiting for request";
     159            0 :                 BOOST_REQUIRE_EQUAL(false, true);
     160            0 :                 return;
     161              :         }
     162              : 
     163              :         // SetRequestMode and AddRequest BOTH send requests...
     164            1 :         start_time = std::chrono::steady_clock::now();
     165            1 :         t.SetRequestMode(artdaq::detail::RequestMessageMode::EndOfRun);
     166            1 :         t.AddRequest(2, 0x20);
     167            1 :         rv = poll(ufds, 1, 1000);
     168            1 :         if (rv > 0)
     169              :         {
     170            1 :                 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
     171              :                 {
     172            1 :                         auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
     173            1 :                         BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
     174            2 :                         TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
     175            1 :                         std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
     176            1 :                         artdaq::detail::RequestHeader hdr_buffer;
     177            1 :                         recv(request_socket, &buffer[0], buffer.size(), 0);
     178            1 :                         memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
     179            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
     180            4 :                         TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
     181              :                                             static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
     182            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 2);
     183            1 :                         if (hdr_buffer.isValid())
     184              :                         {
     185            1 :                                 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
     186            1 :                                 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
     187              : 
     188            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
     189            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
     190            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
     191            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(), true);
     192            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
     193            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
     194            1 :                         }
     195              :                         else
     196              :                         {
     197            0 :                                 TLOG(TLVL_ERROR) << "Invalid header received";
     198            0 :                                 BOOST_REQUIRE_EQUAL(false, true);
     199            0 :                                 return;
     200              :                         }
     201            2 :                 }
     202              :                 else
     203              :                 {
     204            0 :                         TLOG(TLVL_ERROR) << "Wrong event type from poll";
     205            0 :                         BOOST_REQUIRE_EQUAL(false, true);
     206            0 :                         return;
     207              :                 }
     208              :         }
     209              :         else
     210              :         {
     211            0 :                 TLOG(TLVL_ERROR) << "Timeout occured waiting for request";
     212            0 :                 BOOST_REQUIRE_EQUAL(false, true);
     213            0 :                 return;
     214              :         }
     215            1 :         rv = poll(ufds, 1, 1000);
     216            1 :         if (rv > 0)
     217              :         {
     218            1 :                 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
     219              :                 {
     220            1 :                         auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
     221            1 :                         BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
     222            2 :                         TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
     223            1 :                         std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
     224            1 :                         artdaq::detail::RequestHeader hdr_buffer;
     225            1 :                         recv(request_socket, &buffer[0], buffer.size(), 0);
     226            1 :                         memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
     227            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
     228            4 :                         TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
     229              :                                             static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
     230            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 2);
     231            1 :                         if (hdr_buffer.isValid())
     232              :                         {
     233            1 :                                 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
     234            1 :                                 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
     235              : 
     236            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
     237            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
     238            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
     239            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(), true);
     240            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
     241            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
     242            1 :                         }
     243              :                         else
     244              :                         {
     245            0 :                                 TLOG(TLVL_ERROR) << "Invalid header received";
     246            0 :                                 BOOST_REQUIRE_EQUAL(false, true);
     247            0 :                                 return;
     248              :                         }
     249            2 :                 }
     250              :                 else
     251              :                 {
     252            0 :                         TLOG(TLVL_ERROR) << "Wrong event type from poll";
     253            0 :                         BOOST_REQUIRE_EQUAL(false, true);
     254            0 :                         return;
     255              :                 }
     256              :         }
     257              :         else
     258              :         {
     259            0 :                 TLOG(TLVL_ERROR) << "Timeout occured waiting for request";
     260            0 :                 BOOST_REQUIRE_EQUAL(false, true);
     261            0 :                 return;
     262              :         }
     263              : 
     264            1 :         t.RemoveRequest(0);
     265            1 :         t.RemoveRequest(2);
     266            1 :         t.AddRequest(3, 0x30);
     267            1 :         start_time = std::chrono::steady_clock::now();
     268            1 :         rv = poll(ufds, 1, 1000);
     269            1 :         if (rv > 0)
     270              :         {
     271            1 :                 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
     272              :                 {
     273            1 :                         auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
     274            1 :                         BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
     275            2 :                         TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
     276            1 :                         std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
     277            1 :                         artdaq::detail::RequestHeader hdr_buffer;
     278            1 :                         recv(request_socket, &buffer[0], buffer.size(), 0);
     279            1 :                         memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
     280            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
     281            4 :                         TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
     282              :                                             static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
     283            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 1);
     284            1 :                         if (hdr_buffer.isValid())
     285              :                         {
     286            1 :                                 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
     287            1 :                                 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
     288              : 
     289            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
     290            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
     291            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
     292            1 :                         }
     293              :                         else
     294              :                         {
     295            0 :                                 TLOG(TLVL_ERROR) << "Invalid header received";
     296            0 :                                 BOOST_REQUIRE_EQUAL(false, true);
     297            0 :                                 return;
     298              :                         }
     299            2 :                 }
     300              :                 else
     301              :                 {
     302            0 :                         TLOG(TLVL_ERROR) << "Wrong event type from poll";
     303            0 :                         BOOST_REQUIRE_EQUAL(false, true);
     304            0 :                         return;
     305              :                 }
     306              :         }
     307              :         else
     308              :         {
     309            0 :                 TLOG(TLVL_ERROR) << "Timeout occured waiting for request";
     310            0 :                 BOOST_REQUIRE_EQUAL(false, true);
     311            0 :                 return;
     312              :         }
     313              : 
     314            1 :         close(request_socket);
     315            3 :         TLOG(TLVL_INFO) << "Requests Test Case END";
     316            1 :         artdaq::Globals::CleanUpGlobals();
     317            1 : }
     318              : 
     319              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1