artdaq_core  v3_04_02
SharedMemoryFragmentManager_t.cc
1 #define TRACE_NAME "SharedMemoryFragmentManager_t"
2 
3 #include "artdaq-core/Core/SharedMemoryFragmentManager.hh"
4 #include "artdaq-core/Utilities/configureMessageFacility.hh"
5 #include "tracemf.h"
6 
7 #define BOOST_TEST_MODULE(SharedMemoryFragmentManager_t)
8 #include "cetlib/quiet_unit_test.hpp"
9 #include "cetlib_except/exception.h"
10 #include "SharedMemoryTestShims.hh"
11 
12 
13 BOOST_AUTO_TEST_SUITE(SharedMemoryFragmentManager_test)
14 
15 BOOST_AUTO_TEST_CASE(Construct)
16 {
17  artdaq::configureMessageFacility("SharedMemoryFragmentManager_t", true, true);
18  TLOG(TLVL_INFO) << "BEGIN TEST Construct" ;
19  artdaq::SharedMemoryFragmentManager man(GetRandomKey(0xF4A6), 10, 0x1000);
20  BOOST_REQUIRE_EQUAL(man.IsValid(), true);
21  BOOST_REQUIRE_EQUAL(man.GetMyId(), 0);
22  BOOST_REQUIRE_EQUAL(man.size(), 10);
23  BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 1);
24  TLOG(TLVL_INFO) << "END TEST Construct";
25 }
26 
27 BOOST_AUTO_TEST_CASE(Attach)
28 {
29  TLOG(TLVL_INFO) << "BEGIN TEST Attach";
30  uint32_t key = GetRandomKey(0xF4A6);
31  artdaq::SharedMemoryFragmentManager man(key, 10, 0x1000);
32  artdaq::SharedMemoryFragmentManager man2(key, 10, 0x1000);
33 
34  BOOST_REQUIRE_EQUAL(man.IsValid(), true);
35  BOOST_REQUIRE_EQUAL(man.GetMyId(), 0);
36  BOOST_REQUIRE_EQUAL(man.size(), 10);
37  BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 2);
38 
39  BOOST_REQUIRE_EQUAL(man2.IsValid(), true);
40  BOOST_REQUIRE_EQUAL(man2.GetMyId(), 1);
41  BOOST_REQUIRE_EQUAL(man2.size(), 10);
42  BOOST_REQUIRE_EQUAL(man2.GetAttachedCount(), 2);
43  TLOG(TLVL_INFO) << "END TEST Attach";
44 
45 }
46 
47 BOOST_AUTO_TEST_CASE(DataFlow)
48 {
49  TLOG(TLVL_INFO) << "BEGIN TEST DataFlow";
50  TLOG(TLVL_DEBUG) << "Initializing SharedMemoryFragmentManagers for DataFlow test" ;
51  uint32_t key = GetRandomKey(0xF4A6);
52  artdaq::SharedMemoryFragmentManager man(key, 10, 0x1000);
53  artdaq::SharedMemoryFragmentManager man2(key, 10, 0x1000);
54 
55  auto fragSizeWords = 0x1000 / sizeof(artdaq::RawDataType) - artdaq::detail::RawFragmentHeader::num_words() - 1;
56 
57  TLOG(TLVL_DEBUG) << "Creating test Fragment" ;
58  artdaq::Fragment frag(fragSizeWords);
59  frag.setSequenceID(0x10);
60  frag.setFragmentID(0x20);
62  frag.setSystemType(type);
63  frag.setTimestamp(0x30);
64  for (size_t ii = 0; ii < fragSizeWords; ++ii)
65  {
66  *(frag.dataBegin() + ii) = ii;
67  }
68 
69  TLOG(TLVL_DEBUG) << "Writing Test Fragment to Shared Memory" ;
70  man.WriteFragment(std::move(frag), false, 0);
71 
72  TLOG(TLVL_DEBUG) << "Reading Test Fragment Header" ;
74  auto sts = man2.ReadFragmentHeader(header);
75 
76  TLOG(TLVL_DEBUG) << "Checking Test Fragment Header Contents" ;
77  BOOST_REQUIRE_EQUAL(sts, 0);
78  BOOST_REQUIRE_EQUAL(header.word_count, frag.size());
79  BOOST_REQUIRE_EQUAL(header.sequence_id, 0x10);
80  BOOST_REQUIRE_EQUAL(header.fragment_id, 0x20);
81  BOOST_REQUIRE_EQUAL(header.type, type);
82  BOOST_REQUIRE_EQUAL(header.timestamp, 0x30);
83 
84  TLOG(TLVL_DEBUG) << "Reading Test Fragment data" ;
85  artdaq::Fragment frag2(header.word_count);
86  sts = man2.ReadFragmentData(frag2.dataBegin(), header.word_count - header.num_words());
87 
88  TLOG(TLVL_DEBUG) << "Checking Test Fragment contents" ;
89  BOOST_REQUIRE_EQUAL(sts, 0);
90  for(size_t ii = 0; ii < fragSizeWords; ++ii)
91  {
92  BOOST_REQUIRE_EQUAL(*(frag.dataBegin() + ii), *(frag2.dataBegin() + ii));
93  }
94  TLOG(TLVL_DEBUG) << "SharedMemoryFragmentManager DataFlow test complete" ;
95  TLOG(TLVL_INFO) << "END TEST DataFlow";
96 }
97 
98 BOOST_AUTO_TEST_CASE(WholeFragment)
99 {
100  TLOG(TLVL_INFO) << "BEGIN TEST WholeFragment";
101  TLOG(TLVL_DEBUG) << "Initializing SharedMemoryFragmentManagers for WholeFragment Test" ;
102  uint32_t key = GetRandomKey(0xF4A6);
103  artdaq::SharedMemoryFragmentManager man(key, 10, 0x1000);
104  artdaq::SharedMemoryFragmentManager man2(key, 10, 0x1000);
105 
106  auto fragSizeWords = 0x1000 / sizeof(artdaq::RawDataType) - artdaq::detail::RawFragmentHeader::num_words() - 1;
107 
108  TLOG(TLVL_DEBUG) << "Creating test Fragment" ;
109  artdaq::Fragment frag(fragSizeWords);
110  frag.setSequenceID(0x10);
111  frag.setFragmentID(0x20);
113  frag.setSystemType(type);
114  frag.setTimestamp(0x30);
115  for (size_t ii = 0; ii < fragSizeWords; ++ii)
116  {
117  *(frag.dataBegin() + ii) = ii;
118  }
119 
120  TLOG(TLVL_DEBUG) << "Writing Test Fragment to Shared Memory" ;
121  man.WriteFragment(std::move(frag), false, 0);
122 
123  TLOG(TLVL_DEBUG) << "Reading Test Fragment Header" ;
124  artdaq::Fragment recvdFrag;
125  auto sts = man2.ReadFragment(recvdFrag);
126 
127  TLOG(TLVL_DEBUG) << "Checking Test Fragment Header Contents" ;
128  BOOST_REQUIRE_EQUAL(sts, 0);
129  BOOST_REQUIRE_EQUAL(recvdFrag.size(), frag.size());
130  BOOST_REQUIRE_EQUAL(recvdFrag.sequenceID(), 0x10);
131  BOOST_REQUIRE_EQUAL(recvdFrag.fragmentID(), 0x20);
132  BOOST_REQUIRE_EQUAL(recvdFrag.type(), type);
133  BOOST_REQUIRE_EQUAL(recvdFrag.timestamp(), 0x30);
134 
135  TLOG(TLVL_DEBUG) << "Checking Test Fragment Data Contents" ;
136  for (size_t ii = 0; ii < fragSizeWords; ++ii)
137  {
138  //TLOG(TLVL_DEBUG) << *(frag.dataBegin() + ii) << " =?= " << *(recvdFrag.dataBegin() + ii) ;
139  BOOST_REQUIRE_EQUAL(*(frag.dataBegin() + ii), *(recvdFrag.dataBegin() + ii));
140  }
141  TLOG(TLVL_DEBUG) << "SharedMemoryFragmentManager WholeFragment test complete" ;
142  TLOG(TLVL_INFO) << "END TEST WholeFragment";
143 }
144 
145 
146 BOOST_AUTO_TEST_CASE(Timeout)
147 {
148  TLOG(TLVL_INFO) << "BEGIN TEST Timeout";
149  TLOG(TLVL_DEBUG) << "Initializing SharedMemoryFragmentManagers for Timeout Test" ;
150  uint32_t key = GetRandomKey(0xF4A6);
151  artdaq::SharedMemoryFragmentManager man(key, 1, 0x1000);
152 
153  auto fragSizeWords = 0x1000 / sizeof(artdaq::RawDataType) - artdaq::detail::RawFragmentHeader::num_words() - 1;
154 
155  TLOG(TLVL_DEBUG) << "Creating test Fragment" ;
156  artdaq::Fragment frag(fragSizeWords);
157  frag.setSequenceID(0x10);
158  frag.setFragmentID(0x20);
160  frag.setSystemType(type);
161  frag.setTimestamp(0x30);
162  for (size_t ii = 0; ii < fragSizeWords; ++ii)
163  {
164  *(frag.dataBegin() + ii) = ii;
165  }
166 
167  TLOG(TLVL_DEBUG) << "Reserving buffer to cause timeout to happen" ;
168  auto ret = man.GetBufferForWriting(true);
169  BOOST_REQUIRE_EQUAL(ret, 0);
170 
171  TLOG(TLVL_DEBUG) << "Attempting to write Fragment to Shared Memory. This should time out." ;
172  auto start_time = std::chrono::steady_clock::now();
173  ret = man.WriteFragment(std::move(frag), true, 100000);
174  auto duration = artdaq::TimeUtils::GetElapsedTimeMicroseconds(start_time);
175 
176  BOOST_REQUIRE_EQUAL(ret, -3);
177  BOOST_REQUIRE_GE(duration, 100000);
178 
179  TLOG(TLVL_DEBUG) << "SharedMemoryFragmentManager Timeout test complete" ;
180  TLOG(TLVL_INFO) << "END TEST Timeout";
181 }
182 
183 BOOST_AUTO_TEST_SUITE_END()
RawDataType word_count
number of RawDataType words in this Fragment
RawDataType type
The type of the fragment, either system or user-defined.
std::size_t size() const
Gets the size of the Fragment, from the Fragment header.
Definition: Fragment.hh:799
The SharedMemoryFragmentManager is a SharedMemoryManager that deals with Fragment transfers using a S...
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
The RawFragmentHeader class contains the basic fields used by artdaq for routing Fragment objects thr...
RawDataType timestamp
The 64-bit timestamp field is the output of a user-defined clock used for building time-correlated ev...
RawDataType sequence_id
The 48-bit sequence_id uniquely identifies events within the artdaq system.
sequence_id_t sequenceID() const
Sequence ID of the Fragment, from the Fragment header.
Definition: Fragment.hh:827
timestamp_t timestamp() const
Timestamp of the Fragment, from the Fragment header.
Definition: Fragment.hh:841
constexpr size_t GetElapsedTimeMicroseconds(std::chrono::steady_clock::time_point then, std::chrono::steady_clock::time_point now=std::chrono::steady_clock::now())
Gets the number of microseconds in the given time interval
Definition: TimeUtils.hh:43
static constexpr type_t DataFragmentType
Copy DataFragmentType from RawFragmentHeader.
Definition: Fragment.hh:148
RawDataType fragment_id
The fragment_id uniquely identifies a particular piece of hardware within the artdaq system...
iterator dataBegin()
Return an iterator to the beginning of the data payload (after header and metadata) ...
Definition: Fragment.hh:1026
type_t type() const
Type of the Fragment, from the Fragment header.
Definition: Fragment.hh:813
void configureMessageFacility(char const *progname, bool useConsole=true, bool printDebug=false)
Configure and start the message facility. Provide the program name so that messages will be appropria...
detail::RawFragmentHeader::RawDataType RawDataType
The RawDataType (currently a 64-bit integer) is the basic unit of data representation within artdaq ...
Definition: Fragment.hh:39
A Fragment contains the data from one piece of the DAQ system for one event The artdaq::Fragment is t...
Definition: Fragment.hh:84
fragment_id_t fragmentID() const
Fragment ID of the Fragment, from the Fragment header.
Definition: Fragment.hh:834