artdaq  v3_12_02
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 #include <thread>
12 
13 BOOST_AUTO_TEST_SUITE(SharedMemoryEventManager_test)
14 
15 artdaq::detail::RawFragmentHeader GetHeader(artdaq::FragmentPtr const& frag)
16 {
17  return *reinterpret_cast<artdaq::detail::RawFragmentHeader*>(frag->headerAddress()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
18 }
19 
20 BOOST_AUTO_TEST_CASE(Construct)
21 {
22  TLOG(TLVL_INFO) << "Test Construct BEGIN";
23  fhicl::ParameterSet pset;
24  pset.put("use_art", false);
25  pset.put("buffer_count", 2);
26  pset.put("max_event_size_bytes", 1000);
27  pset.put("expected_fragments_per_event", 2);
29 
30  BOOST_REQUIRE_EQUAL(t.runID(), 0);
31  BOOST_REQUIRE_EQUAL(t.GetSubrunForSequenceID(1), 1);
32  BOOST_REQUIRE_EQUAL(t.GetLockedBufferCount(), 0);
33  t.startRun(1);
34  BOOST_REQUIRE_EQUAL(t.runID(), 1);
35  TLOG(TLVL_INFO) << "Test Construct END";
36 }
37 
38 BOOST_AUTO_TEST_CASE(AddFragment)
39 {
40  TLOG(TLVL_INFO) << "Test AddFragment BEGIN";
41 
42  fhicl::ParameterSet pset;
43  pset.put("use_art", false);
44  pset.put("buffer_count", 2);
45  pset.put("max_event_size_bytes", 1000);
46  pset.put("expected_fragments_per_event", 2);
48  t.startRun(1);
49 
50  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
51  frag->resize(4);
52  for (auto ii = 0; ii < 4; ++ii)
53  {
54  *(frag->dataBegin() + ii) = ii;
55  }
56 
57  bool sts = t.AddFragment(std::move(frag), 1000000, tmpFrag);
58  BOOST_REQUIRE_EQUAL(sts, true);
59  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
60  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
61  TLOG(TLVL_INFO) << "Test AddFragment END";
62 }
63 
64 BOOST_AUTO_TEST_CASE(DataFlow)
65 {
66  TLOG(TLVL_INFO) << "Test DataFlow BEGIN";
67  fhicl::ParameterSet pset;
68  pset.put("use_art", false);
69  pset.put("buffer_count", 2);
70  pset.put("max_event_size_bytes", 1000);
71  pset.put("expected_fragments_per_event", 3);
73  t.startRun(1);
74 
75  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
76  frag->resize(4);
77  for (auto ii = 0; ii < 4; ++ii)
78  {
79  *(frag->dataBegin() + ii) = ii;
80  }
81 
82  auto hdr = GetHeader(frag);
83  auto fragLoc = t.WriteFragmentHeader(hdr);
84  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
85  t.DoneWritingFragment(hdr);
86  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
87  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
88 
89  frag->setFragmentID(1);
90  hdr = GetHeader(frag);
91  auto fragLoc2 = t.WriteFragmentHeader(hdr);
92  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
93  t.DoneWritingFragment(hdr);
94  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
95  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 2);
96  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
97 
98  frag->setFragmentID(2);
99  hdr = GetHeader(frag);
100  auto fragLoc3 = t.WriteFragmentHeader(hdr);
101  memcpy(fragLoc3, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
102  t.DoneWritingFragment(hdr);
103  BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
104  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
105  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
106 
107  TLOG(TLVL_INFO) << "Test DataFlow END";
108 }
109 
110 BOOST_AUTO_TEST_CASE(EndOfData)
111 {
112  TLOG(TLVL_INFO) << "Test EndOfData BEGIN";
113  fhicl::ParameterSet pset;
114  pset.put("use_art", false);
115  pset.put("buffer_count", 2);
116  pset.put("max_event_size_bytes", 1000);
117  pset.put("expected_fragments_per_event", 1);
118  artdaq::SharedMemoryEventManager t(pset, pset);
119  t.startRun(1);
120 
121  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
122  frag->resize(4);
123  for (auto ii = 0; ii < 4; ++ii)
124  {
125  *(frag->dataBegin() + ii) = ii;
126  }
127 
128  auto hdr = GetHeader(frag);
129  auto fragLoc = t.WriteFragmentHeader(hdr);
130  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
131  t.DoneWritingFragment(hdr);
132  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
133  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
134 
135  t.endOfData();
136 
137  t.startRun(2);
138 
139  frag->setSequenceID(1);
140  hdr = GetHeader(frag);
141  auto fragLoc3 = t.WriteFragmentHeader(hdr);
142 
143  std::atomic<bool> endComplete = false;
144  std::thread thread{
145  [&] { endComplete = t.endOfData(); }};
146 
147  memcpy(fragLoc3, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
148  usleep(100000);
149  BOOST_REQUIRE_EQUAL(endComplete.load(), false);
150  t.DoneWritingFragment(hdr);
151  thread.join();
152  BOOST_REQUIRE_EQUAL(endComplete.load(), true);
153  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
154  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
155 
156  frag->setSequenceID(2);
157  hdr = GetHeader(frag);
158  auto fragLoc2 = t.WriteFragmentHeader(hdr);
159  BOOST_REQUIRE_EQUAL(fragLoc2, nullptr);
160 
161  TLOG(TLVL_INFO) << "Test EndOfData END";
162 }
163 
164 BOOST_AUTO_TEST_CASE(TooManyFragments_InterleavedWrites)
165 {
166  TLOG(TLVL_INFO) << "Test TooManyFragments_InterleavedWrites BEGIN";
167  fhicl::ParameterSet pset;
168  pset.put("use_art", false);
169  pset.put("buffer_count", 2);
170  pset.put("max_event_size_bytes", 1000);
171  pset.put("expected_fragments_per_event", 3);
172  pset.put("stale_buffer_timeout_usec", 100000);
173  artdaq::SharedMemoryEventManager t(pset, pset);
174  t.startRun(1);
175 
176  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
177  frag->resize(4);
178  for (auto ii = 0; ii < 4; ++ii)
179  {
180  *(frag->dataBegin() + ii) = ii;
181  }
182 
183  auto hdr = GetHeader(frag);
184  auto fragLoc = t.WriteFragmentHeader(hdr);
185  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
186  t.DoneWritingFragment(hdr);
187  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
188  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
189 
190  frag->setFragmentID(1);
191  hdr = GetHeader(frag);
192  auto fragLoc2 = t.WriteFragmentHeader(hdr);
193  frag->setFragmentID(2);
194  hdr = GetHeader(frag);
195  auto fragLoc3 = t.WriteFragmentHeader(hdr);
196  frag->setFragmentID(3);
197  hdr = GetHeader(frag);
198  auto fragLoc4 = t.WriteFragmentHeader(hdr);
199  frag->setFragmentID(4);
200  hdr = GetHeader(frag);
201  auto fragLoc5 = t.WriteFragmentHeader(hdr);
202 
203  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
204  t.DoneWritingFragment(hdr);
205  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
206  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
207 
208  memcpy(fragLoc3, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
209  t.DoneWritingFragment(hdr);
210  BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
211  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
212  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
213 
214  memcpy(fragLoc4, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
215  t.DoneWritingFragment(hdr);
216  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
217  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
218 
219  memcpy(fragLoc5, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
220  t.DoneWritingFragment(hdr);
221  BOOST_REQUIRE_EQUAL(fragLoc4 + frag->size(), fragLoc5); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
222  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
223  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
224 
225  usleep(1000000);
226  {
227  frag->setSequenceID(2);
228  frag->setFragmentID(0);
229 
230  auto hdr = GetHeader(frag);
231  auto fragLoc = t.WriteFragmentHeader(hdr);
232  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
233  t.DoneWritingFragment(hdr);
234  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
235  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
236  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
237  }
238  TLOG(TLVL_INFO) << "Test TooManyFragments_InterleavedWrites END";
239 }
240 
241 BOOST_AUTO_TEST_CASE(TooManyFragments_DiscreteWrites)
242 {
243  TLOG(TLVL_INFO) << "Test TooManyFragments_DiscreteWrites BEGIN";
244  fhicl::ParameterSet pset;
245  pset.put("use_art", false);
246  pset.put("buffer_count", 2);
247  pset.put("max_event_size_bytes", 1000);
248  pset.put("expected_fragments_per_event", 3);
249  pset.put("stale_buffer_timeout_usec", 100000);
250  artdaq::SharedMemoryEventManager t(pset, pset);
251  t.startRun(1);
252 
253  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
254  frag->resize(4);
255  for (auto ii = 0; ii < 4; ++ii)
256  {
257  *(frag->dataBegin() + ii) = ii;
258  }
259 
260  auto hdr = GetHeader(frag);
261  auto fragLoc = t.WriteFragmentHeader(hdr);
262  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
263  t.DoneWritingFragment(hdr);
264  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
265  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
266 
267  frag->setFragmentID(1);
268  hdr = GetHeader(frag);
269  auto fragLoc2 = t.WriteFragmentHeader(hdr);
270 
271  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
272  t.DoneWritingFragment(hdr);
273  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
274  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
275 
276  frag->setFragmentID(2);
277  hdr = GetHeader(frag);
278  auto fragLoc3 = t.WriteFragmentHeader(hdr);
279  memcpy(fragLoc3, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
280  t.DoneWritingFragment(hdr);
281  BOOST_REQUIRE_EQUAL(fragLoc2 + frag->size(), fragLoc3); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
282  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
283  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
284 
285  frag->setFragmentID(3);
286  hdr = GetHeader(frag);
287  auto fragLoc4 = t.WriteFragmentHeader(hdr);
288 #if !ART_SUPPORTS_DUPLICATE_EVENTS
289  BOOST_REQUIRE_EQUAL(fragLoc4, t.GetDroppedDataAddress(hdr));
290 #endif
291  memcpy(fragLoc4, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
292  t.DoneWritingFragment(hdr);
293 #if ART_SUPPORTS_DUPLICATE_EVENTS
294  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
295  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
296 #else
297  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
298  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
299 #endif
300 
301  usleep(1000000);
302  {
303  frag->setSequenceID(2);
304  frag->setFragmentID(0);
305 
306  auto hdr = GetHeader(frag);
307  auto fragLoc = t.WriteFragmentHeader(hdr);
308  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
309  t.DoneWritingFragment(hdr);
310  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
311  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
312  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
313  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
314  }
315  TLOG(TLVL_INFO) << "Test TooManyFragments_DiscreteWrites END";
316 }
317 
318 // SharedMemoryEventManager should print error messages, but consume data for buffers which have timed out
319 BOOST_AUTO_TEST_CASE(ConsumeDroppedData_Active)
320 {
321  TLOG(TLVL_INFO) << "Test ConsumeDroppedData_Active BEGIN";
322  fhicl::ParameterSet pset;
323  pset.put("use_art", false);
324  pset.put("buffer_count", 20);
325  pset.put("max_event_size_bytes", 1000);
326  pset.put("expected_fragments_per_event", 2);
327  pset.put("stale_buffer_timeout_usec", 100000);
328 
329  artdaq::FragmentPtr frag(new artdaq::Fragment(1, 0, artdaq::Fragment::FirstUserFragmentType, 0UL)), tmpFrag;
330  frag->resize(4);
331  for (auto ii = 0; ii < 4; ++ii)
332  {
333  *(frag->dataBegin() + ii) = ii;
334  }
335 
336  artdaq::SharedMemoryEventManager t(pset, pset);
337  t.startRun(1);
338  {
339  auto hdr = GetHeader(frag);
340  auto fragLoc = t.WriteFragmentHeader(hdr);
341  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
342  t.DoneWritingFragment(hdr);
343  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
344  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
345  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(1), 1);
346  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
347  }
348  {
349  frag->setSequenceID(2);
350  frag->setFragmentID(0);
351 
352  auto hdr = GetHeader(frag);
353  auto fragLoc = t.WriteFragmentHeader(hdr);
354  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
355  t.DoneWritingFragment(hdr);
356  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 2);
357  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
358  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 1);
359  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 0);
360 
361  frag->setFragmentID(1);
362  hdr = GetHeader(frag);
363  auto fragLoc2 = t.WriteFragmentHeader(hdr);
364  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
365  t.DoneWritingFragment(hdr);
366  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
367  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
368  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
369  // BOOST_REQUIRE_EQUAL(t.GetFragmentCount(2), 2);
370  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
371  BOOST_REQUIRE_EQUAL(fragLoc + frag->size(), fragLoc2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
372  }
373  {
374  frag->setSequenceID(3);
375  frag->setFragmentID(0);
376 
377  auto hdr = GetHeader(frag);
378  auto fragLoc = t.WriteFragmentHeader(hdr);
379  memcpy(fragLoc, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
380  t.DoneWritingFragment(hdr);
381  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 2);
382  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
383  BOOST_REQUIRE_EQUAL(t.GetFragmentCount(3), 1);
384  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 1);
385 
386  frag->setFragmentID(1);
387  hdr = GetHeader(frag);
388  auto fragLoc2 = t.WriteFragmentHeader(hdr);
389  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
390  t.DoneWritingFragment(hdr);
391  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
392  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
393  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
394  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
395  }
396 
397  sleep(1);
398 
399  {
400  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 2);
401  frag->setSequenceID(4);
402  frag->setFragmentID(1);
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.GetPendingEventCount(), 0);
408  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
409  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 1);
410  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount() + t.GetArtEventCount(), 3);
411 
412  frag->setFragmentID(1);
413  hdr = GetHeader(frag);
414  auto fragLoc2 = t.WriteFragmentHeader(hdr);
415  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
416  t.DoneWritingFragment(hdr);
417  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
418  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount() + t.GetArtEventCount(), 4);
419  }
420  {
421  frag->setSequenceID(1);
422  frag->setFragmentID(1);
423  auto hdr = GetHeader(frag);
424  auto fragLoc2 = t.WriteFragmentHeader(hdr);
425 #if !ART_SUPPORTS_DUPLICATE_EVENTS
426  BOOST_REQUIRE_EQUAL(fragLoc2, t.GetDroppedDataAddress(hdr));
427 #endif
428  memcpy(fragLoc2, frag->dataBegin(), 4 * sizeof(artdaq::RawDataType));
429  t.DoneWritingFragment(hdr);
430  BOOST_REQUIRE_EQUAL(t.GetPendingEventCount(), 0);
431  // BOOST_REQUIRE_EQUAL(t.GetInactiveEventCount(), 0);
432  BOOST_REQUIRE_EQUAL(t.GetOpenEventCount(), 0);
433 #if ART_SUPPORTS_DUPLICATE_EVENTS
434  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 5);
435 #else
436  BOOST_REQUIRE_EQUAL(t.GetArtEventCount(), 4);
437 #endif
438  }
439 
440  TLOG(TLVL_INFO) << "Test ConsumeDroppedData_Active END";
441 }
442 
443 BOOST_AUTO_TEST_CASE(RunNumbers)
444 {
445  TLOG(TLVL_INFO) << "Test RunNumbers BEGIN";
446  fhicl::ParameterSet pset;
447  pset.put("use_art", false);
448  pset.put("buffer_count", 2);
449  pset.put("max_event_size_bytes", 1000);
450  pset.put("expected_fragments_per_event", 2);
451  artdaq::SharedMemoryEventManager t(pset, pset);
452 
453  t.startRun(1);
454  BOOST_REQUIRE_EQUAL(t.runID(), 1);
455  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 1);
456  t.rolloverSubrun();
457  BOOST_REQUIRE_EQUAL(t.runID(), 1);
458  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 2);
459  t.rolloverSubrun();
460  BOOST_REQUIRE_EQUAL(t.runID(), 1);
461  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 3);
462 
463  // Check repeated requests for same subrun
464  t.rolloverSubrun(3, 4);
465  t.rolloverSubrun(4, 4);
466  t.rolloverSubrun(5, 4);
467 
468  t.startRun(3);
469  BOOST_REQUIRE_EQUAL(t.runID(), 3);
470  BOOST_REQUIRE_EQUAL(t.GetCurrentSubrun(), 1);
471 
472  artdaq::SharedMemoryEventReceiver r(t.GetKey(), t.GetBroadcastKey());
473  bool errflag = false;
474 
475  t.endRun();
476  bool sts = r.ReadyForRead();
477  BOOST_REQUIRE_EQUAL(sts, true);
478  auto hdr = r.ReadHeader(errflag);
479  BOOST_REQUIRE_EQUAL(errflag, false);
480  BOOST_REQUIRE(hdr != nullptr);
481  if (hdr != nullptr)
482  { // Make static analyzer happy
483  BOOST_REQUIRE_EQUAL(hdr->is_complete, true);
484  BOOST_REQUIRE_EQUAL(hdr->run_id, 3);
485  BOOST_REQUIRE_EQUAL(hdr->subrun_id, 1);
486  }
487  auto frags = r.GetFragmentsByType(errflag, artdaq::Fragment::EndOfRunFragmentType);
488  BOOST_REQUIRE_EQUAL(errflag, false);
489  BOOST_REQUIRE_EQUAL(frags->size(), 1);
490  r.ReleaseBuffer();
491 
492  TLOG(TLVL_INFO) << "Test RunNumbers END";
493 }
494 
495 BOOST_AUTO_TEST_SUITE_END()
The SharedMemoryEventManager is a SharedMemoryManger which tracks events as they are built...