LCOV - code coverage report
Current view: top level - hdf5libs/unittest - HDF5WriteReadTriggerRecord_test.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 99.6 % 284 283
Test Date: 2025-12-21 13:07:08 Functions: 100.0 % 25 25

            Line data    Source code
       1              : /**
       2              :  * @file HDF5WriteReadTriggerRecord_test.cxx Application that tests and demonstrates
       3              :  * the write/read functions of the HDF5RawDataFile class.
       4              :  *
       5              :  * This is part of the DUNE DAQ Application Framework, copyright 2020.
       6              :  * Licensing/copyright details are in the COPYING file that you should have
       7              :  * received with this code.
       8              :  */
       9              : 
      10              : #include "hdf5libs/HDF5RawDataFile.hpp"
      11              : #include "hdf5libs/test/HDF5TestUtils.hpp"
      12              : 
      13              : #include "detdataformats/DetID.hpp"
      14              : 
      15              : #define BOOST_TEST_MODULE HDF5WriteReadTriggerRecord_test // NOLINT
      16              : 
      17              : #include "boost/test/unit_test.hpp"
      18              : 
      19              : #include <cstdlib>
      20              : #include <filesystem>
      21              : #include <fstream>
      22              : #include <iostream>
      23              : #include <memory>
      24              : #include <regex>
      25              : #include <string>
      26              : #include <utility>
      27              : #include <vector>
      28              : 
      29              : using namespace dunedaq::hdf5libs;
      30              : 
      31              : constexpr int run_number = 53;
      32              : constexpr int file_index = 0;
      33              : const std::string application_name = "HDF5WriteReadTriggerRecord_test";
      34              : constexpr size_t fragment_size = 100;
      35              : constexpr size_t element_count_tpc = 4;
      36              : constexpr size_t element_count_pds = 4;
      37              : constexpr size_t element_count_ta = 4;
      38              : constexpr size_t element_count_tc = 1;
      39              : size_t compressed_raw_data_size;
      40              : size_t uncompressed_raw_data_size;
      41              : 
      42              : const size_t components_per_record = element_count_tpc + element_count_pds + element_count_ta + element_count_tc;
      43              : 
      44              : HDF5FileLayoutParameters
      45            8 : create_file_layout_params()
      46              : {
      47            8 :   dunedaq::hdf5libs::HDF5PathParameters params_tpc;
      48            8 :   params_tpc.detector_group_type = "Detector_Readout";
      49            8 :   params_tpc.detector_group_name = "TPC";
      50            8 :   params_tpc.element_name_prefix = "Link";
      51            8 :   params_tpc.digits_for_element_number = 5;
      52              : 
      53              :   // dunedaq::hdf5libs::hdf5filelayout::PathParams params_pds;
      54              :   // params_pds.detector_group_type = "PDS";
      55              :   // params_pds.detector_group_name = "PDS";
      56              :   // params_pds.element_name_prefix = "Element";
      57              :   // params_pds.digits_for_element_number = 5;
      58              : 
      59              :   // note, for unit test json equality checks, 'PDS' needs to come before
      60              :   //'TPC', as on reading back the filelayout it looks like it's alphabetical.
      61            8 :   std::vector<dunedaq::hdf5libs::HDF5PathParameters> param_list;
      62              :   // param_list.push_back(params_pds);
      63            8 :   param_list.push_back(params_tpc);
      64              : 
      65            8 :   dunedaq::hdf5libs::HDF5FileLayoutParameters layout_params;
      66            8 :   layout_params.path_params_list = param_list;
      67            8 :   layout_params.record_name_prefix = "TriggerRecord";
      68            8 :   layout_params.digits_for_record_number = 6;
      69            8 :   layout_params.digits_for_sequence_number = 4;
      70            8 :   layout_params.record_header_dataset_name = "TriggerRecordHeader";
      71              : 
      72            8 :   return layout_params;
      73            8 : }
      74              : 
      75              : std::vector<dunedaq::daqdataformats::ComponentRequest>
      76           40 : create_component_requests(dunedaq::daqdataformats::timestamp_t ts)
      77              : {
      78           40 :   std::vector<dunedaq::daqdataformats::ComponentRequest> components;
      79              :   // loop over elements tpc
      80          200 :   for (size_t ele_num = 0; ele_num < element_count_tpc; ++ele_num) {
      81              : 
      82          160 :     auto sid =
      83          160 :       dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout, ele_num);
      84              : 
      85          160 :     components.emplace_back(sid, ts, ts);
      86              : 
      87              :   } // end loop over elements
      88              : 
      89              :   // loop over elements pds
      90          200 :   for (size_t ele_num = 0; ele_num < element_count_pds; ++ele_num) {
      91          320 :     auto sid = dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout,
      92          160 :                                                  ele_num + element_count_tpc);
      93              : 
      94          160 :     components.emplace_back(sid, ts, ts);
      95              : 
      96              :   } // end loop over elements
      97              : 
      98              :   // loop over TriggerActivity
      99          200 :   for (size_t ele_num = 0; ele_num < element_count_ta; ++ele_num) {
     100              : 
     101          160 :     auto sid = dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kTrigger, ele_num);
     102              : 
     103          160 :     components.emplace_back(sid, ts, ts);
     104              : 
     105              :   } // end loop over elements
     106              : 
     107              :   // loop over TriggerCandidate
     108           80 :   for (size_t ele_num = 0; ele_num < element_count_tc; ++ele_num) {
     109              : 
     110           80 :     auto sid = dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kTrigger,
     111           40 :                                                  ele_num + element_count_ta);
     112              : 
     113           40 :     components.emplace_back(sid, ts, ts);
     114              : 
     115              :   } // end loop over elements
     116           40 :   return components;
     117            0 : }
     118              : 
     119              : dunedaq::daqdataformats::TriggerRecord
     120           40 : create_trigger_record(uint64_t trig_num)
     121              : {
     122              :   // setup our dummy_data
     123           40 :   std::vector<char> dummy_vector(fragment_size);
     124           40 :   char* dummy_data = dummy_vector.data();
     125              : 
     126              :   // get a timestamp for this trigger
     127           40 :   int64_t ts = std::chrono::duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count();
     128              : 
     129              :   // create TriggerRecordHeader
     130           40 :   dunedaq::daqdataformats::TriggerRecordHeader trh(create_component_requests(ts));
     131           40 :   trh.set_trigger_number(trig_num);
     132           40 :   trh.set_trigger_timestamp(ts);
     133           40 :   trh.set_run_number(run_number);
     134           40 :   trh.set_sequence_number(0);
     135           40 :   trh.set_max_sequence_number(1);
     136           40 :   trh.set_element_id(dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kTRBuilder, 0));
     137              : 
     138              :   // create our TriggerRecord
     139           40 :   dunedaq::daqdataformats::TriggerRecord tr(trh);
     140              : 
     141              :   // loop over elements tpc
     142          200 :   for (size_t ele_num = 0; ele_num < element_count_tpc; ++ele_num) {
     143              : 
     144              :     // create our fragment
     145          160 :     dunedaq::daqdataformats::FragmentHeader fh;
     146          160 :     fh.trigger_number = trig_num;
     147          160 :     fh.trigger_timestamp = ts;
     148          160 :     fh.window_begin = ts;
     149          160 :     fh.window_end = ts;
     150          160 :     fh.run_number = run_number;
     151          160 :     fh.fragment_type =
     152              :       static_cast<dunedaq::daqdataformats::fragment_type_t>(dunedaq::daqdataformats::FragmentType::kWIB);
     153          160 :     fh.sequence_number = 0;
     154          160 :     fh.detector_id = static_cast<uint16_t>(dunedaq::detdataformats::DetID::Subdetector::kHD_TPC);
     155          320 :     fh.element_id =
     156          160 :       dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout, ele_num);
     157              : 
     158          160 :     std::unique_ptr<dunedaq::daqdataformats::Fragment> frag_ptr(
     159          160 :       new dunedaq::daqdataformats::Fragment(dummy_data, fragment_size));
     160          160 :     frag_ptr->set_header_fields(fh);
     161              : 
     162              :     // add fragment to TriggerRecord
     163          160 :     tr.add_fragment(std::move(frag_ptr));
     164              : 
     165          160 :   } // end loop over elements
     166              : 
     167              :   // loop over elements pds
     168          200 :   for (size_t ele_num = 0; ele_num < element_count_pds; ++ele_num) {
     169              : 
     170              :     // create our fragment
     171          160 :     dunedaq::daqdataformats::FragmentHeader fh;
     172          160 :     fh.trigger_number = trig_num;
     173          160 :     fh.trigger_timestamp = ts;
     174          160 :     fh.window_begin = ts;
     175          160 :     fh.window_end = ts;
     176          160 :     fh.run_number = run_number;
     177          160 :     fh.fragment_type =
     178              :       static_cast<dunedaq::daqdataformats::fragment_type_t>(dunedaq::daqdataformats::FragmentType::kDAPHNE);
     179          160 :     fh.sequence_number = 0;
     180          160 :     fh.detector_id = static_cast<uint16_t>(dunedaq::detdataformats::DetID::Subdetector::kHD_PDS);
     181          320 :     fh.element_id = dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout,
     182          160 :                                                       ele_num + element_count_tpc);
     183              : 
     184          160 :     std::unique_ptr<dunedaq::daqdataformats::Fragment> frag_ptr(
     185          160 :       new dunedaq::daqdataformats::Fragment(dummy_data, fragment_size));
     186          160 :     frag_ptr->set_header_fields(fh);
     187              : 
     188              :     // add fragment to TriggerRecord
     189          160 :     tr.add_fragment(std::move(frag_ptr));
     190              : 
     191          160 :   } // end loop over elements
     192              : 
     193              :   // loop over TriggerActivity
     194          200 :   for (size_t ele_num = 0; ele_num < element_count_ta; ++ele_num) {
     195              : 
     196              :     // create our fragment
     197          160 :     dunedaq::daqdataformats::FragmentHeader fh;
     198          160 :     fh.trigger_number = trig_num;
     199          160 :     fh.trigger_timestamp = ts;
     200          160 :     fh.window_begin = ts;
     201          160 :     fh.window_end = ts;
     202          160 :     fh.run_number = run_number;
     203          160 :     fh.fragment_type =
     204              :       static_cast<dunedaq::daqdataformats::fragment_type_t>(dunedaq::daqdataformats::FragmentType::kTriggerActivity);
     205          160 :     fh.sequence_number = 0;
     206          160 :     fh.detector_id = static_cast<uint16_t>(dunedaq::detdataformats::DetID::Subdetector::kDAQ);
     207          160 :     fh.element_id = dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kTrigger, ele_num);
     208              : 
     209          160 :     std::unique_ptr<dunedaq::daqdataformats::Fragment> frag_ptr(
     210          160 :       new dunedaq::daqdataformats::Fragment(dummy_data, fragment_size));
     211          160 :     frag_ptr->set_header_fields(fh);
     212              : 
     213              :     // add fragment to TriggerRecord
     214          160 :     tr.add_fragment(std::move(frag_ptr));
     215              : 
     216          160 :   } // end loop over elements
     217              : 
     218              :   // loop over TriggerCandidate
     219           80 :   for (size_t ele_num = 0; ele_num < element_count_tc; ++ele_num) {
     220              : 
     221              :     // create our fragment
     222           40 :     dunedaq::daqdataformats::FragmentHeader fh;
     223           40 :     fh.trigger_number = trig_num;
     224           40 :     fh.trigger_timestamp = ts;
     225           40 :     fh.window_begin = ts;
     226           40 :     fh.window_end = ts;
     227           40 :     fh.run_number = run_number;
     228           40 :     fh.fragment_type =
     229              :       static_cast<dunedaq::daqdataformats::fragment_type_t>(dunedaq::daqdataformats::FragmentType::kTriggerCandidate);
     230           40 :     fh.sequence_number = 0;
     231           40 :     fh.detector_id = static_cast<uint16_t>(dunedaq::detdataformats::DetID::Subdetector::kDAQ);
     232           40 :     fh.element_id = dunedaq::daqdataformats::SourceID(dunedaq::daqdataformats::SourceID::Subsystem::kTrigger,
     233              :                                                       ele_num + element_count_ta);
     234              : 
     235           40 :     std::unique_ptr<dunedaq::daqdataformats::Fragment> frag_ptr(
     236           40 :       new dunedaq::daqdataformats::Fragment(dummy_data, fragment_size));
     237           40 :     frag_ptr->set_header_fields(fh);
     238              : 
     239              :     // add fragment to TriggerRecord
     240           40 :     tr.add_fragment(std::move(frag_ptr));
     241              : 
     242           40 :   } // end loop over elements
     243              : 
     244           40 :   return tr;
     245           40 : }
     246              : 
     247              : struct FileWriteFixture
     248              : {
     249            8 :   FileWriteFixture(int num_triggers = 5, unsigned comp_lvl = 0, uint64_t trigger_record_number_offset = 0)
     250            8 :     : trigger_count(num_triggers)
     251            8 :     , compression_level(comp_lvl)
     252            8 :     , file_path(std::filesystem::temp_directory_path())
     253            8 :     , hdf5_filename("demo" + std::to_string(getpid()) + "_" + std::string(getenv("USER")) + "_comp" +
     254           16 :                     std::to_string(compression_level) + ".hdf5")
     255            8 :     , fl_pars(create_file_layout_params())
     256            8 :     , recorded_size_at_write(0)
     257              :   {
     258            8 :     delete_files_matching_pattern(file_path, hdf5_filename);
     259              : 
     260              :     // create src-geo id map
     261            8 :     auto srcid_geoid_map = create_srcid_geoid_map();
     262              :     // create the file
     263           16 :     std::unique_ptr<HDF5RawDataFile> h5file_ptr(new HDF5RawDataFile(file_path + "/" + hdf5_filename,
     264              :                                                                     run_number,
     265              :                                                                     file_index,
     266              :                                                                     application_name,
     267            8 :                                                                     fl_pars,
     268              :                                                                     srcid_geoid_map,
     269           24 :                                                                     compression_level));
     270              : 
     271              :     // write several events, each with several fragments
     272           48 :     for (uint64_t idx = 0; idx < trigger_count; ++idx) {
     273              :       // Allow for the possibility of large trigger record numbers, otherwise just write trigger_count fragments
     274           80 :       trigger_number = (trigger_record_number_offset == 0)
     275           40 :                          ? idx + 1                                   // Sequential numbering
     276           10 :                          : 1 + (idx * trigger_record_number_offset); // Large offset numbering
     277              : 
     278           40 :       h5file_ptr->write(create_trigger_record(trigger_number));
     279              :     }
     280              : 
     281              :     // get recorded size for checking
     282            8 :     recorded_size_at_write = h5file_ptr->get_recorded_size();
     283              : 
     284            8 :     h5file_ptr.reset(); // explicit destruction
     285            8 :   }
     286            8 :   ~FileWriteFixture() { delete_files_matching_pattern(file_path, hdf5_filename); }
     287              : 
     288            2 :   void read_file_attributes()
     289              :   {
     290              :     // open file for reading now
     291            2 :     h5file_ptr.reset(new HDF5RawDataFile(file_path + "/" + hdf5_filename));
     292              : 
     293              :     // check attributes
     294            2 :     auto recorded_size_attr = h5file_ptr->get_attribute<size_t>("recorded_size");
     295            2 :     auto run_number_attr = h5file_ptr->get_attribute<size_t>("run_number");
     296            2 :     auto file_index_attr = h5file_ptr->get_attribute<size_t>("file_index");
     297            2 :     auto app_name_attr = h5file_ptr->get_attribute<std::string>("application_name");
     298            2 :     auto record_type_attr = h5file_ptr->get_attribute<std::string>("record_type");
     299            2 :     auto compression_level_attr = h5file_ptr->get_attribute<unsigned>("compression_level");
     300            2 :     BOOST_REQUIRE_EQUAL(recorded_size_at_write, recorded_size_attr);
     301            2 :     BOOST_REQUIRE_EQUAL(run_number, run_number_attr);
     302            2 :     BOOST_REQUIRE_EQUAL(file_index, file_index_attr);
     303            2 :     BOOST_REQUIRE_EQUAL(application_name, app_name_attr);
     304            2 :     BOOST_REQUIRE_EQUAL("TriggerRecord", record_type_attr);
     305            2 :     BOOST_REQUIRE_EQUAL(this->compression_level, compression_level_attr);
     306              : 
     307              :     // extract and check file layout parameters
     308            2 :     auto file_layout_parameters_read = h5file_ptr->get_file_layout().get_file_layout_params();
     309            2 :     BOOST_REQUIRE_EQUAL(fl_pars.to_json(), file_layout_parameters_read.to_json());
     310              : 
     311            2 :     if (this->compression_level == 0) {
     312            1 :       uncompressed_raw_data_size = recorded_size_at_write;
     313              :     } else {
     314            1 :       compressed_raw_data_size = recorded_size_at_write;
     315            1 :       BOOST_ASSERT(compressed_raw_data_size < uncompressed_raw_data_size);
     316              :     }
     317            2 :   }
     318              : 
     319            2 :   void read_file_datasets()
     320              :   {
     321              :     // open file for reading now
     322            2 :     h5file_ptr.reset(new HDF5RawDataFile(file_path + "/" + hdf5_filename));
     323              : 
     324            2 :     auto trigger_record_ids = h5file_ptr->get_all_trigger_record_ids();
     325            2 :     BOOST_REQUIRE_EQUAL(trigger_count, trigger_record_ids.size());
     326              : 
     327            2 :     auto first_trigger_record_id = *(trigger_record_ids.begin());
     328            2 :     auto last_trigger_record_id = *(std::next(trigger_record_ids.begin(), trigger_record_ids.size() - 1));
     329            2 :     BOOST_REQUIRE_EQUAL(1, first_trigger_record_id.first);
     330            2 :     BOOST_REQUIRE_EQUAL(trigger_count, last_trigger_record_id.first);
     331              : 
     332            2 :     auto all_datasets = h5file_ptr->get_dataset_paths();
     333            2 :     BOOST_REQUIRE_EQUAL(trigger_count * (1 + components_per_record), all_datasets.size());
     334              : 
     335            2 :     auto all_trh_paths = h5file_ptr->get_trigger_record_header_dataset_paths();
     336            2 :     BOOST_REQUIRE_EQUAL(trigger_count, all_trh_paths.size());
     337              : 
     338            2 :     auto all_frag_paths = h5file_ptr->get_all_fragment_dataset_paths();
     339            2 :     BOOST_REQUIRE_EQUAL(trigger_count * components_per_record, all_frag_paths.size());
     340              : 
     341              :     // test access by name
     342            2 :     std::unique_ptr<dunedaq::daqdataformats::TriggerRecordHeader> trh_ptr;
     343            2 :     trh_ptr = h5file_ptr->get_trh_ptr(all_trh_paths.at(2));
     344            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_trigger_number(), 3);
     345            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_run_number(), run_number);
     346              : 
     347              :     // test access by trigger number
     348            2 :     trh_ptr = h5file_ptr->get_trh_ptr(2, 0);
     349            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_trigger_number(), 2);
     350            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_run_number(), run_number);
     351              : 
     352            2 :     std::unique_ptr<dunedaq::daqdataformats::Fragment> frag_ptr;
     353              : 
     354              :     // test access by name
     355            2 :     frag_ptr = h5file_ptr->get_frag_ptr(all_frag_paths.back());
     356            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), last_trigger_record_id.first);
     357            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     358              : 
     359              :     // test access by trigger number, type,  element
     360            2 :     frag_ptr = h5file_ptr->get_frag_ptr(2, 0, "Detector_Readout", 0);
     361            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), 2);
     362            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     363            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().subsystem,
     364              :                         dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout);
     365            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().id, 0);
     366              : 
     367              :     // test access by trigger number, type, element
     368            2 :     frag_ptr = h5file_ptr->get_frag_ptr(4, 0, "Detector_Readout", 4);
     369            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), 4);
     370            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     371            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().subsystem,
     372              :                         dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout);
     373            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().id, 4);
     374              : 
     375              :     // test access by passing in SourceID
     376            2 :     dunedaq::daqdataformats::SourceID gid = { dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout, 1 };
     377            2 :     frag_ptr = h5file_ptr->get_frag_ptr(5, 0, gid);
     378            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), 5);
     379            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     380            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().subsystem,
     381              :                         dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout);
     382            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().id, 1);
     383            2 :   }
     384              : 
     385            2 :   void read_file_max_sequence()
     386              :   {
     387              :     // open file for reading now
     388            2 :     h5file_ptr.reset(new HDF5RawDataFile(file_path + "/" + hdf5_filename));
     389              : 
     390            2 :     auto trigger_record_ids = h5file_ptr->get_all_trigger_record_ids();
     391            2 :     BOOST_REQUIRE_EQUAL(trigger_count, trigger_record_ids.size());
     392              : 
     393            2 :     auto first_trigger_record_id = *(trigger_record_ids.begin());
     394            2 :     auto last_trigger_record_id = *(std::next(trigger_record_ids.begin(), trigger_record_ids.size() - 1));
     395            2 :     BOOST_REQUIRE_EQUAL(1, first_trigger_record_id.first);
     396            2 :     BOOST_REQUIRE_EQUAL(trigger_count, last_trigger_record_id.first);
     397              : 
     398            2 :     auto all_datasets = h5file_ptr->get_dataset_paths();
     399            2 :     BOOST_REQUIRE_EQUAL(trigger_count * (1 + components_per_record), all_datasets.size());
     400              : 
     401            2 :     auto all_trh_paths = h5file_ptr->get_trigger_record_header_dataset_paths();
     402            2 :     BOOST_REQUIRE_EQUAL(trigger_count, all_trh_paths.size());
     403              : 
     404            2 :     auto all_frag_paths = h5file_ptr->get_all_fragment_dataset_paths();
     405            2 :     BOOST_REQUIRE_EQUAL(trigger_count * components_per_record, all_frag_paths.size());
     406              : 
     407              :     // test access by name
     408            2 :     std::unique_ptr<dunedaq::daqdataformats::TriggerRecordHeader> trh_ptr;
     409            2 :     trh_ptr = h5file_ptr->get_trh_ptr(all_trh_paths.at(2));
     410            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_trigger_number(), 3);
     411            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_run_number(), run_number);
     412              : 
     413              :     // test access by trigger number
     414            2 :     trh_ptr = h5file_ptr->get_trh_ptr(2, 0);
     415            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_trigger_number(), 2);
     416            2 :     BOOST_REQUIRE_EQUAL(trh_ptr->get_run_number(), run_number);
     417              : 
     418            2 :     std::unique_ptr<dunedaq::daqdataformats::Fragment> frag_ptr;
     419              : 
     420              :     // test access by name
     421            2 :     frag_ptr = h5file_ptr->get_frag_ptr(all_frag_paths.back());
     422            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), last_trigger_record_id.first);
     423            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     424              : 
     425              :     // test access by trigger number, type, element
     426            2 :     frag_ptr = h5file_ptr->get_frag_ptr(2, 0, "Detector_Readout", 0);
     427            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), 2);
     428            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     429            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().subsystem,
     430              :                         dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout);
     431            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().id, 0);
     432              : 
     433              :     // test access by trigger number, type, element
     434            2 :     frag_ptr = h5file_ptr->get_frag_ptr(4, 0, "Detector_Readout", 4);
     435            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), 4);
     436            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     437            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().subsystem,
     438              :                         dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout);
     439            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().id, 4);
     440              : 
     441              :     // test access by passing in SourceID
     442            2 :     dunedaq::daqdataformats::SourceID gid = { dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout, 1 };
     443            2 :     frag_ptr = h5file_ptr->get_frag_ptr(5, 0, gid);
     444            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_trigger_number(), 5);
     445            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_run_number(), run_number);
     446            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().subsystem,
     447              :                         dunedaq::daqdataformats::SourceID::Subsystem::kDetectorReadout);
     448            2 :     BOOST_REQUIRE_EQUAL(frag_ptr->get_element_id().id, 1);
     449            2 :   }
     450              : 
     451            2 :   void read_write_large_trigger_numbers()
     452              :   {
     453              :     // open file for reading now
     454            2 :     h5file_ptr.reset(new HDF5RawDataFile(file_path + "/" + hdf5_filename));
     455              : 
     456            2 :     auto trigger_record_ids = h5file_ptr->get_all_trigger_record_ids();
     457            2 :     BOOST_REQUIRE_EQUAL(trigger_count, trigger_record_ids.size());
     458              : 
     459            2 :     auto first_trigger_record_id = *(trigger_record_ids.begin());
     460            2 :     auto last_trigger_record_id = *(std::next(trigger_record_ids.begin(), trigger_record_ids.size() - 1));
     461            2 :     BOOST_REQUIRE_EQUAL(1, first_trigger_record_id.first);
     462            2 :     BOOST_REQUIRE_EQUAL(trigger_number, last_trigger_record_id.first);
     463            2 :     BOOST_REQUIRE(trigger_number > 0xffffffff);
     464            2 :   }
     465              : 
     466              :   uint64_t trigger_count;
     467              :   uint64_t trigger_number;
     468              :   unsigned compression_level;
     469              :   std::string file_path;
     470              :   std::string hdf5_filename;
     471              :   HDF5FileLayoutParameters fl_pars;
     472              :   size_t recorded_size_at_write;
     473              :   std::unique_ptr<HDF5RawDataFile> h5file_ptr;
     474              : };
     475              : 
     476              : BOOST_AUTO_TEST_SUITE(HDF5WriteReadTriggerRecord_test)
     477              : 
     478            2 : BOOST_AUTO_TEST_CASE(ReadFileAttributes)
     479              : {
     480            1 :   FileWriteFixture fixture(5, 0, 0);
     481            1 :   fixture.read_file_attributes();
     482            1 : }
     483              : 
     484            2 : BOOST_AUTO_TEST_CASE(ReadCompressedFileAttributes)
     485              : {
     486            1 :   FileWriteFixture fixture(5, 1, 0);
     487            1 :   fixture.read_file_attributes();
     488            1 : }
     489              : 
     490            2 : BOOST_AUTO_TEST_CASE(ReadFileDatasets)
     491              : {
     492            1 :   FileWriteFixture fixture(5, 0, 0);
     493            1 :   fixture.read_file_datasets();
     494            1 : }
     495              : 
     496            2 : BOOST_AUTO_TEST_CASE(ReadCompressedFileDatasets)
     497              : {
     498            1 :   FileWriteFixture fixture(5, 1, 0);
     499            1 :   fixture.read_file_datasets();
     500            1 : }
     501              : 
     502            2 : BOOST_AUTO_TEST_CASE(ReadFileMaxSequence)
     503              : {
     504            1 :   FileWriteFixture fixture(5, 0, 0);
     505            1 :   fixture.read_file_max_sequence();
     506            1 : }
     507              : 
     508            2 : BOOST_AUTO_TEST_CASE(ReadCompressedFileMaxSequence)
     509              : {
     510            1 :   FileWriteFixture fixture(5, 1, 0);
     511            1 :   fixture.read_file_max_sequence();
     512            1 : }
     513              : 
     514            2 : BOOST_AUTO_TEST_CASE(LargeTriggerRecordNumbers)
     515              : {
     516            1 :   FileWriteFixture fixture(5, 0, 2000000000);
     517            1 :   fixture.read_write_large_trigger_numbers();
     518            1 : }
     519              : 
     520            2 : BOOST_AUTO_TEST_CASE(CompressedLargeTriggerRecordNumbers)
     521              : {
     522            1 :   FileWriteFixture fixture(5, 1, 2000000000);
     523            1 :   fixture.read_write_large_trigger_numbers();
     524            1 : }
     525              : 
     526              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1