1 #define TRACE_NAME "SharedMemoryEventManager_t"
3 #include "artdaq-core/Core/SharedMemoryEventReceiver.hh"
4 #include "artdaq-core/Data/Fragment.hh"
5 #include "artdaq/DAQrate/SharedMemoryEventManager.hh"
7 #define BOOST_TEST_MODULE SharedMemoryEventManager_t
8 #include "cetlib/quiet_unit_test.hpp"
9 #include "cetlib_except/exception.h"
11 BOOST_AUTO_TEST_SUITE(SharedMemoryEventManager_test)
13 artdaq::detail::RawFragmentHeader GetHeader(artdaq::FragmentPtr const& frag)
15 return *
reinterpret_cast<artdaq::detail::RawFragmentHeader*
>(frag->headerAddress());
18 BOOST_AUTO_TEST_CASE(Construct)
20 TLOG(TLVL_INFO) <<
"Test Construct BEGIN";
21 fhicl::ParameterSet pset;
22 pset.put(
"use_art",
false);
23 pset.put(
"buffer_count", 2);
24 pset.put(
"max_event_size_bytes", 1000);
25 pset.put(
"expected_fragments_per_event", 2);
28 BOOST_REQUIRE_EQUAL(t.runID(), 0);
29 BOOST_REQUIRE_EQUAL(t.GetSubrunForSequenceID(1), 1);
30 BOOST_REQUIRE_EQUAL(t.GetLockedBufferCount(), 0);
32 BOOST_REQUIRE_EQUAL(t.runID(), 1);
33 TLOG(TLVL_INFO) <<
"Test Construct END";
36 BOOST_AUTO_TEST_CASE(AddFragment)
38 TLOG(TLVL_INFO) <<
"Test AddFragment BEGIN";
40 fhicl::ParameterSet pset;
41 pset.put(
"use_art",
false);
42 pset.put(
"buffer_count", 2);
43 pset.put(
"max_event_size_bytes", 1000);
44 pset.put(
"expected_fragments_per_event", 2);
48 artdaq::FragmentPtr frag(
new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
50 for (
auto ii = 0; ii < 4; ++ii)
52 *(frag->dataBegin() + ii) = ii;
55 bool sts = t.AddFragment(std::move(frag), 1000000, tmpFrag);
56 BOOST_REQUIRE_EQUAL(sts,
true);
57 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
58 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
59 TLOG(TLVL_INFO) <<
"Test AddFragment END";
62 BOOST_AUTO_TEST_CASE(DataFlow)
64 TLOG(TLVL_INFO) <<
"Test DataFlow BEGIN";
65 fhicl::ParameterSet pset;
66 pset.put(
"use_art",
false);
67 pset.put(
"buffer_count", 2);
68 pset.put(
"max_event_size_bytes", 1000);
69 pset.put(
"expected_fragments_per_event", 3);
73 artdaq::FragmentPtr frag(
new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
75 for (
auto ii = 0; ii < 4; ++ii)
77 *(frag->dataBegin() + ii) = ii;
80 auto hdr = GetHeader(frag);
81 auto fragLoc = t.WriteFragmentHeader(hdr);
82 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
83 t.DoneWritingFragment(hdr);
84 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
85 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
87 frag->setFragmentID(1);
88 hdr = GetHeader(frag);
89 auto fragLoc2 = t.WriteFragmentHeader(hdr);
90 memcpy(fragLoc2, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
91 t.DoneWritingFragment(hdr);
92 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
93 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 2);
94 BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
96 frag->setFragmentID(2);
97 hdr = GetHeader(frag);
98 auto fragLoc3 = t.WriteFragmentHeader(hdr);
99 memcpy(fragLoc3, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
100 t.DoneWritingFragment(hdr);
101 BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3);
102 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
103 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
105 TLOG(TLVL_INFO) <<
"Test DataFlow END";
108 BOOST_AUTO_TEST_CASE(EndOfData)
110 TLOG(TLVL_INFO) <<
"Test EndOfData BEGIN";
111 fhicl::ParameterSet pset;
112 pset.put(
"use_art",
false);
113 pset.put(
"buffer_count", 2);
114 pset.put(
"max_event_size_bytes", 1000);
115 pset.put(
"expected_fragments_per_event", 1);
119 artdaq::FragmentPtr frag(
new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
121 for (
auto ii = 0; ii < 4; ++ii)
123 *(frag->dataBegin() + ii) = ii;
126 auto hdr = GetHeader(frag);
127 auto fragLoc = t.WriteFragmentHeader(hdr);
128 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
129 t.DoneWritingFragment(hdr);
130 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
131 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
137 frag->setSequenceID(1);
138 hdr = GetHeader(frag);
139 auto fragLoc3 = t.WriteFragmentHeader(hdr);
141 std::atomic<bool> endComplete =
false;
143 [&] { endComplete = t.endOfData(); }};
145 memcpy(fragLoc3, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
147 BOOST_REQUIRE_EQUAL(endComplete.load(),
false);
148 t.DoneWritingFragment(hdr);
150 BOOST_REQUIRE_EQUAL(endComplete.load(),
true);
151 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
152 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
154 frag->setSequenceID(2);
155 hdr = GetHeader(frag);
156 auto fragLoc2 = t.WriteFragmentHeader(hdr);
157 BOOST_REQUIRE_EQUAL(fragLoc2,
nullptr);
159 TLOG(TLVL_INFO) <<
"Test EndOfData END";
162 BOOST_AUTO_TEST_CASE(TooManyFragments_InterleavedWrites)
164 TLOG(TLVL_INFO) <<
"Test TooManyFragments_InterleavedWrites BEGIN";
165 fhicl::ParameterSet pset;
166 pset.put(
"use_art",
false);
167 pset.put(
"buffer_count", 2);
168 pset.put(
"max_event_size_bytes", 1000);
169 pset.put(
"expected_fragments_per_event", 3);
170 pset.put(
"stale_buffer_timeout_usec", 100000);
174 artdaq::FragmentPtr frag(
new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
176 for (
auto ii = 0; ii < 4; ++ii)
178 *(frag->dataBegin() + ii) = ii;
181 auto hdr = GetHeader(frag);
182 auto fragLoc = t.WriteFragmentHeader(hdr);
183 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
184 t.DoneWritingFragment(hdr);
185 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
186 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
188 frag->setFragmentID(1);
189 hdr = GetHeader(frag);
190 auto fragLoc2 = t.WriteFragmentHeader(hdr);
191 frag->setFragmentID(2);
192 hdr = GetHeader(frag);
193 auto fragLoc3 = t.WriteFragmentHeader(hdr);
194 frag->setFragmentID(3);
195 hdr = GetHeader(frag);
196 auto fragLoc4 = t.WriteFragmentHeader(hdr);
197 frag->setFragmentID(4);
198 hdr = GetHeader(frag);
199 auto fragLoc5 = t.WriteFragmentHeader(hdr);
201 memcpy(fragLoc2, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
202 t.DoneWritingFragment(hdr);
203 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
204 BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
206 memcpy(fragLoc3, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
207 t.DoneWritingFragment(hdr);
208 BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3);
209 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
210 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
212 memcpy(fragLoc4, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
213 t.DoneWritingFragment(hdr);
214 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
215 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
217 memcpy(fragLoc5, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
218 t.DoneWritingFragment(hdr);
219 BOOST_REQUIRE_EQUAL(fragLoc4 + frag->size(), fragLoc5);
220 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
221 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
225 frag->setSequenceID(2);
226 frag->setFragmentID(0);
228 auto hdr = GetHeader(frag);
229 auto fragLoc = t.WriteFragmentHeader(hdr);
230 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
231 t.DoneWritingFragment(hdr);
232 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
233 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
234 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
236 TLOG(TLVL_INFO) <<
"Test TooManyFragments_InterleavedWrites END";
239 BOOST_AUTO_TEST_CASE(TooManyFragments_DiscreteWrites)
241 TLOG(TLVL_INFO) <<
"Test TooManyFragments_DiscreteWrites BEGIN";
242 fhicl::ParameterSet pset;
243 pset.put(
"use_art",
false);
244 pset.put(
"buffer_count", 2);
245 pset.put(
"max_event_size_bytes", 1000);
246 pset.put(
"expected_fragments_per_event", 3);
247 pset.put(
"stale_buffer_timeout_usec", 100000);
251 artdaq::FragmentPtr frag(
new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
253 for (
auto ii = 0; ii < 4; ++ii)
255 *(frag->dataBegin() + ii) = ii;
258 auto hdr = GetHeader(frag);
259 auto fragLoc = t.WriteFragmentHeader(hdr);
260 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
261 t.DoneWritingFragment(hdr);
262 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
263 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
265 frag->setFragmentID(1);
266 hdr = GetHeader(frag);
267 auto fragLoc2 = t.WriteFragmentHeader(hdr);
269 memcpy(fragLoc2, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
270 t.DoneWritingFragment(hdr);
271 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
272 BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
274 frag->setFragmentID(2);
275 hdr = GetHeader(frag);
276 auto fragLoc3 = t.WriteFragmentHeader(hdr);
277 memcpy(fragLoc3, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
278 t.DoneWritingFragment(hdr);
279 BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3);
280 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
281 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
283 frag->setFragmentID(3);
284 hdr = GetHeader(frag);
285 auto fragLoc4 = t.WriteFragmentHeader(hdr);
286 #if !ART_SUPPORTS_DUPLICATE_EVENTS
287 BOOST_REQUIRE_EQUAL(fragLoc4, t.GetDroppedDataAddress(hdr));
289 memcpy(fragLoc4, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
290 t.DoneWritingFragment(hdr);
291 #if ART_SUPPORTS_DUPLICATE_EVENTS
292 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
293 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
295 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
296 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
301 frag->setSequenceID(2);
302 frag->setFragmentID(0);
304 auto hdr = GetHeader(frag);
305 auto fragLoc = t.WriteFragmentHeader(hdr);
306 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
307 t.DoneWritingFragment(hdr);
308 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
310 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
311 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
313 TLOG(TLVL_INFO) <<
"Test TooManyFragments_DiscreteWrites END";
317 BOOST_AUTO_TEST_CASE(ConsumeDroppedData_Active)
319 TLOG(TLVL_INFO) <<
"Test ConsumeDroppedData_Active BEGIN";
320 fhicl::ParameterSet pset;
321 pset.put(
"use_art",
false);
322 pset.put(
"buffer_count", 20);
323 pset.put(
"max_event_size_bytes", 1000);
324 pset.put(
"expected_fragments_per_event", 2);
325 pset.put(
"stale_buffer_timeout_usec", 100000);
327 artdaq::FragmentPtr frag(
new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
329 for (
auto ii = 0; ii < 4; ++ii)
331 *(frag->dataBegin() + ii) = ii;
337 auto hdr = GetHeader(frag);
338 auto fragLoc = t.WriteFragmentHeader(hdr);
339 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
340 t.DoneWritingFragment(hdr);
341 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
343 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
344 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
347 frag->setSequenceID(2);
348 frag->setFragmentID(0);
350 auto hdr = GetHeader(frag);
351 auto fragLoc = t.WriteFragmentHeader(hdr);
352 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
353 t.DoneWritingFragment(hdr);
354 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
356 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
357 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
359 frag->setFragmentID(1);
360 hdr = GetHeader(frag);
361 auto fragLoc2 = t.WriteFragmentHeader(hdr);
362 memcpy(fragLoc2, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
363 t.DoneWritingFragment(hdr);
364 BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
365 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
368 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
369 BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
372 frag->setSequenceID(3);
373 frag->setFragmentID(0);
375 auto hdr = GetHeader(frag);
376 auto fragLoc = t.WriteFragmentHeader(hdr);
377 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
378 t.DoneWritingFragment(hdr);
379 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
381 BOOST_REQUIRE_EQUAL(t.GetFragmentCount(3), 1);
382 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
384 frag->setFragmentID(1);
385 hdr = GetHeader(frag);
386 auto fragLoc2 = t.WriteFragmentHeader(hdr);
387 memcpy(fragLoc2, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
388 t.DoneWritingFragment(hdr);
389 BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
391 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
392 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
398 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
399 frag->setSequenceID(4);
400 frag->setFragmentID(1);
401 auto hdr = GetHeader(frag);
402 auto fragLoc = t.WriteFragmentHeader(hdr);
403 memcpy(fragLoc, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
404 t.DoneWritingFragment(hdr);
405 BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
407 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
408 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 3);
410 frag->setFragmentID(1);
411 hdr = GetHeader(frag);
412 auto fragLoc2 = t.WriteFragmentHeader(hdr);
413 memcpy(fragLoc2, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
414 t.DoneWritingFragment(hdr);
415 BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
416 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
417 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 4);
420 frag->setSequenceID(1);
421 frag->setFragmentID(1);
422 auto hdr = GetHeader(frag);
423 auto fragLoc2 = t.WriteFragmentHeader(hdr);
424 #if !ART_SUPPORTS_DUPLICATE_EVENTS
425 BOOST_REQUIRE_EQUAL(fragLoc2, t.GetDroppedDataAddress(hdr));
427 memcpy(fragLoc2, frag->dataBegin(), 4 *
sizeof(artdaq::RawDataType));
428 t.DoneWritingFragment(hdr);
429 BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
431 BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
432 #if ART_SUPPORTS_DUPLICATE_EVENTS
433 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 5);
435 BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 4);
439 TLOG(TLVL_INFO) <<
"Test ConsumeDroppedData_Active END";
442 BOOST_AUTO_TEST_CASE(RunNumbers)
444 TLOG(TLVL_INFO) <<
"Test RunNumbers BEGIN";
445 fhicl::ParameterSet pset;
446 pset.put(
"use_art",
false);
447 pset.put(
"buffer_count", 2);
448 pset.put(
"max_event_size_bytes", 1000);
449 pset.put(
"expected_fragments_per_event", 2);
453 BOOST_REQUIRE_EQUAL(t.runID(), 1);
454 BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 1);
456 BOOST_REQUIRE_EQUAL(t.runID(), 1);
457 BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 2);
459 BOOST_REQUIRE_EQUAL(t.runID(), 1);
460 BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 3);
463 t.rolloverSubrun(3, 4);
464 t.rolloverSubrun(4, 4);
465 t.rolloverSubrun(5, 4);
468 BOOST_REQUIRE_EQUAL(t.runID(), 3);
469 BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 1);
471 artdaq::SharedMemoryEventReceiver r(t.GetKey(), t.GetBroadcastKey());
472 bool errflag =
false;
475 bool sts = r.ReadyForRead();
476 BOOST_REQUIRE_EQUAL(sts,
true);
477 auto hdr = r.ReadHeader(errflag);
478 BOOST_REQUIRE_EQUAL(errflag,
false);
479 BOOST_REQUIRE(hdr !=
nullptr);
482 BOOST_REQUIRE_EQUAL(hdr->is_complete,
true);
483 BOOST_REQUIRE_EQUAL(hdr->run_id, 3);
484 BOOST_REQUIRE_EQUAL(hdr->subrun_id, 1);
486 auto frags = r.GetFragmentsByType(errflag, artdaq::Fragment::EndOfRunFragmentType);
487 BOOST_REQUIRE_EQUAL(errflag,
false);
488 BOOST_REQUIRE_EQUAL(frags->size(), 1);
491 TLOG(TLVL_INFO) <<
"Test RunNumbers END";
494 BOOST_AUTO_TEST_SUITE_END()
The SharedMemoryEventManager is a SharedMemoryManger which tracks events as they are built...