LCOV - code coverage report
Current view: top level - detdataformats/unittest - DAQHeader_test.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 100.0 % 103 103
Test Date: 2026-05-24 15:29:04 Functions: 100.0 % 17 17

            Line data    Source code
       1              : /**
       2              :  * @file DAQHeader_test.cxx DAQHeader class Unit Tests
       3              :  *
       4              :  * This is part of the DUNE DAQ Application Framework, copyright 2022.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : 
       9              : #include "detdataformats/DAQHeader.hpp"
      10              : 
      11              : #define BOOST_TEST_MODULE DAQHeader_test // NOLINT
      12              : 
      13              : #include "boost/test/unit_test.hpp"
      14              : 
      15              : #include <cstring>
      16              : #include <limits>
      17              : #include <sstream>
      18              : #include <string>
      19              : #include <tuple>
      20              : #include <utility>
      21              : #include <vector>
      22              : 
      23              : #pragma GCC diagnostic ignored "-Woverflow" // intentional overflows are performed as part of testing
      24              : 
      25              : using namespace dunedaq::detdataformats;
      26              : 
      27              : // Unit tests for a data formats library can expect to work with a lot of unsigned integers
      28              : // NOLINTBEGIN(build/unsigned)
      29              : 
      30              : namespace {
      31              : using word_t = DAQHeader::word_t;
      32              : 
      33              : DAQHeader
      34           11 : make_header(word_t version,
      35              :             word_t det_id,
      36              :             word_t crate_id,
      37              :             word_t slot_id,
      38              :             word_t link_id,
      39              :             word_t timestamp_1,
      40              :             word_t timestamp_2)
      41              : {
      42           11 :   DAQHeader header;
      43           11 :   header.version = version;
      44           11 :   header.det_id = det_id;
      45           11 :   header.crate_id = crate_id;
      46           11 :   header.slot_id = slot_id;
      47           11 :   header.link_id = link_id;
      48           11 :   header.timestamp_1 = timestamp_1;
      49           11 :   header.timestamp_2 = timestamp_2;
      50           11 :   return header;
      51              : }
      52              : 
      53              : std::pair<word_t, word_t>
      54            6 : split_timestamp(uint64_t timestamp)
      55              : {
      56            6 :   return { static_cast<word_t>(timestamp), static_cast<word_t>(timestamp >> 32) };
      57              : }
      58              : 
      59              : DAQHeader
      60            1 : header_from_stream_output(const std::string& output)
      61              : {
      62            1 :   std::istringstream iss(output);
      63              : 
      64            1 :   std::string version_token;
      65            1 :   std::string det_id_token;
      66            1 :   std::string crate_id_token;
      67            1 :   std::string slot_id_token;
      68            1 :   std::string link_id_token;
      69            1 :   std::string timestamp_label;
      70            1 :   uint64_t timestamp_value{};
      71              : 
      72            1 :   iss >> version_token >> det_id_token >> crate_id_token >> slot_id_token >> link_id_token >> timestamp_label >>
      73            1 :     timestamp_value;
      74              : 
      75            1 :   const auto [timestamp_1, timestamp_2] = split_timestamp(timestamp_value);
      76              : 
      77            5 :   return make_header(static_cast<word_t>(std::stoul(version_token.substr(std::string("Version:").size()))),
      78            2 :                      static_cast<word_t>(std::stoul(det_id_token.substr(std::string("DetID:").size()))),
      79            2 :                      static_cast<word_t>(std::stoul(crate_id_token.substr(std::string("CrateID:").size()))),
      80            2 :                      static_cast<word_t>(std::stoul(slot_id_token.substr(std::string("SlotID:").size()))),
      81            2 :                      static_cast<word_t>(std::stoul(link_id_token.substr(std::string("LinkID:").size()))),
      82              :                      timestamp_1,
      83            1 :                      timestamp_2);
      84            1 : }
      85              : } // namespace ""
      86              : 
      87              : BOOST_AUTO_TEST_SUITE(DAQHeader_test)
      88              : 
      89            2 : BOOST_AUTO_TEST_CASE(DefaultConstruction)
      90              : {
      91            1 :   DAQHeader header;
      92              : 
      93            1 :   BOOST_REQUIRE_EQUAL(header.timestamp_1, std::numeric_limits<word_t>::max());
      94            1 :   BOOST_REQUIRE_EQUAL(header.timestamp_2, std::numeric_limits<word_t>::max());
      95            1 :   BOOST_REQUIRE_EQUAL(header.get_timestamp(), std::numeric_limits<uint64_t>::max());
      96            1 : }
      97              : 
      98            2 : BOOST_AUTO_TEST_CASE(TimestampAssembly)
      99              : {
     100            1 :   DAQHeader header = make_header(0, 0, 0, 0, 0, 0x89ABCDEF, 0x01234567);
     101              : 
     102            1 :   BOOST_REQUIRE_EQUAL(header.get_timestamp(), 0x0123456789ABCDEFULL);
     103            1 : }
     104              : 
     105            2 : BOOST_AUTO_TEST_CASE(TimestampRoundTripFromGetTimestamp)
     106              : {
     107            1 :   const std::vector<std::pair<word_t, word_t>> values = { { 0x00000000u, 0x00000000u },
     108              :                                                           { 0xFFFFFFFFu, 0x00000000u },
     109              :                                                           { 0x00000000u, 0xFFFFFFFFu },
     110              :                                                           { 0x01234567u, 0x89ABCDEFu },
     111            1 :                                                           { 0xFFFFFFFFu, 0xFFFFFFFFu } };
     112              : 
     113            6 :   for (const auto& value : values) {
     114            5 :     const DAQHeader original = make_header(0, 0, 0, 0, 0, value.first, value.second);
     115            5 :     const uint64_t timestamp = original.get_timestamp();
     116            5 :     const auto [timestamp_1, timestamp_2] = split_timestamp(timestamp);
     117              : 
     118            5 :     BOOST_REQUIRE_EQUAL(timestamp_1, original.timestamp_1);
     119            5 :     BOOST_REQUIRE_EQUAL(timestamp_2, original.timestamp_2);
     120              :   }
     121            1 : }
     122              : 
     123            2 : BOOST_AUTO_TEST_CASE(BitfieldUpperBounds)
     124              : {
     125            1 :   DAQHeader header = make_header(63, 63, 1023, 15, 63, 0, 0);
     126              : 
     127            1 :   BOOST_REQUIRE_EQUAL(header.version, 63);
     128            1 :   BOOST_REQUIRE_EQUAL(header.det_id, 63);
     129            1 :   BOOST_REQUIRE_EQUAL(header.crate_id, 1023);
     130            1 :   BOOST_REQUIRE_EQUAL(header.slot_id, 15);
     131            1 :   BOOST_REQUIRE_EQUAL(header.link_id, 63);
     132            1 : }
     133              : 
     134            2 : BOOST_AUTO_TEST_CASE(BitfieldMasking)
     135              : {
     136            1 :   DAQHeader header = make_header(0, 0, 0, 0, 0, 0, 0);
     137              : 
     138            1 :   header.version = 99;    // NOLINT 99 & 0x3F = 35
     139            1 :   header.det_id = 127;    // NOLINT 127 & 0x3F = 63
     140            1 :   header.crate_id = 2048; // NOLINT 2048 & 0x3FF = 0
     141            1 :   header.slot_id = 31;    // NOLINT 31 & 0x0F = 15
     142            1 :   header.link_id = 65;    // NOLINT 65 & 0x3F = 1
     143              : 
     144            1 :   BOOST_REQUIRE_EQUAL(header.version, 35);
     145            1 :   BOOST_REQUIRE_EQUAL(header.det_id, 63);
     146            1 :   BOOST_REQUIRE_EQUAL(header.crate_id, 0);
     147            1 :   BOOST_REQUIRE_EQUAL(header.slot_id, 15);
     148            1 :   BOOST_REQUIRE_EQUAL(header.link_id, 1);
     149            1 : }
     150              : 
     151            2 : BOOST_AUTO_TEST_CASE(StreamOperatorRoundTrip)
     152              : {
     153            1 :   const DAQHeader original = make_header(7, 3, 22, 4, 9, 0x01234567, 0x89ABCDEF);
     154              : 
     155            1 :   std::ostringstream oss;
     156            1 :   oss << original;
     157            1 :   const std::string output = oss.str();
     158            1 :   const DAQHeader recovered = header_from_stream_output(output);
     159              : 
     160            1 :   BOOST_REQUIRE(!output.empty());
     161            1 :   BOOST_REQUIRE(output.back() == '\n');
     162              : 
     163            1 :   BOOST_REQUIRE_EQUAL(recovered.version, original.version);
     164            1 :   BOOST_REQUIRE_EQUAL(recovered.det_id, original.det_id);
     165            1 :   BOOST_REQUIRE_EQUAL(recovered.crate_id, original.crate_id);
     166            1 :   BOOST_REQUIRE_EQUAL(recovered.slot_id, original.slot_id);
     167            1 :   BOOST_REQUIRE_EQUAL(recovered.link_id, original.link_id);
     168            1 :   BOOST_REQUIRE_EQUAL(recovered.timestamp_1, original.timestamp_1);
     169            1 :   BOOST_REQUIRE_EQUAL(recovered.timestamp_2, original.timestamp_2);
     170            1 : }
     171              : 
     172            2 : BOOST_AUTO_TEST_CASE(ByteRoundTrip)
     173              : {
     174            1 :   const DAQHeader original = make_header(13, 21, 777, 10, 55, 0x11111111, 0x22222222);
     175              : 
     176            1 :   uint8_t buffer[sizeof(DAQHeader)]; // NOLINT(modernize-avoid-c-arrays)
     177            1 :   std::memcpy(buffer, &original, sizeof(DAQHeader));
     178              : 
     179            1 :   DAQHeader recovered;
     180            1 :   std::memcpy(&recovered, buffer, sizeof(DAQHeader));
     181              : 
     182            1 :   BOOST_REQUIRE_EQUAL(recovered.version, original.version);
     183            1 :   BOOST_REQUIRE_EQUAL(recovered.det_id, original.det_id);
     184            1 :   BOOST_REQUIRE_EQUAL(recovered.crate_id, original.crate_id);
     185            1 :   BOOST_REQUIRE_EQUAL(recovered.slot_id, original.slot_id);
     186            1 :   BOOST_REQUIRE_EQUAL(recovered.link_id, original.link_id);
     187            1 :   BOOST_REQUIRE_EQUAL(recovered.timestamp_1, original.timestamp_1);
     188            1 :   BOOST_REQUIRE_EQUAL(recovered.timestamp_2, original.timestamp_2);
     189            1 :   BOOST_REQUIRE_EQUAL(recovered.get_timestamp(), original.get_timestamp());
     190            1 : }
     191              : 
     192              : BOOST_AUTO_TEST_SUITE_END()
     193              : 
     194              : // NOLINTEND(build/unsigned)
        

Generated by: LCOV version 2.0-1