artdaq  v3_09_00
SharedMemoryEventManager_t.cc
1 #define TRACE_NAME "SharedMemoryEventManager_t"
2 
3 #include "artdaq-core/Core/SharedMemoryEventReceiver.hh"
4 #include "artdaq-core/Data/Fragment.hh"
5 #include "artdaq/DAQrate/SharedMemoryEventManager.hh"
6 
7 #define BOOST_TEST_MODULE SharedMemoryEventManager_t
8 #include "cetlib/quiet_unit_test.hpp"
9 #include "cetlib_except/exception.h"
10 
11 BOOST_AUTO_TEST_SUITE(SharedMemoryEventManager_test)
12 
13 artdaq::detail::RawFragmentHeader GetHeader(artdaq::FragmentPtr const& frag)
14 {
15  return *reinterpret_cast<artdaq::detail::RawFragmentHeader*>(frag->headerAddress()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
16 }
17 
18 BOOST_AUTO_TEST_CASE(Construct)
19 {
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);
27 
28  BOOST_REQUIRE_EQUAL(t.runID(), 0);
29  BOOST_REQUIRE_EQUAL(t.GetSubrunForSequenceID(1), 1);
30  BOOST_REQUIRE_EQUAL(t.GetLockedBufferCount(), 0);
31  TLOG(TLVL_INFO) << "Test Construct END";
32 }
33 
34 BOOST_AUTO_TEST_CASE(AddFragment)
35 {
36  TLOG(TLVL_INFO) << "Test AddFragment BEGIN";
37 
38  fhicl::ParameterSet pset;
39  pset.put("use_art", false);
40  pset.put("buffer_count", 2);
41  pset.put("max_event_size_bytes", 1000);
42  pset.put("expected_fragments_per_event", 2);
44 
45  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
46  frag->resize(4);
47  for (auto ii = 0; ii < 4; ++ii)
48  {
49  *(frag->dataBegin() + ii) = ii;
50  }
51 
52  bool sts = t.AddFragment(std::move(frag), 1000000, tmpFrag);
53  BOOST_REQUIRE_EQUAL(sts, true);
54  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
55  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
56  TLOG(TLVL_INFO) << "Test AddFragment END";
57 }
58 
59 BOOST_AUTO_TEST_CASE(DataFlow)
60 {
61  TLOG(TLVL_INFO) << "Test DataFlow BEGIN";
62  fhicl::ParameterSet pset;
63  pset.put("use_art", false);
64  pset.put("buffer_count", 2);
65  pset.put("max_event_size_bytes", 1000);
66  pset.put("expected_fragments_per_event", 3);
68 
69  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
70  frag->resize(4);
71  for (auto ii = 0; ii < 4; ++ii)
72  {
73  *(frag->dataBegin() + ii) = ii;
74  }
75 
76  auto hdr = GetHeader(frag);
77  auto fragLoc = t.WriteFragmentHeader(hdr);
78  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
79  t.DoneWritingFragment(hdr);
80  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
81  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
82 
83  frag->setFragmentID(1);
84  hdr = GetHeader(frag);
85  auto fragLoc2 = t.WriteFragmentHeader(hdr);
86  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
87  t.DoneWritingFragment(hdr);
88  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
89  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 2);
90  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
91 
92  frag->setFragmentID(2);
93  hdr = GetHeader(frag);
94  auto fragLoc3 = t.WriteFragmentHeader(hdr);
95  memcpy(fragLoc3, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
96  t.DoneWritingFragment(hdr);
97  BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
98  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
99  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
100 
101  TLOG(TLVL_INFO) << "Test DataFlow END";
102 }
103 
104 BOOST_AUTO_TEST_CASE(TooManyFragments_InterleavedWrites)
105 {
106  TLOG(TLVL_INFO) << "Test TooManyFragments_InterleavedWrites BEGIN";
107  fhicl::ParameterSet pset;
108  pset.put("use_art", false);
109  pset.put("buffer_count", 2);
110  pset.put("max_event_size_bytes", 1000);
111  pset.put("expected_fragments_per_event", 3);
112  pset.put("stale_buffer_timeout_usec", 100000);
113  artdaq::SharedMemoryEventManager t(pset, pset);
114 
115  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
116  frag->resize(4);
117  for (auto ii = 0; ii < 4; ++ii)
118  {
119  *(frag->dataBegin() + ii) = ii;
120  }
121 
122  auto hdr = GetHeader(frag);
123  auto fragLoc = t.WriteFragmentHeader(hdr);
124  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
125  t.DoneWritingFragment(hdr);
126  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
127  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
128 
129  frag->setFragmentID(1);
130  hdr = GetHeader(frag);
131  auto fragLoc2 = t.WriteFragmentHeader(hdr);
132  frag->setFragmentID(2);
133  hdr = GetHeader(frag);
134  auto fragLoc3 = t.WriteFragmentHeader(hdr);
135  frag->setFragmentID(3);
136  hdr = GetHeader(frag);
137  auto fragLoc4 = t.WriteFragmentHeader(hdr);
138  frag->setFragmentID(4);
139  hdr = GetHeader(frag);
140  auto fragLoc5 = t.WriteFragmentHeader(hdr);
141 
142  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
143  t.DoneWritingFragment(hdr);
144  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
145  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
146 
147  memcpy(fragLoc3, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
148  t.DoneWritingFragment(hdr);
149  BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
150  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
151  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
152 
153  memcpy(fragLoc4, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
154  t.DoneWritingFragment(hdr);
155  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
156  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
157 
158  memcpy(fragLoc5, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
159  t.DoneWritingFragment(hdr);
160  BOOST_REQUIRE_EQUAL(fragLoc4 + frag->size(), fragLoc5); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
161  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
162  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
163 
164  usleep(1000000);
165  {
166  frag->setSequenceID(2);
167  frag->setFragmentID(0);
168 
169  auto hdr = GetHeader(frag);
170  auto fragLoc = t.WriteFragmentHeader(hdr);
171  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
172  t.DoneWritingFragment(hdr);
173  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
174  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
175  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
176  }
177  TLOG(TLVL_INFO) << "Test TooManyFragments_InterleavedWrites END";
178 }
179 
180 BOOST_AUTO_TEST_CASE(TooManyFragments_DiscreteWrites)
181 {
182  TLOG(TLVL_INFO) << "Test TooManyFragments_DiscreteWrites BEGIN";
183  fhicl::ParameterSet pset;
184  pset.put("use_art", false);
185  pset.put("buffer_count", 2);
186  pset.put("max_event_size_bytes", 1000);
187  pset.put("expected_fragments_per_event", 3);
188  pset.put("stale_buffer_timeout_usec", 100000);
189  artdaq::SharedMemoryEventManager t(pset, pset);
190 
191  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
192  frag->resize(4);
193  for (auto ii = 0; ii < 4; ++ii)
194  {
195  *(frag->dataBegin() + ii) = ii;
196  }
197 
198  auto hdr = GetHeader(frag);
199  auto fragLoc = t.WriteFragmentHeader(hdr);
200  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
201  t.DoneWritingFragment(hdr);
202  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
203  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
204 
205  frag->setFragmentID(1);
206  hdr = GetHeader(frag);
207  auto fragLoc2 = t.WriteFragmentHeader(hdr);
208 
209  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
210  t.DoneWritingFragment(hdr);
211  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
212  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
213 
214  frag->setFragmentID(2);
215  hdr = GetHeader(frag);
216  auto fragLoc3 = t.WriteFragmentHeader(hdr);
217  memcpy(fragLoc3, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
218  t.DoneWritingFragment(hdr);
219  BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
220  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
221  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
222 
223  frag->setFragmentID(3);
224  hdr = GetHeader(frag);
225  auto fragLoc4 = t.WriteFragmentHeader(hdr);
226 #if !ART_SUPPORTS_DUPLICATE_EVENTS
227  BOOST_REQUIRE_EQUAL(fragLoc4, t.GetDroppedDataAddress(3));
228 #endif
229  memcpy(fragLoc4, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
230  t.DoneWritingFragment(hdr);
231 #if ART_SUPPORTS_DUPLICATE_EVENTS
232  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
233  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
234 #else
235  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
236  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
237 #endif
238 
239  usleep(1000000);
240  {
241  frag->setSequenceID(2);
242  frag->setFragmentID(0);
243 
244  auto hdr = GetHeader(frag);
245  auto fragLoc = t.WriteFragmentHeader(hdr);
246  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
247  t.DoneWritingFragment(hdr);
248  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
249  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
250  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
251  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
252  }
253  TLOG(TLVL_INFO) << "Test TooManyFragments_DiscreteWrites END";
254 }
255 
256 /*
257 // Need to check the following scenarios:
258 // 1. Active buffer with lower sequence id than a completed buffer (b. timeout case)
259 // 2a. Inactive buffer with lower sequence id than a completed buffer (b. timeout case)
260 // 2c. Inactive buffer times out and then data arrives (Error case)
261 BOOST_AUTO_TEST_CASE(Ordering_IncompleteActiveBuffer)
262 {
263  TLOG(TLVL_INFO) << "Test Ordering_IncompleteActiveBuffer BEGIN" ;
264  fhicl::ParameterSet pset;
265  pset.put("use_art", false);
266  pset.put("buffer_count", 20);
267  pset.put("max_event_size_bytes", 1000);
268  pset.put("expected_fragments_per_event", 2);
269 
270  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
271  frag->resize(4);
272  for (auto ii = 0; ii < 4; ++ii)
273  {
274  *(frag->dataBegin() + ii) = ii;
275  }
276 
277  artdaq::SharedMemoryEventManager t(pset, pset);
278  {
279 
280  auto hdr = GetHeader(frag);
281  auto fragLoc = t.WriteFragmentHeader(hdr);
282  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
283  t.DoneWritingFragment(hdr);
284  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
285  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
286  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
287  }
288  {
289  frag->setSequenceID(2);
290  frag->setFragmentID(0);
291 
292  auto hdr = GetHeader(frag);
293  auto fragLoc = t.WriteFragmentHeader(hdr);
294  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
295  t.DoneWritingFragment(hdr);
296  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
297  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
298  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
299 
300  frag->setFragmentID(1);
301  hdr = GetHeader(frag);
302  auto fragLoc2 = t.WriteFragmentHeader(hdr);
303  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
304  t.DoneWritingFragment(hdr);
305  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 1);
306  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
307  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 2);
308  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
309  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
310 
311  }
312  {
313  frag->setSequenceID(3);
314  frag->setFragmentID(0);
315 
316  auto hdr = GetHeader(frag);
317  auto fragLoc = t.WriteFragmentHeader(hdr);
318  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
319  t.DoneWritingFragment(hdr);
320  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
321  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
322  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
323 
324  frag->setFragmentID(1);
325  hdr = GetHeader(frag);
326  auto fragLoc2 = t.WriteFragmentHeader(hdr);
327  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
328  t.DoneWritingFragment(hdr);
329  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 2);
330  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
331  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
332  }
333 
334  {
335  frag->setSequenceID(1);
336  frag->setFragmentID(1);
337  auto hdr = GetHeader(frag);
338  auto fragLoc2 = t.WriteFragmentHeader(hdr);
339  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
340  t.DoneWritingFragment(hdr);
341  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
342  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
343  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 3);
344  }
345  TLOG(TLVL_INFO) << "Test Ordering_IncompleteActiveBuffer END" ;
346 }
347 
348 BOOST_AUTO_TEST_CASE(Ordering_IncompleteActiveBuffer_Timeout)
349 {
350  TLOG(TLVL_INFO) << "Test Ordering_IncompleteActiveBuffer_Timeout BEGIN" ;
351  fhicl::ParameterSet pset;
352  pset.put("use_art", false);
353  pset.put("buffer_count", 20);
354  pset.put("max_event_size_bytes", 1000);
355  pset.put("expected_fragments_per_event", 2);
356  pset.put("stale_buffer_timeout_usec", 100000);
357 
358  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
359  frag->resize(4);
360  for (auto ii = 0; ii < 4; ++ii)
361  {
362  *(frag->dataBegin() + ii) = ii;
363  }
364 
365  artdaq::SharedMemoryEventManager t(pset, pset);
366  {
367  auto hdr = GetHeader(frag);
368  auto fragLoc = t.WriteFragmentHeader(hdr);
369  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
370  t.DoneWritingFragment(hdr);
371  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
372  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
373  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
374  }
375  {
376  frag->setSequenceID(2);
377  frag->setFragmentID(0);
378 
379  auto hdr = GetHeader(frag);
380  auto fragLoc = t.WriteFragmentHeader(hdr);
381  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
382  t.DoneWritingFragment(hdr);
383  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
384  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
385  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
386 
387  frag->setFragmentID(1);
388  hdr = GetHeader(frag);
389  auto fragLoc2 = t.WriteFragmentHeader(hdr);
390  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
391  t.DoneWritingFragment(hdr);
392  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 1);
393  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
394  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 2);
395  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
396  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
397 
398  }
399  {
400  frag->setSequenceID(3);
401  frag->setFragmentID(0);
402 
403  auto hdr = GetHeader(frag);
404  auto fragLoc = t.WriteFragmentHeader(hdr);
405  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
406  t.DoneWritingFragment(hdr);
407  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
408  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
409  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
410 
411  frag->setFragmentID(1);
412  hdr = GetHeader(frag);
413  auto fragLoc2 = t.WriteFragmentHeader(hdr);
414  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
415  t.DoneWritingFragment(hdr);
416  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 2);
417  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
418  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
419  }
420 
421  sleep(1);
422 
423  {
424  frag->setSequenceID(4);
425  frag->setFragmentID(0);
426  auto hdr = GetHeader(frag);
427  auto fragLoc = t.WriteFragmentHeader(hdr);
428  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
429  t.DoneWritingFragment(hdr);
430  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
431  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
432  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 3);
433 
434  frag->setFragmentID(1);
435  hdr = GetHeader(frag);
436  auto fragLoc2 = t.WriteFragmentHeader(hdr);
437  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
438  t.DoneWritingFragment(hdr);
439  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
440  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
441  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 4);
442  }
443  TLOG(TLVL_INFO) << "Test Ordering_IncompleteActiveBuffer_Timeout END" ;
444 }
445 
446 BOOST_AUTO_TEST_CASE(Ordering_InactiveBuffer)
447 {
448  TLOG(TLVL_INFO) << "Test Ordering_InactiveBuffer BEGIN" ;
449  fhicl::ParameterSet pset;
450  pset.put("use_art", false);
451  pset.put("buffer_count", 20);
452  pset.put("max_event_size_bytes", 1000);
453  pset.put("expected_fragments_per_event", 2);
454 
455  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
456  frag->resize(4);
457  for (auto ii = 0; ii < 4; ++ii)
458  {
459  *(frag->dataBegin() + ii) = ii;
460  }
461 
462  artdaq::SharedMemoryEventManager t(pset, pset);
463  {
464  frag->setSequenceID(2);
465  frag->setFragmentID(0);
466 
467  auto hdr = GetHeader(frag);
468  auto fragLoc = t.WriteFragmentHeader(hdr);
469  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
470  t.DoneWritingFragment(hdr);
471  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
472  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
473  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
474 
475  frag->setFragmentID(1);
476  hdr = GetHeader(frag);
477  auto fragLoc2 = t.WriteFragmentHeader(hdr);
478  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
479  t.DoneWritingFragment(hdr);
480  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
481  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 1);
482  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
483  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 2);
484  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
485  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
486 
487  }
488  {
489  frag->setSequenceID(3);
490  frag->setFragmentID(0);
491 
492  auto hdr = GetHeader(frag);
493  auto fragLoc = t.WriteFragmentHeader(hdr);
494  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
495  t.DoneWritingFragment(hdr);
496  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
497  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
498  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 1);
499  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(3), 1);
500  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
501 
502  frag->setFragmentID(1);
503  hdr = GetHeader(frag);
504  auto fragLoc2 = t.WriteFragmentHeader(hdr);
505  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
506  t.DoneWritingFragment(hdr);
507  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 2);
508  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
509  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
510  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
511  }
512 
513  {
514  frag->setSequenceID(1);
515  frag->setFragmentID(0);
516 
517  auto hdr = GetHeader(frag);
518  auto fragLoc = t.WriteFragmentHeader(hdr);
519  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
520  t.DoneWritingFragment(hdr);
521  frag->setFragmentID(1);
522  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
523  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
524  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 2);
525  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
526 
527  hdr = GetHeader(frag);
528  auto fragLoc2 = t.WriteFragmentHeader(hdr);
529  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
530  t.DoneWritingFragment(hdr);
531  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
532  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
533  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
534  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 3);
535  }
536  TLOG(TLVL_INFO) << "Test Ordering_InactiveBuffer END" ;
537 }
538 
539 BOOST_AUTO_TEST_CASE(Ordering_InactiveBuffer_Timeout)
540 {
541  TLOG(TLVL_INFO) << "Test Ordering_InactiveBuffer_Timeout BEGIN" ;
542  fhicl::ParameterSet pset;
543  pset.put("use_art", false);
544  pset.put("buffer_count", 20);
545  pset.put("max_event_size_bytes", 1000);
546  pset.put("expected_fragments_per_event", 2);
547  pset.put("stale_buffer_timeout_usec", 100000);
548 
549  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
550  frag->resize(4);
551  for (auto ii = 0; ii < 4; ++ii)
552  {
553  *(frag->dataBegin() + ii) = ii;
554  }
555 
556  artdaq::SharedMemoryEventManager t(pset, pset);
557  {
558  frag->setSequenceID(2);
559  frag->setFragmentID(0);
560 
561  auto hdr = GetHeader(frag);
562  auto fragLoc = t.WriteFragmentHeader(hdr);
563  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
564  t.DoneWritingFragment(hdr);
565  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
566  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
567  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
568 
569  frag->setFragmentID(1);
570  hdr = GetHeader(frag);
571  auto fragLoc2 = t.WriteFragmentHeader(hdr);
572  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
573  t.DoneWritingFragment(hdr);
574  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 1);
575  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
576  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
577  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 2);
578  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
579  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
580 
581  }
582  {
583  frag->setSequenceID(3);
584  frag->setFragmentID(0);
585 
586  auto hdr = GetHeader(frag);
587  auto fragLoc = t.WriteFragmentHeader(hdr);
588  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
589  t.DoneWritingFragment(hdr);
590  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
591  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
592  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 1);
593  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(3), 1);
594  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
595 
596  frag->setFragmentID(1);
597  hdr = GetHeader(frag);
598  auto fragLoc2 = t.WriteFragmentHeader(hdr);
599  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
600  t.DoneWritingFragment(hdr);
601  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 2);
602  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
603  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
604  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
605  }
606 
607  sleep(1);
608 
609  {
610  frag->setSequenceID(4);
611  frag->setFragmentID(1);
612  auto hdr = GetHeader(frag);
613  auto fragLoc2 = t.WriteFragmentHeader(hdr);
614  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
615  t.DoneWritingFragment(hdr);
616  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
617  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
618  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
619  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
620  }
621  TLOG(TLVL_INFO) << "Test Ordering_InactiveBuffer_Timeout END" ;
622 }
623 */
624 //SharedMemoryEventManager should print error messages, but consume data for buffers which have timed out
625 BOOST_AUTO_TEST_CASE(ConsumeDroppedData_Active)
626 {
627  TLOG(TLVL_INFO) << "Test ConsumeDroppedData_Active BEGIN";
628  fhicl::ParameterSet pset;
629  pset.put("use_art", false);
630  pset.put("buffer_count", 20);
631  pset.put("max_event_size_bytes", 1000);
632  pset.put("expected_fragments_per_event", 2);
633  pset.put("stale_buffer_timeout_usec", 100000);
634 
635  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
636  frag->resize(4);
637  for (auto ii = 0; ii < 4; ++ii)
638  {
639  *(frag->dataBegin() + ii) = ii;
640  }
641 
642  artdaq::SharedMemoryEventManager t(pset, pset);
643  {
644  auto hdr = GetHeader(frag);
645  auto fragLoc = t.WriteFragmentHeader(hdr);
646  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
647  t.DoneWritingFragment(hdr);
648  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
649  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
650  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
651  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
652  }
653  {
654  frag->setSequenceID(2);
655  frag->setFragmentID(0);
656 
657  auto hdr = GetHeader(frag);
658  auto fragLoc = t.WriteFragmentHeader(hdr);
659  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
660  t.DoneWritingFragment(hdr);
661  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
662  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
663  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
664  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
665 
666  frag->setFragmentID(1);
667  hdr = GetHeader(frag);
668  auto fragLoc2 = t.WriteFragmentHeader(hdr);
669  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
670  t.DoneWritingFragment(hdr);
671  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
672  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
673  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
674  //BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 2);
675  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
676  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
677  }
678  {
679  frag->setSequenceID(3);
680  frag->setFragmentID(0);
681 
682  auto hdr = GetHeader(frag);
683  auto fragLoc = t.WriteFragmentHeader(hdr);
684  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
685  t.DoneWritingFragment(hdr);
686  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 2);
687  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
688  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(3), 1);
689  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
690 
691  frag->setFragmentID(1);
692  hdr = GetHeader(frag);
693  auto fragLoc2 = t.WriteFragmentHeader(hdr);
694  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
695  t.DoneWritingFragment(hdr);
696  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
697  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
698  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
699  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
700  }
701 
702  sleep(1);
703 
704  {
705  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
706  frag->setSequenceID(4);
707  frag->setFragmentID(1);
708  auto hdr = GetHeader(frag);
709  auto fragLoc = t.WriteFragmentHeader(hdr);
710  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
711  t.DoneWritingFragment(hdr);
712  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
713  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
714  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
715  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 3);
716 
717  frag->setFragmentID(1);
718  hdr = GetHeader(frag);
719  auto fragLoc2 = t.WriteFragmentHeader(hdr);
720  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
721  t.DoneWritingFragment(hdr);
722  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
723  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
724  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 4);
725  }
726  {
727  frag->setSequenceID(1);
728  frag->setFragmentID(1);
729  auto hdr = GetHeader(frag);
730  auto fragLoc2 = t.WriteFragmentHeader(hdr);
731 #if !ART_SUPPORTS_DUPLICATE_EVENTS
732  BOOST_REQUIRE_EQUAL(fragLoc2, t.GetDroppedDataAddress(1));
733 #endif
734  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
735  t.DoneWritingFragment(hdr);
736  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
737  //BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
738  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
739 #if ART_SUPPORTS_DUPLICATE_EVENTS
740  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 5);
741 #else
742  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 4);
743 #endif
744  }
745 
746  TLOG(TLVL_INFO) << "Test ConsumeDroppedData_Active END";
747 }
748 /*
749 //SharedMemoryEventManager should print error messages, but consume data for buffers which have timed out
750 BOOST_AUTO_TEST_CASE(ConsumeDroppedData_Inactive)
751 {
752  TLOG(TLVL_INFO) << "Test ConsumeDroppedData_Inactive BEGIN" ;
753  fhicl::ParameterSet pset;
754  pset.put("use_art", false);
755  pset.put("buffer_count", 20);
756  pset.put("max_event_size_bytes", 1000);
757  pset.put("expected_fragments_per_event", 2);
758  pset.put("stale_buffer_timeout_usec", 100000);
759 
760  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
761  frag->resize(4);
762  for (auto ii = 0; ii < 4; ++ii)
763  {
764  *(frag->dataBegin() + ii) = ii;
765  }
766 
767  artdaq::SharedMemoryEventManager t(pset, pset);
768  {
769  frag->setSequenceID(2);
770  frag->setFragmentID(0);
771 
772  auto hdr = GetHeader(frag);
773  auto fragLoc = t.WriteFragmentHeader(hdr);
774  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
775  t.DoneWritingFragment(hdr);
776  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
777  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
778  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
779  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
780 
781  frag->setFragmentID(1);
782  hdr = GetHeader(frag);
783  auto fragLoc2 = t.WriteFragmentHeader(hdr);
784  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
785  t.DoneWritingFragment(hdr);
786  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 1);
787  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
788  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
789  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 2);
790  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
791  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2);
792 
793  }
794  {
795  frag->setSequenceID(3);
796  frag->setFragmentID(0);
797 
798  auto hdr = GetHeader(frag);
799  auto fragLoc = t.WriteFragmentHeader(hdr);
800  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
801  t.DoneWritingFragment(hdr);
802  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
803  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
804  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(3), 1);
805  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(),1);
806  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
807 
808  frag->setFragmentID(1);
809  hdr = GetHeader(frag);
810  auto fragLoc2 = t.WriteFragmentHeader(hdr);
811  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
812  t.DoneWritingFragment(hdr);
813  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 2);
814  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 1);
815  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
816  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
817  }
818 
819  sleep(1);
820 
821  {
822  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
823  frag->setSequenceID(4);
824  frag->setFragmentID(1);
825  auto hdr = GetHeader(frag);
826  auto fragLoc = t.WriteFragmentHeader(hdr);
827  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
828  t.DoneWritingFragment(hdr);
829  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
830  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
831  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 1);
832  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
833 
834  frag->setFragmentID(1);
835  hdr = GetHeader(frag);
836  auto fragLoc2 = t.WriteFragmentHeader(hdr);
837  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
838  t.DoneWritingFragment(hdr);
839  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
840  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
841  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 3);
842  }
843  {
844  frag->setSequenceID(1);
845  frag->setFragmentID(1);
846  auto hdr = GetHeader(frag);
847  auto fragLoc2 = t.WriteFragmentHeader(hdr);
848  BOOST_REQUIRE_EQUAL(fragLoc2, t.GetDroppedDataAddress(1));
849  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
850  t.DoneWritingFragment(hdr);
851  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
852  BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
853  BOOST_REQUIRE_EQUAL(t.GetIncompleteEventCount(), 0);
854  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 3);
855  }
856  TLOG(TLVL_INFO) << "Test ConsumeDroppedData_Inactive END" ;
857 }
858 */
859 
860 BOOST_AUTO_TEST_CASE(RunNumbers)
861 {
862  TLOG(TLVL_INFO) << "Test RunNumbers BEGIN";
863  fhicl::ParameterSet pset;
864  pset.put("use_art", false);
865  pset.put("buffer_count", 2);
866  pset.put("max_event_size_bytes", 1000);
867  pset.put("expected_fragments_per_event", 2);
868  artdaq::SharedMemoryEventManager t(pset, pset);
869 
870  t.startRun(1);
871  BOOST_REQUIRE_EQUAL(t.runID(), 1);
872  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 1);
873  t.rolloverSubrun();
874  BOOST_REQUIRE_EQUAL(t.runID(), 1);
875  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 2);
876  t.rolloverSubrun();
877  BOOST_REQUIRE_EQUAL(t.runID(), 1);
878  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 3);
879  t.startRun(3);
880  BOOST_REQUIRE_EQUAL(t.runID(), 3);
881  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 1);
882 
883  artdaq::SharedMemoryEventReceiver r(t.GetKey(), t.GetBroadcastKey());
884  bool errflag = false;
885 
886  t.endRun();
887  bool sts = r.ReadyForRead();
888  BOOST_REQUIRE_EQUAL(sts, true);
889  auto hdr = r.ReadHeader(errflag);
890  BOOST_REQUIRE_EQUAL(errflag, false);
891  BOOST_REQUIRE(hdr != nullptr);
892  if (hdr != nullptr)
893  { // Make static analyzer happy
894  BOOST_REQUIRE_EQUAL(hdr->is_complete, true);
895  BOOST_REQUIRE_EQUAL(hdr->run_id, 3);
896  BOOST_REQUIRE_EQUAL(hdr->subrun_id, 1);
897  }
898  auto frags = r.GetFragmentsByType(errflag, artdaq::Fragment::EndOfRunFragmentType);
899  BOOST_REQUIRE_EQUAL(errflag, false);
900  BOOST_REQUIRE_EQUAL(frags->size(), 1);
901  r.ReleaseBuffer();
902 
903  TLOG(TLVL_INFO) << "Test RunNumbers END";
904 }
905 
906 BOOST_AUTO_TEST_SUITE_END()
The SharedMemoryEventManager is a SharedMemoryManger which tracks events as they are built...