artdaq_core  v3_05_07
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 "SharedMemoryTestShims.hh"
9 #include "cetlib/quiet_unit_test.hpp"
10 #include "cetlib_except/exception.h"
11 
12 BOOST_AUTO_TEST_SUITE(SharedMemoryFragmentManager_test)
13 
14 BOOST_AUTO_TEST_CASE(Construct)
15 {
16  artdaq::configureMessageFacility("SharedMemoryFragmentManager_t", true, true);
17  TLOG(TLVL_INFO) << "BEGIN TEST Construct";
18  artdaq::SharedMemoryFragmentManager man(GetRandomKey(0xF4A6), 10, 0x1000);
19  BOOST_REQUIRE_EQUAL(man.IsValid(), true);
20  BOOST_REQUIRE_EQUAL(man.GetMyId(), 0);
21  BOOST_REQUIRE_EQUAL(man.size(), 10);
22  BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 1);
23  TLOG(TLVL_INFO) << "END TEST Construct";
24 }
25 
26 BOOST_AUTO_TEST_CASE(Attach)
27 {
28  TLOG(TLVL_INFO) << "BEGIN TEST Attach";
29  uint32_t key = GetRandomKey(0xF4A6);
30  artdaq::SharedMemoryFragmentManager man(key, 10, 0x1000);
32 
33  BOOST_REQUIRE_EQUAL(man.IsValid(), true);
34  BOOST_REQUIRE_EQUAL(man.GetMyId(), 0);
35  BOOST_REQUIRE_EQUAL(man.size(), 10);
36  BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 2);
37 
38  BOOST_REQUIRE_EQUAL(man2.IsValid(), true);
39  BOOST_REQUIRE_EQUAL(man2.GetMyId(), 1);
40  BOOST_REQUIRE_EQUAL(man2.size(), 10);
41  BOOST_REQUIRE_EQUAL(man2.GetAttachedCount(), 2);
42  TLOG(TLVL_INFO) << "END TEST Attach";
43 }
44 
45 BOOST_AUTO_TEST_CASE(Reattach)
46 {
47  TLOG(TLVL_INFO) << "BEGIN TEST Reattach";
48  uint32_t key = GetRandomKey(0xF4A6);
49  std::unique_ptr<artdaq::SharedMemoryFragmentManager> man(new artdaq::SharedMemoryFragmentManager(key, 10, 0x1000));
50  std::unique_ptr<artdaq::SharedMemoryFragmentManager> man2(new artdaq::SharedMemoryFragmentManager(key));
51 
52  BOOST_REQUIRE_EQUAL(man->IsValid(), true);
53  BOOST_REQUIRE_EQUAL(man->GetMyId(), 0);
54  BOOST_REQUIRE_EQUAL(man->size(), 10);
55  BOOST_REQUIRE_EQUAL(man->GetAttachedCount(), 2);
56 
57  BOOST_REQUIRE_EQUAL(man2->IsValid(), true);
58  BOOST_REQUIRE_EQUAL(man2->GetMyId(), 1);
59  BOOST_REQUIRE_EQUAL(man2->size(), 10);
60  BOOST_REQUIRE_EQUAL(man2->GetAttachedCount(), 2);
61 
62  man2.reset(nullptr);
63  BOOST_REQUIRE_EQUAL(man->IsValid(), true);
64  BOOST_REQUIRE_EQUAL(man->GetAttachedCount(), 1);
65 
66  man2.reset(new artdaq::SharedMemoryFragmentManager(key));
67  BOOST_REQUIRE_EQUAL(man->IsValid(), true);
68  BOOST_REQUIRE_EQUAL(man->GetMyId(), 0);
69  BOOST_REQUIRE_EQUAL(man->size(), 10);
70  BOOST_REQUIRE_EQUAL(man->GetAttachedCount(), 2);
71 
72  BOOST_REQUIRE_EQUAL(man2->IsValid(), true);
73  BOOST_REQUIRE_EQUAL(man2->GetMyId(), 2);
74  BOOST_REQUIRE_EQUAL(man2->size(), 10);
75  BOOST_REQUIRE_EQUAL(man2->GetAttachedCount(), 2);
76 
77  man.reset(nullptr);
78  BOOST_REQUIRE_EQUAL(man2->IsValid(), true);
79  BOOST_REQUIRE_EQUAL(man2->IsEndOfData(), true);
80  BOOST_REQUIRE_EQUAL(man2->GetMyId(), 2);
81  BOOST_REQUIRE_EQUAL(man2->size(), 10);
82  BOOST_REQUIRE_EQUAL(man2->GetAttachedCount(), 1);
83 
84  man2->Attach();
85  BOOST_REQUIRE_EQUAL(man2->IsValid(), false);
86 
87  man.reset(new artdaq::SharedMemoryFragmentManager(key, 10, 0x1000));
88  BOOST_REQUIRE_EQUAL(man->IsValid(), true);
89  BOOST_REQUIRE_EQUAL(man->GetMyId(), 0);
90  BOOST_REQUIRE_EQUAL(man->size(), 10);
91  BOOST_REQUIRE_EQUAL(man->GetAttachedCount(), 1);
92 
93  man2->Attach();
94  BOOST_REQUIRE_EQUAL(man2->IsValid(), true);
95  BOOST_REQUIRE_EQUAL(man2->GetMyId(), 1);
96  BOOST_REQUIRE_EQUAL(man2->size(), 10);
97  BOOST_REQUIRE_EQUAL(man->GetAttachedCount(), 2);
98  BOOST_REQUIRE_EQUAL(man2->GetAttachedCount(), 2);
99 
100  TLOG(TLVL_INFO) << "END TEST Reattach";
101 }
102 
103 BOOST_AUTO_TEST_CASE(DataFlow)
104 {
105  TLOG(TLVL_INFO) << "BEGIN TEST DataFlow";
106  TLOG(TLVL_DEBUG) << "Initializing SharedMemoryFragmentManagers for DataFlow test";
107  uint32_t key = GetRandomKey(0xF4A6);
108  artdaq::SharedMemoryFragmentManager man(key, 10, 0x1000);
110 
111  auto fragSizeWords = 0x1000 / sizeof(artdaq::RawDataType) - artdaq::detail::RawFragmentHeader::num_words() - 1;
112 
113  TLOG(TLVL_DEBUG) << "Creating test Fragment";
114  artdaq::Fragment frag(fragSizeWords);
115  frag.setSequenceID(0x10);
116  frag.setFragmentID(0x20);
118  frag.setSystemType(type);
119  frag.setTimestamp(0x30);
120  for (size_t ii = 0; ii < fragSizeWords; ++ii)
121  {
122  *(frag.dataBegin() + ii) = ii;
123  }
124 
125  TLOG(TLVL_DEBUG) << "Writing Test Fragment to Shared Memory";
126  man.WriteFragment(std::move(frag), false, 0);
127 
128  TLOG(TLVL_DEBUG) << "Reading Test Fragment Header";
130  auto sts = man2.ReadFragmentHeader(header);
131 
132  TLOG(TLVL_DEBUG) << "Checking Test Fragment Header Contents";
133  BOOST_REQUIRE_EQUAL(sts, 0);
134  BOOST_REQUIRE_EQUAL(header.word_count, frag.size());
135  BOOST_REQUIRE_EQUAL(header.sequence_id, 0x10);
136  BOOST_REQUIRE_EQUAL(header.fragment_id, 0x20);
137  BOOST_REQUIRE_EQUAL(header.type, type);
138  BOOST_REQUIRE_EQUAL(header.timestamp, 0x30);
139 
140  TLOG(TLVL_DEBUG) << "Reading Test Fragment data";
141  artdaq::Fragment frag2(header.word_count);
142  sts = man2.ReadFragmentData(frag2.dataBegin(), header.word_count - header.num_words());
143 
144  TLOG(TLVL_DEBUG) << "Checking Test Fragment contents";
145  BOOST_REQUIRE_EQUAL(sts, 0);
146  for (size_t ii = 0; ii < fragSizeWords; ++ii)
147  {
148  BOOST_REQUIRE_EQUAL(*(frag.dataBegin() + ii), *(frag2.dataBegin() + ii));
149  }
150  TLOG(TLVL_DEBUG) << "SharedMemoryFragmentManager DataFlow test complete";
151  TLOG(TLVL_INFO) << "END TEST DataFlow";
152 }
153 
154 BOOST_AUTO_TEST_CASE(WholeFragment)
155 {
156  TLOG(TLVL_INFO) << "BEGIN TEST WholeFragment";
157  TLOG(TLVL_DEBUG) << "Initializing SharedMemoryFragmentManagers for WholeFragment Test";
158  uint32_t key = GetRandomKey(0xF4A6);
159  artdaq::SharedMemoryFragmentManager man(key, 10, 0x1000);
161 
162  auto fragSizeWords = 0x1000 / sizeof(artdaq::RawDataType) - artdaq::detail::RawFragmentHeader::num_words() - 1;
163 
164  TLOG(TLVL_DEBUG) << "Creating test Fragment";
165  artdaq::Fragment frag(fragSizeWords);
166  frag.setSequenceID(0x10);
167  frag.setFragmentID(0x20);
169  frag.setSystemType(type);
170  frag.setTimestamp(0x30);
171  for (size_t ii = 0; ii < fragSizeWords; ++ii)
172  {
173  *(frag.dataBegin() + ii) = ii;
174  }
175 
176  TLOG(TLVL_DEBUG) << "Writing Test Fragment to Shared Memory";
177  man.WriteFragment(std::move(frag), false, 0);
178 
179  TLOG(TLVL_DEBUG) << "Reading Test Fragment Header";
180  artdaq::Fragment recvdFrag;
181  auto sts = man2.ReadFragment(recvdFrag);
182 
183  TLOG(TLVL_DEBUG) << "Checking Test Fragment Header Contents";
184  BOOST_REQUIRE_EQUAL(sts, 0);
185  BOOST_REQUIRE_EQUAL(recvdFrag.size(), frag.size());
186  BOOST_REQUIRE_EQUAL(recvdFrag.sequenceID(), 0x10);
187  BOOST_REQUIRE_EQUAL(recvdFrag.fragmentID(), 0x20);
188  BOOST_REQUIRE_EQUAL(recvdFrag.type(), type);
189  BOOST_REQUIRE_EQUAL(recvdFrag.timestamp(), 0x30);
190 
191  TLOG(TLVL_DEBUG) << "Checking Test Fragment Data Contents";
192  for (size_t ii = 0; ii < fragSizeWords; ++ii)
193  {
194  //TLOG(TLVL_DEBUG) << *(frag.dataBegin() + ii) << " =?= " << *(recvdFrag.dataBegin() + ii) ;
195  BOOST_REQUIRE_EQUAL(*(frag.dataBegin() + ii), *(recvdFrag.dataBegin() + ii));
196  }
197  TLOG(TLVL_DEBUG) << "SharedMemoryFragmentManager WholeFragment test complete";
198  TLOG(TLVL_INFO) << "END TEST WholeFragment";
199 }
200 
201 BOOST_AUTO_TEST_CASE(Timeout)
202 {
203  TLOG(TLVL_INFO) << "BEGIN TEST Timeout";
204  TLOG(TLVL_DEBUG) << "Initializing SharedMemoryFragmentManagers for Timeout Test";
205  uint32_t key = GetRandomKey(0xF4A6);
206  artdaq::SharedMemoryFragmentManager man(key, 1, 0x1000);
207 
208  auto fragSizeWords = 0x1000 / sizeof(artdaq::RawDataType) - artdaq::detail::RawFragmentHeader::num_words() - 1;
209 
210  TLOG(TLVL_DEBUG) << "Creating test Fragment";
211  artdaq::Fragment frag(fragSizeWords);
212  frag.setSequenceID(0x10);
213  frag.setFragmentID(0x20);
215  frag.setSystemType(type);
216  frag.setTimestamp(0x30);
217  for (size_t ii = 0; ii < fragSizeWords; ++ii)
218  {
219  *(frag.dataBegin() + ii) = ii;
220  }
221 
222  TLOG(TLVL_DEBUG) << "Reserving buffer to cause timeout to happen";
223  auto ret = man.GetBufferForWriting(true);
224  BOOST_REQUIRE_EQUAL(ret, 0);
225 
226  TLOG(TLVL_DEBUG) << "Attempting to write Fragment to Shared Memory. This should time out.";
227  auto start_time = std::chrono::steady_clock::now();
228  ret = man.WriteFragment(std::move(frag), true, 100000);
229  auto duration = artdaq::TimeUtils::GetElapsedTimeMicroseconds(start_time);
230 
231  BOOST_REQUIRE_EQUAL(ret, -3);
232  BOOST_REQUIRE_GE(duration, 100000);
233 
234  TLOG(TLVL_DEBUG) << "SharedMemoryFragmentManager Timeout test complete";
235  TLOG(TLVL_INFO) << "END TEST Timeout";
236 }
237 
238 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:826
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:851
timestamp_t timestamp() const
Timestamp of the Fragment, from the Fragment header.
Definition: Fragment.hh:863
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:41
static constexpr type_t DataFragmentType
Copy DataFragmentType from RawFragmentHeader.
Definition: Fragment.hh:149
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:1056
type_t type() const
Type of the Fragment, from the Fragment header.
Definition: Fragment.hh:839
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:40
A Fragment contains the data from one piece of the DAQ system for one event The artdaq::Fragment is t...
Definition: Fragment.hh:85
fragment_id_t fragmentID() const
Fragment ID of the Fragment, from the Fragment header.
Definition: Fragment.hh:857