LCOV - code coverage report
Current view: top level - test/DAQrate - RequestSender_t.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 74.1 % 166 123
Test Date: 2026-10-29 00:35:58 Functions: 50.7 % 69 35

            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 :         bool found_new_request = false;
     168            4 :         while (!found_new_request)
     169              :         {
     170            3 :                 rv = poll(ufds, 1, 1000);
     171            3 :                 if (rv > 0)
     172              :                 {
     173            3 :                         if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
     174              :                         {
     175            6 :                                 TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
     176            3 :                                 std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
     177            3 :                                 artdaq::detail::RequestHeader hdr_buffer;
     178            3 :                                 recv(request_socket, &buffer[0], buffer.size(), 0);
     179            3 :                                 memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
     180           12 :                                 TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
     181              : 
     182            3 :                                 if (hdr_buffer.packet_count == 1)
     183              :                                 {
     184            2 :                                         continue;
     185              :                                 }
     186            1 :                                 found_new_request = true;
     187            1 :                                 auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
     188            1 :                                 BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
     189            4 :                                 TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
     190              :                                                     static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
     191            4 :                                 TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 2);
     192            1 :                                 if (hdr_buffer.isValid())
     193              :                                 {
     194            1 :                                         std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
     195            1 :                                         memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
     196              : 
     197            4 :                                         TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
     198            4 :                                         TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 0);
     199            4 :                                         TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x10);
     200            4 :                                         TRACE_REQUIRE_EQUAL(pkt_buffer[1].isValid(), true);
     201            4 :                                         TRACE_REQUIRE_EQUAL(pkt_buffer[1].sequence_id, 2);
     202            4 :                                         TRACE_REQUIRE_EQUAL(pkt_buffer[1].timestamp, 0x20);
     203            1 :                                 }
     204              :                                 else
     205              :                                 {
     206            0 :                                         TLOG(TLVL_ERROR) << "Invalid header received";
     207            0 :                                         BOOST_REQUIRE_EQUAL(false, true);
     208            0 :                                         return;
     209              :                                 }
     210            4 :                         }
     211              :                         else
     212              :                         {
     213            0 :                                 TLOG(TLVL_ERROR) << "Wrong event type from poll";
     214            0 :                                 BOOST_REQUIRE_EQUAL(false, true);
     215            0 :                                 return;
     216              :                         }
     217              :                 }
     218              :                 else
     219              :                 {
     220            0 :                         TLOG(TLVL_ERROR) << "Timeout occured waiting for request";
     221            0 :                         BOOST_REQUIRE_EQUAL(false, true);
     222            0 :                         return;
     223              :                 }
     224              :         }
     225              : 
     226            1 :         t.RemoveRequest(0);
     227            1 :         t.RemoveRequest(2);
     228            1 :         t.AddRequest(3, 0x30);
     229            1 :         start_time = std::chrono::steady_clock::now();
     230            1 :         rv = poll(ufds, 1, 1000);
     231            1 :         if (rv > 0)
     232              :         {
     233            1 :                 if (ufds[0].revents == POLLIN || ufds[0].revents == POLLPRI)
     234              :                 {
     235            1 :                         auto delay_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count();
     236            1 :                         BOOST_REQUIRE_GE(delay_time, DELAY_TIME);
     237            2 :                         TLOG(TLVL_TRACE) << "Recieved packet on Request channel";
     238            1 :                         std::vector<uint8_t> buffer(MAX_REQUEST_MESSAGE_SIZE);
     239            1 :                         artdaq::detail::RequestHeader hdr_buffer;
     240            1 :                         recv(request_socket, &buffer[0], buffer.size(), 0);
     241            1 :                         memcpy(&hdr_buffer, &buffer[0], sizeof(artdaq::detail::RequestHeader));
     242            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.isValid(), true);
     243            4 :                         TRACE_REQUIRE_EQUAL(static_cast<uint8_t>(hdr_buffer.mode),
     244              :                                             static_cast<uint8_t>(artdaq::detail::RequestMessageMode::EndOfRun));
     245            4 :                         TRACE_REQUIRE_EQUAL(hdr_buffer.packet_count, 1);
     246            1 :                         if (hdr_buffer.isValid())
     247              :                         {
     248            1 :                                 std::vector<artdaq::detail::RequestPacket> pkt_buffer(hdr_buffer.packet_count);
     249            1 :                                 memcpy(&pkt_buffer[0], &buffer[sizeof(artdaq::detail::RequestHeader)], sizeof(artdaq::detail::RequestPacket) * hdr_buffer.packet_count);
     250              : 
     251            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].isValid(), true);
     252            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].sequence_id, 3);
     253            4 :                                 TRACE_REQUIRE_EQUAL(pkt_buffer[0].timestamp, 0x30);
     254            1 :                         }
     255              :                         else
     256              :                         {
     257            0 :                                 TLOG(TLVL_ERROR) << "Invalid header received";
     258            0 :                                 BOOST_REQUIRE_EQUAL(false, true);
     259            0 :                                 return;
     260              :                         }
     261            2 :                 }
     262              :                 else
     263              :                 {
     264            0 :                         TLOG(TLVL_ERROR) << "Wrong event type from poll";
     265            0 :                         BOOST_REQUIRE_EQUAL(false, true);
     266            0 :                         return;
     267              :                 }
     268              :         }
     269              :         else
     270              :         {
     271            0 :                 TLOG(TLVL_ERROR) << "Timeout occured waiting for request";
     272            0 :                 BOOST_REQUIRE_EQUAL(false, true);
     273            0 :                 return;
     274              :         }
     275              : 
     276            1 :         close(request_socket);
     277            3 :         TLOG(TLVL_INFO) << "Requests Test Case END";
     278            1 :         artdaq::Globals::CleanUpGlobals();
     279            1 : }
     280              : 
     281              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1