artdaq  v3_09_03
FragmentBuffer_t.cc
1 #define TRACE_NAME "FragmentBuffer_t"
2 
3 #define BOOST_TEST_MODULE FragmentBuffer_t
4 #include <boost/test/unit_test.hpp>
5 
6 #include "artdaq-core/Data/ContainerFragment.hh"
7 #include "artdaq-core/Data/Fragment.hh"
8 #include "artdaq/DAQrate/FragmentBuffer.hh"
9 #include "artdaq/DAQrate/RequestSender.hh"
10 
11 #define MESSAGEFACILITY_DEBUG true
12 
13 #define RATE_TEST_COUNT 100000
14 #define TRACE_REQUIRE_EQUAL(l, r) \
15  do \
16  { \
17  if (l == r) \
18  { \
19  TLOG(TLVL_DEBUG) << __LINE__ << ": Checking if " << #l << " (" << l << ") equals " << #r << " (" << r << ")...YES!"; \
20  } \
21  else \
22  { \
23  TLOG(TLVL_ERROR) << __LINE__ << ": Checking if " << #l << " (" << l << ") equals " << #r << " (" << r << ")...NO!"; \
24  } \
25  BOOST_REQUIRE_EQUAL(l, r); \
26  } while (0)
27 
28 namespace artdaqtest {
29 class FragmentBufferTestGenerator;
30 }
31 
36 {
37 public:
41  explicit FragmentBufferTestGenerator(const fhicl::ParameterSet& ps);
42 
49  artdaq::FragmentPtrs Generate(size_t n, std::vector<artdaq::Fragment::fragment_id_t> fragmentIds = std::vector<artdaq::Fragment::fragment_id_t>());
50 
51 public:
56  void setTimestamp(artdaq::Fragment::timestamp_t ts) { ts_ = ts; }
57 
62  artdaq::Fragment::timestamp_t getTimestamp() { return ts_; }
63 
64 private:
65  artdaq::Fragment::timestamp_t ts_;
66  artdaq::Fragment::sequence_id_t seq_;
67  std::set<artdaq::Fragment::fragment_id_t> fragmentIDs_;
68 };
69 
71  : ts_(0), seq_(1)
72 {
73  metricMan->initialize(ps.get<fhicl::ParameterSet>("metrics", fhicl::ParameterSet()));
74  metricMan->do_start();
75 
76  auto idlist = ps.get<std::vector<artdaq::Fragment::fragment_id_t>>("fragment_ids", {ps.get<artdaq::Fragment::fragment_id_t>("fragment_id", 1)});
77  for (auto& id : idlist)
78  {
79  fragmentIDs_.insert(id);
80  }
81 }
82 
83 artdaq::FragmentPtrs artdaqtest::FragmentBufferTestGenerator::Generate(size_t n, std::vector<artdaq::Fragment::fragment_id_t> fragmentIds)
84 {
85  if (fragmentIds.size() == 0) std::copy(fragmentIDs_.begin(), fragmentIDs_.end(), std::back_inserter(fragmentIds));
86 
87  artdaq::FragmentPtrs frags;
88  while (n > 0)
89  {
90  ++ts_;
91  for (auto& id : fragmentIds)
92  {
93  TLOG(TLVL_DEBUG) << "Adding Fragment with ID " << id << ", SeqID " << seq_ << ", and timestamp " << ts_;
94  frags.emplace_back(new artdaq::Fragment(seq_, id, artdaq::Fragment::FirstUserFragmentType, ts_));
95  }
96  ++seq_;
97  n--;
98  }
99 
100  return frags;
101 }
102 
103 BOOST_AUTO_TEST_SUITE(FragmentBuffer_t)
104 
105 BOOST_AUTO_TEST_CASE(IgnoreRequests)
106 {
107  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
108  TLOG(TLVL_INFO) << "IgnoreRequests test case BEGIN";
109  fhicl::ParameterSet ps;
110  ps.put<int>("fragment_id", 1);
111  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
112  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
113  ps.put<std::string>("request_mode", "ignored");
114 
115  auto buffer = std::make_shared<artdaq::RequestBuffer>();
116  buffer->setRunning(true);
117 
118  artdaq::FragmentBuffer fp(ps);
119  fp.SetRequestBuffer(buffer);
120 
121  buffer->push(53, 35);
122 
124 
125  fp.AddFragmentsToBuffer(gen.Generate(1));
126 
127  artdaq::FragmentPtrs fps;
128  auto sts = fp.applyRequests(fps);
129 
130  TRACE_REQUIRE_EQUAL(sts, true);
131  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
132  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
133  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
134  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
135 
136  TLOG(TLVL_INFO) << "IgnoreRequests test case END";
137 }
138 
139 BOOST_AUTO_TEST_CASE(SingleMode)
140 {
141  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
142  TLOG(TLVL_INFO) << "SingleMode test case BEGIN";
143  fhicl::ParameterSet ps;
144  ps.put<int>("fragment_id", 1);
145  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
146  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
147  ps.put<std::string>("request_mode", "single");
148 
149  auto buffer = std::make_shared<artdaq::RequestBuffer>();
150  buffer->setRunning(true);
152  artdaq::FragmentBuffer fp(ps);
153  fp.SetRequestBuffer(buffer);
154 
155  buffer->push(1, 1);
156  fp.AddFragmentsToBuffer(gen.Generate(1));
157  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
158 
159  artdaq::FragmentPtrs fps;
160  auto sts = fp.applyRequests(fps);
161  auto type = artdaq::Fragment::FirstUserFragmentType;
162  TRACE_REQUIRE_EQUAL(sts, true);
163  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
164  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
165  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
166  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
167  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
168  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
169  fps.clear();
170 
171  buffer->push(2, 5);
172  sts = fp.applyRequests(fps);
173  TRACE_REQUIRE_EQUAL(sts, true);
174  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
175  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
176  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
177  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
178  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
179  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
180  fps.clear();
181 
182  fp.AddFragmentsToBuffer(gen.Generate(2));
183  buffer->push(4, 7);
184 
185  sts = fp.applyRequests(fps);
186  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
187  TRACE_REQUIRE_EQUAL(sts, true);
188  TRACE_REQUIRE_EQUAL(fps.size(), 2);
189  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
190  auto ts = artdaq::Fragment::InvalidTimestamp;
191  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
192  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
193  auto emptyType = artdaq::Fragment::EmptyFragmentType;
194  TRACE_REQUIRE_EQUAL(fps.front()->type(), emptyType);
195  fps.pop_front();
196  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
197  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
198  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
199  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
200  fps.clear();
201 
202  TLOG(TLVL_INFO) << "SingleMode test case END";
203 }
204 
205 BOOST_AUTO_TEST_CASE(BufferMode)
206 {
207  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
208  TLOG(TLVL_INFO) << "BufferMode test case BEGIN";
209  fhicl::ParameterSet ps;
210  ps.put<int>("fragment_id", 1);
211  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
212  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
213  ps.put<std::string>("request_mode", "buffer");
214 
215  auto buffer = std::make_shared<artdaq::RequestBuffer>();
216  buffer->setRunning(true);
218  artdaq::FragmentBuffer fp(ps);
219  fp.SetRequestBuffer(buffer);
220 
221  buffer->push(1, 1);
222  fp.AddFragmentsToBuffer(gen.Generate(1));
223 
224  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
225 
226  artdaq::FragmentPtrs fps;
227  auto sts = fp.applyRequests(fps);
228  TRACE_REQUIRE_EQUAL(sts, true);
229  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
230  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
231  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
232  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
233  auto type = artdaq::Fragment::ContainerFragmentType;
234  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
235  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
236  auto cf = artdaq::ContainerFragment(*fps.front());
237  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
238  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
239  type = artdaq::Fragment::FirstUserFragmentType;
240  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
241  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
242  fps.clear();
243 
244  buffer->push(2, 5);
245  sts = fp.applyRequests(fps);
246  TRACE_REQUIRE_EQUAL(sts, true);
247  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
248  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
249  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
250  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
251  type = artdaq::Fragment::ContainerFragmentType;
252  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
253  auto cf2 = artdaq::ContainerFragment(*fps.front());
254  TRACE_REQUIRE_EQUAL(cf2.block_count(), 0);
255  TRACE_REQUIRE_EQUAL(cf2.missing_data(), false);
256  type = artdaq::Fragment::EmptyFragmentType;
257  TRACE_REQUIRE_EQUAL(cf2.fragment_type(), type);
258  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
259  fps.clear();
260 
261  fp.AddFragmentsToBuffer(gen.Generate(2));
262  buffer->push(4, 7);
263 
264  sts = fp.applyRequests(fps);
265  TRACE_REQUIRE_EQUAL(sts, true);
266  TRACE_REQUIRE_EQUAL(fps.size(), 2);
267 
268  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
269  auto ts = artdaq::Fragment::InvalidTimestamp;
270  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
271  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
272  auto emptyType = artdaq::Fragment::EmptyFragmentType;
273  TRACE_REQUIRE_EQUAL(fps.front()->type(), emptyType);
274  TRACE_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
275  fps.pop_front();
276  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
277  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
278  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
279  type = artdaq::Fragment::ContainerFragmentType;
280  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
281  auto cf3 = artdaq::ContainerFragment(*fps.front());
282  TRACE_REQUIRE_EQUAL(cf3.block_count(), 2);
283  TRACE_REQUIRE_EQUAL(cf3.missing_data(), false);
284  type = artdaq::Fragment::FirstUserFragmentType;
285  TRACE_REQUIRE_EQUAL(cf3.fragment_type(), type);
286  fps.clear();
287  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
288 
289  TLOG(TLVL_INFO) << "BufferMode test case END";
290 }
291 
292 BOOST_AUTO_TEST_CASE(BufferMode_KeepLatest)
293 {
294  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
295  TLOG(TLVL_INFO) << "BufferMode_KeepLatest test case BEGIN";
296  fhicl::ParameterSet ps;
297  ps.put<int>("fragment_id", 1);
298  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
299  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
300  ps.put<std::string>("request_mode", "buffer");
301  ps.put("buffer_mode_keep_latest", true);
302 
303  auto buffer = std::make_shared<artdaq::RequestBuffer>();
304  buffer->setRunning(true);
306  artdaq::FragmentBuffer fp(ps);
307  fp.SetRequestBuffer(buffer);
308 
309  buffer->push(1, 1);
310  fp.AddFragmentsToBuffer(gen.Generate(1));
311 
312  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
313 
314  artdaq::FragmentPtrs fps;
315  auto sts = fp.applyRequests(fps);
316  TRACE_REQUIRE_EQUAL(sts, true);
317  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
318  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
319  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
320  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
321  auto type = artdaq::Fragment::ContainerFragmentType;
322  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
323  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
324  auto cf = artdaq::ContainerFragment(*fps.front());
325  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
326  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
327  type = artdaq::Fragment::FirstUserFragmentType;
328  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
329  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
330  fps.clear();
331 
332  buffer->push(2, 5);
333  sts = fp.applyRequests(fps);
334  TRACE_REQUIRE_EQUAL(sts, true);
335  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
336  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
337  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
338  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
339  type = artdaq::Fragment::ContainerFragmentType;
340  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
341  auto cf2 = artdaq::ContainerFragment(*fps.front());
342  TRACE_REQUIRE_EQUAL(cf2.block_count(), 1);
343  TRACE_REQUIRE_EQUAL(cf2.missing_data(), false);
344  type = artdaq::Fragment::FirstUserFragmentType;
345  TRACE_REQUIRE_EQUAL(cf2.fragment_type(), type);
346  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
347  fps.clear();
348 
349  fp.AddFragmentsToBuffer(gen.Generate(2));
350  buffer->push(4, 7);
351  sts = fp.applyRequests(fps);
352  TRACE_REQUIRE_EQUAL(sts, true);
353  TRACE_REQUIRE_EQUAL(fps.size(), 2);
354 
355  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
356  auto ts = artdaq::Fragment::InvalidTimestamp;
357  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
358  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
359  auto emptyType = artdaq::Fragment::EmptyFragmentType;
360  TRACE_REQUIRE_EQUAL(fps.front()->type(), emptyType);
361  TRACE_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
362  fps.pop_front();
363  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
364  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
365  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
366  type = artdaq::Fragment::ContainerFragmentType;
367  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
368  auto cf3 = artdaq::ContainerFragment(*fps.front());
369  TRACE_REQUIRE_EQUAL(cf3.block_count(), 2);
370  TRACE_REQUIRE_EQUAL(cf3.missing_data(), false);
371  type = artdaq::Fragment::FirstUserFragmentType;
372  TRACE_REQUIRE_EQUAL(cf3.fragment_type(), type);
373  fps.clear();
374  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
375 
376  TLOG(TLVL_INFO) << "BufferMode_KeepLatest test case END";
377 }
378 BOOST_AUTO_TEST_CASE(CircularBufferMode)
379 {
380  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
381  TLOG(TLVL_INFO) << "CircularBufferMode test case BEGIN";
382  fhicl::ParameterSet ps;
383  ps.put<int>("fragment_id", 1);
384  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
385  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
386  ps.put<bool>("circular_buffer_mode", true);
387  ps.put<int>("data_buffer_depth_fragments", 3);
388  ps.put<std::string>("request_mode", "buffer");
389 
390  auto buffer = std::make_shared<artdaq::RequestBuffer>();
391  buffer->setRunning(true);
393  artdaq::FragmentBuffer fp(ps);
394  fp.SetRequestBuffer(buffer);
395 
396  buffer->push(1, 1);
397  fp.AddFragmentsToBuffer(gen.Generate(1));
398 
399  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
400 
401  artdaq::FragmentPtrs fps;
402  auto sts = fp.applyRequests(fps);
403  TRACE_REQUIRE_EQUAL(sts, true);
404  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
405  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
406  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
407  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
408  auto type = artdaq::Fragment::ContainerFragmentType;
409  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
410  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
411  auto cf = artdaq::ContainerFragment(*fps.front());
412  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
413  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
414  type = artdaq::Fragment::FirstUserFragmentType;
415  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
416  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
417  fps.clear();
418 
419  buffer->push(2, 5);
420  sts = fp.applyRequests(fps);
421  TRACE_REQUIRE_EQUAL(sts, true);
422  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
423  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
424  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
425  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
426  type = artdaq::Fragment::ContainerFragmentType;
427  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
428  auto cf2 = artdaq::ContainerFragment(*fps.front());
429  TRACE_REQUIRE_EQUAL(cf2.block_count(), 0);
430  TRACE_REQUIRE_EQUAL(cf2.missing_data(), false);
431  type = artdaq::Fragment::EmptyFragmentType;
432  TRACE_REQUIRE_EQUAL(cf2.fragment_type(), type);
433  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
434  fps.clear();
435 
436  fp.AddFragmentsToBuffer(gen.Generate(3));
437 
438  buffer->push(4, 7);
439  sts = fp.applyRequests(fps);
440  TRACE_REQUIRE_EQUAL(sts, true);
441  TRACE_REQUIRE_EQUAL(fps.size(), 2);
442 
443  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
444  auto ts = artdaq::Fragment::InvalidTimestamp;
445  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
446  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
447  auto emptyType = artdaq::Fragment::EmptyFragmentType;
448  TRACE_REQUIRE_EQUAL(fps.front()->type(), emptyType);
449  TRACE_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
450  fps.pop_front();
451  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
452  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
453  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
454  type = artdaq::Fragment::ContainerFragmentType;
455  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
456  auto cf3 = artdaq::ContainerFragment(*fps.front());
457  TRACE_REQUIRE_EQUAL(cf3.block_count(), 3);
458  TRACE_REQUIRE_EQUAL(cf3.missing_data(), false);
459  type = artdaq::Fragment::FirstUserFragmentType;
460  TRACE_REQUIRE_EQUAL(cf3.fragment_type(), type);
461  fps.clear();
462  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
463 
464  fp.AddFragmentsToBuffer(gen.Generate(5));
465 
466  buffer->push(5, 8);
467 
468  sts = fp.applyRequests(fps);
469  TRACE_REQUIRE_EQUAL(sts, true);
470  TRACE_REQUIRE_EQUAL(fps.size(), 1);
471 
472  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
473  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 8);
474  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
475  type = artdaq::Fragment::ContainerFragmentType;
476  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
477  auto cf4 = artdaq::ContainerFragment(*fps.front());
478  TRACE_REQUIRE_EQUAL(cf4.block_count(), 3);
479  TRACE_REQUIRE_EQUAL(cf4.missing_data(), false);
480  type = artdaq::Fragment::FirstUserFragmentType;
481  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
482  TRACE_REQUIRE_EQUAL(cf4.at(0)->timestamp(), 7);
483  TRACE_REQUIRE_EQUAL(cf4.at(1)->timestamp(), 8);
484  TRACE_REQUIRE_EQUAL(cf4.at(2)->timestamp(), 9);
485  fps.clear();
486  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 6);
487 
488  TLOG(TLVL_INFO) << "CircularBufferMode test case END";
489 }
490 
491 BOOST_AUTO_TEST_CASE(WindowMode_Function)
492 {
493  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
494  TLOG(TLVL_INFO) << "WindowMode_Function test case BEGIN";
495  fhicl::ParameterSet ps;
496  ps.put<int>("fragment_id", 1);
497 
498  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
499  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
500  ps.put<size_t>("data_buffer_depth_fragments", 5);
501  ps.put<bool>("circular_buffer_mode", true);
502  ps.put<std::string>("request_mode", "window");
503  ps.put<size_t>("missing_request_window_timeout_us", 500000);
504  ps.put<size_t>("window_close_timeout_us", 500000);
505 
506  auto buffer = std::make_shared<artdaq::RequestBuffer>();
507  buffer->setRunning(true);
509  artdaq::FragmentBuffer fp(ps);
510  fp.SetRequestBuffer(buffer);
511 
512  buffer->push(1, 1);
513  fp.AddFragmentsToBuffer(gen.Generate(1));
514 
515  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
516 
517  artdaq::FragmentPtrs fps;
518  auto sts = fp.applyRequests(fps);
519  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
520  TRACE_REQUIRE_EQUAL(sts, true);
521  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
522  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
523  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
524  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
525  auto type = artdaq::Fragment::ContainerFragmentType;
526  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
527  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
528  auto cf = artdaq::ContainerFragment(*fps.front());
529  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
530  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
531  type = artdaq::Fragment::FirstUserFragmentType;
532  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
533  fps.clear();
534 
535  // No data for request
536  buffer->push(2, 2);
537 
538  sts = fp.applyRequests(fps);
539  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
540  TRACE_REQUIRE_EQUAL(sts, true);
541  TRACE_REQUIRE_EQUAL(fps.size(), 0);
542 
543  fp.AddFragmentsToBuffer(gen.Generate(1));
544 
545  sts = fp.applyRequests(fps);
546  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
547  TRACE_REQUIRE_EQUAL(sts, true);
548  TRACE_REQUIRE_EQUAL(fps.size(), 1);
549  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
550  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
551  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
552  type = artdaq::Fragment::ContainerFragmentType;
553  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
554  auto cf2 = artdaq::ContainerFragment(*fps.front());
555  TRACE_REQUIRE_EQUAL(cf2.block_count(), 1);
556  TRACE_REQUIRE_EQUAL(cf2.missing_data(), false);
557  type = artdaq::Fragment::FirstUserFragmentType;
558  TRACE_REQUIRE_EQUAL(cf2.fragment_type(), type);
559  fps.clear();
560 
561  // Request Timeout
562  buffer->push(4, 3);
563 
564  sts = fp.applyRequests(fps);
565  TRACE_REQUIRE_EQUAL(sts, true);
566  TRACE_REQUIRE_EQUAL(fps.size(), 0);
567  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
568 
569  usleep(1500000);
570  sts = fp.applyRequests(fps);
571  TRACE_REQUIRE_EQUAL(sts, true);
572  TRACE_REQUIRE_EQUAL(fps.size(), 1);
573 
574  // Also, missing request timeout
575  auto list = fp.GetSentWindowList(1);
576  TRACE_REQUIRE_EQUAL(list.size(), 1);
577  TRACE_REQUIRE_EQUAL(list.begin()->first, 4);
578  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
579 
580  usleep(1500000);
581 
582  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
583  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
584  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
585  type = artdaq::Fragment::ContainerFragmentType;
586  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
587  auto cf3 = artdaq::ContainerFragment(*fps.front());
588  TRACE_REQUIRE_EQUAL(cf3.block_count(), 0);
589  TRACE_REQUIRE_EQUAL(cf3.missing_data(), true);
590  type = artdaq::Fragment::EmptyFragmentType;
591  TRACE_REQUIRE_EQUAL(cf3.fragment_type(), type);
592  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
593  fps.clear();
594 
595  // Data-taking has passed request
596  fp.AddFragmentsToBuffer(gen.Generate(12));
597 
598  buffer->push(5, 4);
599 
600  list = fp.GetSentWindowList(1); // Out-of-order list is only updated in getNext calls
601  TRACE_REQUIRE_EQUAL(list.size(), 1);
602  sts = fp.applyRequests(fps);
603  list = fp.GetSentWindowList(1);
604  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 6);
605  TRACE_REQUIRE_EQUAL(list.size(), 0);
606  TRACE_REQUIRE_EQUAL(sts, true);
607  TRACE_REQUIRE_EQUAL(fps.size(), 1);
608  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
609  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
610  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
611  type = artdaq::Fragment::ContainerFragmentType;
612  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
613  auto cf4 = artdaq::ContainerFragment(*fps.front());
614  TRACE_REQUIRE_EQUAL(cf4.block_count(), 0);
615  TRACE_REQUIRE_EQUAL(cf4.missing_data(), true);
616  type = artdaq::Fragment::EmptyFragmentType;
617  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
618  fps.clear();
619 
620  // Out-of-order windows
621  buffer->push(7, 13);
622 
623  sts = fp.applyRequests(fps);
624  TRACE_REQUIRE_EQUAL(sts, true);
625  TRACE_REQUIRE_EQUAL(fps.size(), 1);
626  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
627  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 13);
628  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 7);
629  type = artdaq::Fragment::ContainerFragmentType;
630  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
631  auto cf5 = artdaq::ContainerFragment(*fps.front());
632  TRACE_REQUIRE_EQUAL(cf5.block_count(), 1);
633  TRACE_REQUIRE_EQUAL(cf5.missing_data(), false);
634  type = artdaq::Fragment::FirstUserFragmentType;
635  TRACE_REQUIRE_EQUAL(cf5.fragment_type(), type);
636  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 6);
637  fps.clear();
638 
639  list = fp.GetSentWindowList(1);
640  TRACE_REQUIRE_EQUAL(list.size(), 1);
641  TRACE_REQUIRE_EQUAL(list.begin()->first, 7);
642 
643  buffer->push(6, 12);
644 
645  sts = fp.applyRequests(fps);
646  TRACE_REQUIRE_EQUAL(sts, true);
647  TRACE_REQUIRE_EQUAL(fps.size(), 1);
648  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
649  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
650  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 6);
651  type = artdaq::Fragment::ContainerFragmentType;
652  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
653  auto cf6 = artdaq::ContainerFragment(*fps.front());
654  TRACE_REQUIRE_EQUAL(cf6.block_count(), 1);
655  TRACE_REQUIRE_EQUAL(cf6.missing_data(), false);
656  type = artdaq::Fragment::FirstUserFragmentType;
657  TRACE_REQUIRE_EQUAL(cf6.fragment_type(), type);
658  fps.clear();
659  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 8);
660 
661  list = fp.GetSentWindowList(1);
662  TRACE_REQUIRE_EQUAL(list.size(), 0);
663 
664  usleep(1500000);
665 
666  TLOG(TLVL_INFO) << "WindowMode_Function test case END";
667 }
668 
669 // 1. Both start and end before any data in buffer "RequestBeforeBuffer"
670 // 2. Start before buffer, end in buffer "RequestStartsBeforeBuffer"
671 // 3. Start befoer buffer, end after buffer "RequestOutsideBuffer"
672 // 4. Start and end in buffer "RequestInBuffer"
673 // 5. Start in buffer, end after buffer "RequestEndsAfterBuffer"
674 // 6. Start and end after buffer "RequestAfterBuffer"
675 BOOST_AUTO_TEST_CASE(WindowMode_RequestBeforeBuffer)
676 {
677  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
678  TLOG(TLVL_INFO) << "WindowMode_RequestBeforeBuffer test case BEGIN";
679  fhicl::ParameterSet ps;
680  ps.put<int>("fragment_id", 1);
681 
682  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
683  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
684  ps.put<bool>("circular_buffer_mode", true);
685  ps.put<size_t>("data_buffer_depth_fragments", 5);
686  ps.put<std::string>("request_mode", "window");
687 
688  auto buffer = std::make_shared<artdaq::RequestBuffer>();
689  buffer->setRunning(true);
691  artdaq::FragmentBuffer fp(ps);
692  fp.SetRequestBuffer(buffer);
693 
694  artdaq::FragmentPtrs fps;
695  int sts;
696  artdaq::Fragment::type_t type;
697 
698  // 1. Both start and end before any data in buffer
699  // -- Should return ContainerFragment with MissingData bit set and zero Fragments
700  fp.AddFragmentsToBuffer(gen.Generate(10)); // Buffer start is at ts 6, end at 10
701 
702  buffer->push(1, 1); // Requesting data from ts 1 to 3
703 
704  sts = fp.applyRequests(fps);
705  TRACE_REQUIRE_EQUAL(sts, true);
706  TRACE_REQUIRE_EQUAL(fps.size(), 1);
707  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
708  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
709  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
710  type = artdaq::Fragment::ContainerFragmentType;
711  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
712  auto cf4 = artdaq::ContainerFragment(*fps.front());
713  TRACE_REQUIRE_EQUAL(cf4.block_count(), 0);
714  TRACE_REQUIRE_EQUAL(cf4.missing_data(), true);
715  type = artdaq::Fragment::EmptyFragmentType;
716  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
717 
718  TLOG(TLVL_INFO) << "WindowMode_RequestBeforeBuffer test case END";
719 }
721 {
722  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
723  TLOG(TLVL_INFO) << "WindowMode_RequestStartsBeforeBuffer test case BEGIN";
724 
725  fhicl::ParameterSet ps;
726  ps.put<int>("fragment_id", 1);
727  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
728  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
729  ps.put<size_t>("data_buffer_depth_fragments", 5);
730  ps.put<bool>("circular_buffer_mode", true);
731  ps.put<std::string>("request_mode", "window");
732 
733  auto buffer = std::make_shared<artdaq::RequestBuffer>();
734  buffer->setRunning(true);
736  artdaq::FragmentBuffer fp(ps);
737  fp.SetRequestBuffer(buffer);
738 
739  artdaq::FragmentPtrs fps;
740  int sts;
741  artdaq::Fragment::type_t type;
742 
743  fp.AddFragmentsToBuffer(gen.Generate(10)); // Buffer contains 6 to 10
744 
745  // 2. Start before buffer, end in buffer
746  // -- Should return ContainerFragment with MissingData bit set and one or more Fragments
747  buffer->push(1, 4); // Requesting data from ts 4 to 6
748 
749  sts = fp.applyRequests(fps);
750  TRACE_REQUIRE_EQUAL(sts, true);
751  TRACE_REQUIRE_EQUAL(fps.size(), 1);
752  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
753  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
754  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
755  type = artdaq::Fragment::ContainerFragmentType;
756  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
757  auto cf4 = artdaq::ContainerFragment(*fps.front());
758  TRACE_REQUIRE_EQUAL(cf4.block_count(), 1);
759  TRACE_REQUIRE_EQUAL(cf4.missing_data(), true);
760  type = artdaq::Fragment::FirstUserFragmentType;
761  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
762 
763  TLOG(TLVL_INFO) << "WindowMode_RequestStartsBeforeBuffer test case END";
764 }
765 BOOST_AUTO_TEST_CASE(WindowMode_RequestOutsideBuffer)
766 {
767  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
768  TLOG(TLVL_INFO) << "WindowMode_RequestOutsideBuffer test case BEGIN";
769  fhicl::ParameterSet ps;
770  ps.put<int>("fragment_id", 1);
771  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
772  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 4);
773  ps.put<size_t>("window_close_timeout_us", 500000);
774  ps.put<bool>("circular_buffer_mode", true);
775  ps.put<size_t>("data_buffer_depth_fragments", 5);
776  ps.put<std::string>("request_mode", "window");
777 
778  auto buffer = std::make_shared<artdaq::RequestBuffer>();
779  buffer->setRunning(true);
781  artdaq::FragmentBuffer fp(ps);
782  fp.SetRequestBuffer(buffer);
783 
784  artdaq::FragmentPtrs fps;
785  int sts;
786  artdaq::Fragment::type_t type;
787 
788  fp.AddFragmentsToBuffer(gen.Generate(10)); // Buffer contains 6 to 10
789 
790  // 3. Start before buffer, end after buffer
791  // -- Should not return until buffer passes end or timeout (check both cases), MissingData bit set
792 
793  buffer->push(1, 6); // Requesting data from ts 6 to 9, buffer will contain 10
794 
795  sts = fp.applyRequests(fps);
796  TRACE_REQUIRE_EQUAL(sts, true);
797  TRACE_REQUIRE_EQUAL(fps.size(), 1);
798  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
799  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 6);
800  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
801  type = artdaq::Fragment::ContainerFragmentType;
802  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
803  auto cf = artdaq::ContainerFragment(*fps.front());
804  TRACE_REQUIRE_EQUAL(cf.block_count(), 4);
805  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
806  type = artdaq::Fragment::FirstUserFragmentType;
807  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
808  fps.clear();
809 
810  buffer->push(2, 9); // Requesting data from ts 9 to 12
811 
812  sts = fp.applyRequests(fps);
813  TRACE_REQUIRE_EQUAL(sts, true);
814  TRACE_REQUIRE_EQUAL(fps.size(), 0);
815 
816  fp.AddFragmentsToBuffer(gen.Generate(3)); // Buffer start is at ts 10, end at 13
817 
818  sts = fp.applyRequests(fps);
819  TRACE_REQUIRE_EQUAL(sts, true);
820  TRACE_REQUIRE_EQUAL(fps.size(), 1);
821  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
822  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 9);
823  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
824  type = artdaq::Fragment::ContainerFragmentType;
825  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
826  auto cf2 = artdaq::ContainerFragment(*fps.front());
827  TRACE_REQUIRE_EQUAL(cf2.block_count(), 3);
828  TRACE_REQUIRE_EQUAL(cf2.missing_data(), true);
829  type = artdaq::Fragment::FirstUserFragmentType;
830  TRACE_REQUIRE_EQUAL(cf2.fragment_type(), type);
831  fps.clear();
832 
833  buffer->push(3, 12); // Requesting data from ts 11 to 14
834 
835  sts = fp.applyRequests(fps);
836  TRACE_REQUIRE_EQUAL(sts, true);
837  TRACE_REQUIRE_EQUAL(fps.size(), 0);
838 
839  usleep(550000);
840 
841  sts = fp.applyRequests(fps);
842  TRACE_REQUIRE_EQUAL(sts, true);
843  TRACE_REQUIRE_EQUAL(fps.size(), 1);
844  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
845  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
846  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
847  type = artdaq::Fragment::ContainerFragmentType;
848  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
849  auto cf4 = artdaq::ContainerFragment(*fps.front());
850  TRACE_REQUIRE_EQUAL(cf4.block_count(), 1);
851  TRACE_REQUIRE_EQUAL(cf4.missing_data(), true);
852  type = artdaq::Fragment::FirstUserFragmentType;
853  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
854 
855  TLOG(TLVL_INFO) << "WindowMode_RequestOutsideBuffer test case END";
856 }
857 BOOST_AUTO_TEST_CASE(WindowMode_RequestInBuffer)
858 {
859  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
860  TLOG(TLVL_INFO) << "WindowMode_RequestInBuffer test case BEGIN";
861  fhicl::ParameterSet ps;
862  ps.put<int>("fragment_id", 1);
863  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
864  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
865  ps.put<bool>("circular_buffer_mode", true);
866  ps.put<size_t>("data_buffer_depth_fragments", 5);
867  ps.put<std::string>("request_mode", "window");
868 
869  auto buffer = std::make_shared<artdaq::RequestBuffer>();
870  buffer->setRunning(true);
872  artdaq::FragmentBuffer fp(ps);
873  fp.SetRequestBuffer(buffer);
874 
875  artdaq::FragmentPtrs fps;
876  int sts;
877  artdaq::Fragment::type_t type;
878 
879  // 4. Start and end in buffer
880  // -- Should return ContainerFragment with one or more Fragments
881  fp.AddFragmentsToBuffer(gen.Generate(6)); // Buffer start is at ts 2, end at 6
882 
883  buffer->push(1, 3); // Requesting data from ts 3 to 5
884 
885  sts = fp.applyRequests(fps);
886  TRACE_REQUIRE_EQUAL(sts, true);
887  TRACE_REQUIRE_EQUAL(fps.size(), 1);
888  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
889  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
890  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
891  type = artdaq::Fragment::ContainerFragmentType;
892  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
893  auto cf4 = artdaq::ContainerFragment(*fps.front());
894  TRACE_REQUIRE_EQUAL(cf4.block_count(), 3);
895  TRACE_REQUIRE_EQUAL(cf4.missing_data(), false);
896  type = artdaq::Fragment::FirstUserFragmentType;
897  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
898 
899  TLOG(TLVL_INFO) << "WindowMode_RequestInBuffer test case END";
900 }
902 {
903  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
904  TLOG(TLVL_INFO) << "WindowMode_RequestEndsAfterBuffer test case BEGIN";
905  fhicl::ParameterSet ps;
906  ps.put<int>("fragment_id", 1);
907  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
908  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
909  ps.put<size_t>("window_close_timeout_us", 500000);
910  ps.put<bool>("circular_buffer_mode", true);
911  ps.put<size_t>("data_buffer_depth_fragments", 5);
912  ps.put<std::string>("request_mode", "window");
913 
914  auto buffer = std::make_shared<artdaq::RequestBuffer>();
915  buffer->setRunning(true);
917  artdaq::FragmentBuffer fp(ps);
918  fp.SetRequestBuffer(buffer);
919 
920  artdaq::FragmentPtrs fps;
921  int sts;
922  artdaq::Fragment::type_t type;
923 
924  fp.AddFragmentsToBuffer(gen.Generate(6)); // Buffer contains 2 to 6
925 
926  // 5. Start in buffer, end after buffer
927  // -- Should not return until buffer passes end or timeout (check both cases). MissingData bit set if timeout
928  buffer->push(1, 5); // Requesting data from ts 5 to 7
929 
930  sts = fp.applyRequests(fps);
931  TRACE_REQUIRE_EQUAL(sts, true);
932  TRACE_REQUIRE_EQUAL(fps.size(), 0);
933 
934  fp.AddFragmentsToBuffer(gen.Generate(2)); // Buffer contains 4 to 8
935 
936  sts = fp.applyRequests(fps);
937  TRACE_REQUIRE_EQUAL(sts, true);
938  TRACE_REQUIRE_EQUAL(fps.size(), 1);
939  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
940  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
941  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
942  type = artdaq::Fragment::ContainerFragmentType;
943  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
944  auto cf = artdaq::ContainerFragment(*fps.front());
945  TRACE_REQUIRE_EQUAL(cf.block_count(), 3);
946  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
947  type = artdaq::Fragment::FirstUserFragmentType;
948  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
949  fps.clear();
950 
951  buffer->push(2, 8); // Requesting data from ts 8 to 10
952 
953  sts = fp.applyRequests(fps);
954  TRACE_REQUIRE_EQUAL(sts, true);
955  TRACE_REQUIRE_EQUAL(fps.size(), 0);
956 
957  usleep(550000);
958 
959  sts = fp.applyRequests(fps);
960  TRACE_REQUIRE_EQUAL(sts, true);
961  TRACE_REQUIRE_EQUAL(fps.size(), 1);
962  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
963  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 8);
964  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
965  type = artdaq::Fragment::ContainerFragmentType;
966  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
967  auto cf4 = artdaq::ContainerFragment(*fps.front());
968  TRACE_REQUIRE_EQUAL(cf4.block_count(), 1);
969  TRACE_REQUIRE_EQUAL(cf4.missing_data(), true);
970  type = artdaq::Fragment::FirstUserFragmentType;
971  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
972 
973  TLOG(TLVL_INFO) << "WindowMode_RequestEndsAfterBuffer test case END";
974 }
975 BOOST_AUTO_TEST_CASE(WindowMode_RequestAfterBuffer)
976 {
977  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
978  TLOG(TLVL_INFO) << "WindowMode_RequestAfterBuffer test case BEGIN";
979  fhicl::ParameterSet ps;
980  ps.put<int>("fragment_id", 1);
981  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
982  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
983  ps.put<size_t>("window_close_timeout_us", 500000);
984  ps.put<bool>("circular_buffer_mode", true);
985  ps.put<size_t>("data_buffer_depth_fragments", 5);
986  ps.put<std::string>("request_mode", "window");
987 
988  auto buffer = std::make_shared<artdaq::RequestBuffer>();
989  buffer->setRunning(true);
991  artdaq::FragmentBuffer fp(ps);
992  fp.SetRequestBuffer(buffer);
993 
994  artdaq::FragmentPtrs fps;
995  int sts;
996  artdaq::Fragment::type_t type;
997 
998  // 6. Start and end after buffer
999  // -- Should not return until buffer passes end or timeout (check both cases). MissingData bit set if timeout
1000  fp.AddFragmentsToBuffer(gen.Generate(10)); // Buffer start is 6, end at 10
1001 
1002  buffer->push(1, 11); // Requesting data from ts 11 to 13
1003 
1004  sts = fp.applyRequests(fps);
1005  TRACE_REQUIRE_EQUAL(sts, true);
1006  TRACE_REQUIRE_EQUAL(fps.size(), 0);
1007  fp.AddFragmentsToBuffer(gen.Generate(1)); // Buffer start is 7, end at 11
1008 
1009  sts = fp.applyRequests(fps);
1010  TRACE_REQUIRE_EQUAL(sts, true);
1011  TRACE_REQUIRE_EQUAL(fps.size(), 0);
1012 
1013  fp.AddFragmentsToBuffer(gen.Generate(3)); // Buffer start is 10, end at 14
1014 
1015  sts = fp.applyRequests(fps);
1016  TRACE_REQUIRE_EQUAL(sts, true);
1017  TRACE_REQUIRE_EQUAL(fps.size(), 1);
1018  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1019  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 11);
1020  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1021  type = artdaq::Fragment::ContainerFragmentType;
1022  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1023  auto cf = artdaq::ContainerFragment(*fps.front());
1024  TRACE_REQUIRE_EQUAL(cf.block_count(), 3);
1025  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1026  type = artdaq::Fragment::FirstUserFragmentType;
1027  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1028  fps.clear();
1029 
1030  buffer->push(2, 16); // Requesting data from ts 15 to 17
1031 
1032  sts = fp.applyRequests(fps);
1033  TRACE_REQUIRE_EQUAL(sts, true);
1034  TRACE_REQUIRE_EQUAL(fps.size(), 0);
1035 
1036  usleep(550000);
1037 
1038  sts = fp.applyRequests(fps);
1039  TRACE_REQUIRE_EQUAL(sts, true);
1040  TRACE_REQUIRE_EQUAL(fps.size(), 1);
1041  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1042  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 16);
1043  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1044  type = artdaq::Fragment::ContainerFragmentType;
1045  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1046  auto cf4 = artdaq::ContainerFragment(*fps.front());
1047  TRACE_REQUIRE_EQUAL(cf4.block_count(), 0);
1048  TRACE_REQUIRE_EQUAL(cf4.missing_data(), true);
1049  type = artdaq::Fragment::EmptyFragmentType;
1050  TRACE_REQUIRE_EQUAL(cf4.fragment_type(), type);
1051 
1052  TLOG(TLVL_INFO) << "WindowMode_RequestAfterBuffer test case END";
1053 }
1054 
1055 BOOST_AUTO_TEST_CASE(SequenceIDMode)
1056 {
1057  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1058  TLOG(TLVL_INFO) << "SequenceIDMode test case BEGIN";
1059  fhicl::ParameterSet ps;
1060  ps.put<int>("fragment_id", 1);
1061  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1062  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1063  ps.put<std::string>("request_mode", "SequenceID");
1064 
1065  auto buffer = std::make_shared<artdaq::RequestBuffer>();
1066  buffer->setRunning(true);
1068  artdaq::FragmentBuffer fp(ps);
1069  fp.SetRequestBuffer(buffer);
1070 
1071  buffer->push(1, 1);
1072  fp.AddFragmentsToBuffer(gen.Generate(1));
1073 
1074  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
1075 
1076  // Test that Fragment with matching Sequence ID and timestamp is returned
1077  artdaq::FragmentPtrs fps;
1078  auto sts = fp.applyRequests(fps);
1079  auto type = artdaq::Fragment::FirstUserFragmentType;
1080  TRACE_REQUIRE_EQUAL(sts, true);
1081  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
1082  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1083  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1084  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1085  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1086  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
1087  fps.clear();
1088 
1089  // Test that no Fragment is returned when one does not exist in the buffer
1090  buffer->push(2, 5);
1091 
1092  sts = fp.applyRequests(fps);
1093  TRACE_REQUIRE_EQUAL(sts, true);
1094  TRACE_REQUIRE_EQUAL(fps.size(), 0u);
1095 
1096  // Test that Fragment with matching Sequence ID and non-matching timestamp is returned
1097  fp.AddFragmentsToBuffer(gen.Generate(1));
1098 
1099  sts = fp.applyRequests(fps);
1100  TRACE_REQUIRE_EQUAL(sts, true);
1101  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
1102  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1103  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
1104  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1105  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1106  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1107  fps.clear();
1108 
1109  // Test out-of-order requests, with non-matching timestamps
1110  fp.AddFragmentsToBuffer(gen.Generate(2));
1111 
1112  buffer->push(4, 7);
1113 
1114  sts = fp.applyRequests(fps);
1115  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1116  TRACE_REQUIRE_EQUAL(sts, true);
1117  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
1118  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1119  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
1120  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1121  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1122  fps.clear();
1123 
1124  buffer->push(3, 6);
1125 
1126  sts = fp.applyRequests(fps);
1127  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
1128  TRACE_REQUIRE_EQUAL(sts, true);
1129  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
1130  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1131  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
1132  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1133  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1134 
1135  TLOG(TLVL_INFO) << "SequenceIDMode test case END";
1136 }
1137 
1138 BOOST_AUTO_TEST_CASE(IgnoreRequests_MultipleIDs)
1139 {
1140  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1141  TLOG(TLVL_INFO) << "IgnoreRequests_MultipleIDs test case BEGIN";
1142  fhicl::ParameterSet ps;
1143  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1144  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1145  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1146  ps.put<std::string>("request_mode", "ignored");
1147 
1148  auto buffer = std::make_shared<artdaq::RequestBuffer>();
1149  buffer->setRunning(true);
1151  artdaq::FragmentBuffer fp(ps);
1152  fp.SetRequestBuffer(buffer);
1153 
1154  buffer->push(53, 35);
1155  fp.AddFragmentsToBuffer(gen.Generate(1));
1156 
1157  artdaq::FragmentPtrs fps;
1158  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1159  auto sts = fp.applyRequests(fps);
1160  TRACE_REQUIRE_EQUAL(sts, true);
1161  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1162  while (fps.size() > 0)
1163  {
1164  ids[fps.front()->fragmentID()]++;
1165  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1166  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1167  fps.pop_front();
1168  }
1169 
1170  TRACE_REQUIRE_EQUAL(ids[1], 1);
1171  TRACE_REQUIRE_EQUAL(ids[2], 1);
1172  TRACE_REQUIRE_EQUAL(ids[3], 1);
1173  ids.clear();
1174 
1175  fps.clear();
1176 
1177  TLOG(TLVL_INFO) << "IgnoreRequests_MultipleIDs test case END";
1178 }
1179 
1180 BOOST_AUTO_TEST_CASE(SingleMode_MultipleIDs)
1181 {
1182  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1183  TLOG(TLVL_INFO) << "SingleMode_MultipleIDs test case BEGIN";
1184  fhicl::ParameterSet ps;
1185  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1186  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1187  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1188  ps.put<std::string>("request_mode", "single");
1189 
1190  auto buffer = std::make_shared<artdaq::RequestBuffer>();
1191  buffer->setRunning(true);
1193  artdaq::FragmentBuffer fp(ps);
1194  fp.SetRequestBuffer(buffer);
1195 
1196  buffer->push(1, 1);
1197  fp.AddFragmentsToBuffer(gen.Generate(1));
1198 
1199  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
1200 
1201  artdaq::FragmentPtrs fps;
1202  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1203  auto sts = fp.applyRequests(fps);
1204  auto type = artdaq::Fragment::FirstUserFragmentType;
1205  TRACE_REQUIRE_EQUAL(sts, true);
1206  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1207  while (fps.size() > 0)
1208  {
1209  ids[fps.front()->fragmentID()]++;
1210  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1211  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1212  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1213  fps.pop_front();
1214  }
1215  TRACE_REQUIRE_EQUAL(ids[1], 1);
1216  TRACE_REQUIRE_EQUAL(ids[2], 1);
1217  TRACE_REQUIRE_EQUAL(ids[3], 1);
1218  ids.clear();
1219 
1220  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
1221  fps.clear();
1222 
1223  buffer->push(2, 5);
1224 
1225  sts = fp.applyRequests(fps);
1226  TRACE_REQUIRE_EQUAL(sts, true);
1227  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1228  while (fps.size() > 0)
1229  {
1230  ids[fps.front()->fragmentID()]++;
1231  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
1232  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1233  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1234  fps.pop_front();
1235  }
1236  TRACE_REQUIRE_EQUAL(ids[1], 1);
1237  TRACE_REQUIRE_EQUAL(ids[2], 1);
1238  TRACE_REQUIRE_EQUAL(ids[3], 1);
1239  ids.clear();
1240 
1241  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1242  fps.clear();
1243 
1244  fp.AddFragmentsToBuffer(gen.Generate(2));
1245 
1246  buffer->push(4, 7);
1247 
1248  sts = fp.applyRequests(fps);
1249  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
1250  TRACE_REQUIRE_EQUAL(sts, true);
1251  TRACE_REQUIRE_EQUAL(fps.size(), 6);
1252  auto ts = artdaq::Fragment::InvalidTimestamp;
1253  auto emptyType = artdaq::Fragment::EmptyFragmentType;
1254  for (auto ii = 0; ii < 3; ++ii)
1255  {
1256  ids[fps.front()->fragmentID()]++;
1257  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
1258  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1259  TRACE_REQUIRE_EQUAL(fps.front()->type(), emptyType);
1260  fps.pop_front();
1261  }
1262  TRACE_REQUIRE_EQUAL(ids[1], 1);
1263  TRACE_REQUIRE_EQUAL(ids[2], 1);
1264  TRACE_REQUIRE_EQUAL(ids[3], 1);
1265  ids.clear();
1266  for (auto ii = 0; ii < 3; ++ii)
1267  {
1268  ids[fps.front()->fragmentID()]++;
1269  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
1270  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1271  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1272  fps.pop_front();
1273  }
1274  TRACE_REQUIRE_EQUAL(ids[1], 1);
1275  TRACE_REQUIRE_EQUAL(ids[2], 1);
1276  TRACE_REQUIRE_EQUAL(ids[3], 1);
1277  ids.clear();
1278  fps.clear();
1279 
1280  // Single mode should generate 3 Fragments, 2 new ones and one old one
1281  fp.AddFragmentsToBuffer(gen.Generate(1));
1282 
1283  buffer->push(5, 9);
1284 
1285  sts = fp.applyRequests(fps);
1286  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 6);
1287  TRACE_REQUIRE_EQUAL(sts, true);
1288  TRACE_REQUIRE_EQUAL(fps.size(), 3);
1289  for (auto ii = 0; ii < 3; ++ii)
1290  {
1291  ids[fps.front()->fragmentID()]++;
1292  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 9);
1293  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
1294  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1295  fps.pop_front();
1296  }
1297  TRACE_REQUIRE_EQUAL(ids[1], 1);
1298  TRACE_REQUIRE_EQUAL(ids[2], 1);
1299  TRACE_REQUIRE_EQUAL(ids[3], 1);
1300  ids.clear();
1301  fps.clear();
1302 
1303  TLOG(TLVL_INFO) << "SingleMode_MultipleIDs test case END";
1304 }
1305 
1306 BOOST_AUTO_TEST_CASE(BufferMode_MultipleIDs)
1307 {
1308  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1309  TLOG(TLVL_INFO) << "BufferMode_MultipleIDs test case BEGIN";
1310  fhicl::ParameterSet ps;
1311  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1312  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1313  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1314  ps.put<std::string>("request_mode", "buffer");
1315 
1316  auto buffer = std::make_shared<artdaq::RequestBuffer>();
1317  buffer->setRunning(true);
1319  artdaq::FragmentBuffer fp(ps);
1320  fp.SetRequestBuffer(buffer);
1321 
1322  buffer->push(1, 1);
1323  fp.AddFragmentsToBuffer(gen.Generate(1));
1324 
1325  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
1326 
1327  artdaq::FragmentPtrs fps;
1328  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1329  auto sts = fp.applyRequests(fps);
1330  TRACE_REQUIRE_EQUAL(sts, true);
1331  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1332  auto type = artdaq::Fragment::ContainerFragmentType;
1333  while (fps.size() > 0)
1334  {
1335  ids[fps.front()->fragmentID()]++;
1336  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1337  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1338  type = artdaq::Fragment::ContainerFragmentType;
1339  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1340  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
1341  auto cf = artdaq::ContainerFragment(*fps.front());
1342  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1343  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1344  type = artdaq::Fragment::FirstUserFragmentType;
1345  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1346  fps.pop_front();
1347  }
1348  TRACE_REQUIRE_EQUAL(ids[1], 1);
1349  TRACE_REQUIRE_EQUAL(ids[2], 1);
1350  TRACE_REQUIRE_EQUAL(ids[3], 1);
1351  ids.clear();
1352  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
1353  fps.clear();
1354 
1355  buffer->push(2, 5);
1356 
1357  sts = fp.applyRequests(fps);
1358  TRACE_REQUIRE_EQUAL(sts, true);
1359  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1360  while (fps.size() > 0)
1361  {
1362  ids[fps.front()->fragmentID()]++;
1363  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
1364  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1365  type = artdaq::Fragment::ContainerFragmentType;
1366  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1367  auto cf = artdaq::ContainerFragment(*fps.front());
1368  TRACE_REQUIRE_EQUAL(cf.block_count(), 0);
1369  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1370  type = artdaq::Fragment::EmptyFragmentType;
1371  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1372  fps.pop_front();
1373  }
1374  TRACE_REQUIRE_EQUAL(ids[1], 1);
1375  TRACE_REQUIRE_EQUAL(ids[2], 1);
1376  TRACE_REQUIRE_EQUAL(ids[3], 1);
1377  ids.clear();
1378  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1379  fps.clear();
1380 
1381  fp.AddFragmentsToBuffer(gen.Generate(2));
1382 
1383  buffer->push(4, 7);
1384 
1385  sts = fp.applyRequests(fps);
1386  TRACE_REQUIRE_EQUAL(sts, true);
1387  TRACE_REQUIRE_EQUAL(fps.size(), 6);
1388 
1389  auto ts = artdaq::Fragment::InvalidTimestamp;
1390  auto emptyType = artdaq::Fragment::EmptyFragmentType;
1391  for (auto ii = 0; ii < 3; ++ii)
1392  {
1393  ids[fps.front()->fragmentID()]++;
1394  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
1395  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1396  TRACE_REQUIRE_EQUAL(fps.front()->type(), emptyType);
1397  TRACE_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
1398  fps.pop_front();
1399  }
1400  TRACE_REQUIRE_EQUAL(ids[1], 1);
1401  TRACE_REQUIRE_EQUAL(ids[2], 1);
1402  TRACE_REQUIRE_EQUAL(ids[3], 1);
1403  ids.clear();
1404  for (auto ii = 0; ii < 3; ++ii)
1405  {
1406  ids[fps.front()->fragmentID()]++;
1407  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
1408  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1409  type = artdaq::Fragment::ContainerFragmentType;
1410  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1411  auto cf3 = artdaq::ContainerFragment(*fps.front());
1412  TRACE_REQUIRE_EQUAL(cf3.block_count(), 2);
1413  TRACE_REQUIRE_EQUAL(cf3.missing_data(), false);
1414  type = artdaq::Fragment::FirstUserFragmentType;
1415  TRACE_REQUIRE_EQUAL(cf3.fragment_type(), type);
1416  fps.pop_front();
1417  }
1418  TRACE_REQUIRE_EQUAL(ids[1], 1);
1419  TRACE_REQUIRE_EQUAL(ids[2], 1);
1420  TRACE_REQUIRE_EQUAL(ids[3], 1);
1421  ids.clear();
1422 
1423  fps.clear();
1424  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
1425 
1426  TLOG(TLVL_INFO) << "BufferMode_MultipleIDs test case END";
1427 }
1428 
1429 BOOST_AUTO_TEST_CASE(CircularBufferMode_MultipleIDs)
1430 {
1431  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1432  TLOG(TLVL_INFO) << "CircularBufferMode_MultipleIDs test case BEGIN";
1433  fhicl::ParameterSet ps;
1434  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1435  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1436  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1437  ps.put<bool>("circular_buffer_mode", true);
1438  ps.put<int>("data_buffer_depth_fragments", 3);
1439  ps.put<std::string>("request_mode", "buffer");
1440 
1441  auto buffer = std::make_shared<artdaq::RequestBuffer>();
1442  buffer->setRunning(true);
1444  artdaq::FragmentBuffer fp(ps);
1445  fp.SetRequestBuffer(buffer);
1446 
1447  buffer->push(1, 1);
1448  fp.AddFragmentsToBuffer(gen.Generate(1));
1449 
1450  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
1451 
1452  artdaq::FragmentPtrs fps;
1453  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1454  auto sts = fp.applyRequests(fps);
1455  auto type = artdaq::Fragment::ContainerFragmentType;
1456  TRACE_REQUIRE_EQUAL(sts, true);
1457  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1458  while (fps.size() > 0)
1459  {
1460  ids[fps.front()->fragmentID()]++;
1461  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1462  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1463  type = artdaq::Fragment::ContainerFragmentType;
1464  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1465  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
1466  auto cf = artdaq::ContainerFragment(*fps.front());
1467  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1468  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1469  type = artdaq::Fragment::FirstUserFragmentType;
1470  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1471  fps.pop_front();
1472  }
1473  TRACE_REQUIRE_EQUAL(ids[1], 1);
1474  TRACE_REQUIRE_EQUAL(ids[2], 1);
1475  TRACE_REQUIRE_EQUAL(ids[3], 1);
1476  ids.clear();
1477 
1478  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
1479  fps.clear();
1480 
1481  buffer->push(2, 5);
1482 
1483  sts = fp.applyRequests(fps);
1484  TRACE_REQUIRE_EQUAL(sts, true);
1485  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1486  while (fps.size() > 0)
1487  {
1488  ids[fps.front()->fragmentID()]++;
1489  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
1490  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1491  type = artdaq::Fragment::ContainerFragmentType;
1492  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1493  auto cf = artdaq::ContainerFragment(*fps.front());
1494  TRACE_REQUIRE_EQUAL(cf.block_count(), 0);
1495  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1496  type = artdaq::Fragment::EmptyFragmentType;
1497  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1498  fps.pop_front();
1499  }
1500  TRACE_REQUIRE_EQUAL(ids[1], 1);
1501  TRACE_REQUIRE_EQUAL(ids[2], 1);
1502  TRACE_REQUIRE_EQUAL(ids[3], 1);
1503  ids.clear();
1504 
1505  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1506  fps.clear();
1507 
1508  fp.AddFragmentsToBuffer(gen.Generate(3));
1509 
1510  buffer->push(4, 7);
1511 
1512  sts = fp.applyRequests(fps);
1513  TRACE_REQUIRE_EQUAL(sts, true);
1514  TRACE_REQUIRE_EQUAL(fps.size(), 6);
1515 
1516  auto ts = artdaq::Fragment::InvalidTimestamp;
1517  auto emptyType = artdaq::Fragment::EmptyFragmentType;
1518  for (auto ii = 0; ii < 3; ++ii)
1519  {
1520  ids[fps.front()->fragmentID()]++;
1521  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
1522  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1523  TRACE_REQUIRE_EQUAL(fps.front()->type(), emptyType);
1524  TRACE_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
1525  fps.pop_front();
1526  }
1527  TRACE_REQUIRE_EQUAL(ids[1], 1);
1528  TRACE_REQUIRE_EQUAL(ids[2], 1);
1529  TRACE_REQUIRE_EQUAL(ids[3], 1);
1530  ids.clear();
1531  for (auto ii = 0; ii < 3; ++ii)
1532  {
1533  ids[fps.front()->fragmentID()]++;
1534  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
1535  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1536  type = artdaq::Fragment::ContainerFragmentType;
1537  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1538  auto cf3 = artdaq::ContainerFragment(*fps.front());
1539  TRACE_REQUIRE_EQUAL(cf3.block_count(), 3);
1540  TRACE_REQUIRE_EQUAL(cf3.missing_data(), false);
1541  type = artdaq::Fragment::FirstUserFragmentType;
1542  TRACE_REQUIRE_EQUAL(cf3.fragment_type(), type);
1543  fps.pop_front();
1544  }
1545  TRACE_REQUIRE_EQUAL(ids[1], 1);
1546  TRACE_REQUIRE_EQUAL(ids[2], 1);
1547  TRACE_REQUIRE_EQUAL(ids[3], 1);
1548  ids.clear();
1549 
1550  fps.clear();
1551  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
1552 
1553  fp.AddFragmentsToBuffer(gen.Generate(5));
1554 
1555  buffer->push(5, 8);
1556 
1557  sts = fp.applyRequests(fps);
1558  TRACE_REQUIRE_EQUAL(sts, true);
1559  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1560  while (fps.size() > 0)
1561  {
1562  ids[fps.front()->fragmentID()]++;
1563  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 8);
1564  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
1565  type = artdaq::Fragment::ContainerFragmentType;
1566  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1567  auto cf = artdaq::ContainerFragment(*fps.front());
1568  TRACE_REQUIRE_EQUAL(cf.block_count(), 3);
1569  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1570  type = artdaq::Fragment::FirstUserFragmentType;
1571  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1572  TRACE_REQUIRE_EQUAL(cf.at(0)->timestamp(), 7);
1573  TRACE_REQUIRE_EQUAL(cf.at(1)->timestamp(), 8);
1574  TRACE_REQUIRE_EQUAL(cf.at(2)->timestamp(), 9);
1575  fps.pop_front();
1576  }
1577  TRACE_REQUIRE_EQUAL(ids[1], 1);
1578  TRACE_REQUIRE_EQUAL(ids[2], 1);
1579  TRACE_REQUIRE_EQUAL(ids[3], 1);
1580  ids.clear();
1581 
1582  fps.clear();
1583  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 6);
1584 
1585  TLOG(TLVL_INFO) << "CircularBufferMode_MultipleIDs test case END";
1586 }
1587 
1588 BOOST_AUTO_TEST_CASE(WindowMode_Function_MultipleIDs)
1589 {
1590  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1591  TLOG(TLVL_INFO) << "WindowMode_Function_MultipleIDs test case BEGIN";
1592  fhicl::ParameterSet ps;
1593  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1594  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1595  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1596  ps.put<size_t>("data_buffer_depth_fragments", 5);
1597  ps.put<bool>("circular_buffer_mode", true);
1598  ps.put<std::string>("request_mode", "window");
1599  ps.put<size_t>("missing_request_window_timeout_us", 500000);
1600  ps.put<size_t>("window_close_timeout_us", 500000);
1601 
1602  auto buffer = std::make_shared<artdaq::RequestBuffer>();
1603  buffer->setRunning(true);
1605  artdaq::FragmentBuffer fp(ps);
1606  fp.SetRequestBuffer(buffer);
1607 
1608  buffer->push(1, 1);
1609  fp.AddFragmentsToBuffer(gen.Generate(1));
1610 
1611  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
1612 
1613  artdaq::FragmentPtrs fps;
1614  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1615  auto sts = fp.applyRequests(fps);
1616  auto type = artdaq::Fragment::ContainerFragmentType;
1617  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
1618  TRACE_REQUIRE_EQUAL(sts, true);
1619  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1620  while (fps.size() > 0)
1621  {
1622  ids[fps.front()->fragmentID()]++;
1623  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1624  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1625  type = artdaq::Fragment::ContainerFragmentType;
1626  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1627  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
1628  auto cf = artdaq::ContainerFragment(*fps.front());
1629  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1630  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1631  type = artdaq::Fragment::FirstUserFragmentType;
1632  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1633  fps.pop_front();
1634  }
1635  TRACE_REQUIRE_EQUAL(ids[1], 1);
1636  TRACE_REQUIRE_EQUAL(ids[2], 1);
1637  TRACE_REQUIRE_EQUAL(ids[3], 1);
1638  ids.clear();
1639  fps.clear();
1640 
1641  // No data for request
1642  buffer->push(2, 2);
1643 
1644  sts = fp.applyRequests(fps);
1645  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
1646  TRACE_REQUIRE_EQUAL(sts, true);
1647  TRACE_REQUIRE_EQUAL(fps.size(), 0);
1648 
1649  fp.AddFragmentsToBuffer(gen.Generate(1));
1650 
1651  sts = fp.applyRequests(fps);
1652  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1653  TRACE_REQUIRE_EQUAL(sts, true);
1654  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1655  while (fps.size() > 0)
1656  {
1657  ids[fps.front()->fragmentID()]++;
1658  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
1659  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1660  type = artdaq::Fragment::ContainerFragmentType;
1661  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1662  auto cf = artdaq::ContainerFragment(*fps.front());
1663  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1664  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1665  type = artdaq::Fragment::FirstUserFragmentType;
1666  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1667  fps.pop_front();
1668  }
1669  TRACE_REQUIRE_EQUAL(ids[1], 1);
1670  TRACE_REQUIRE_EQUAL(ids[2], 1);
1671  TRACE_REQUIRE_EQUAL(ids[3], 1);
1672  ids.clear();
1673  fps.clear();
1674 
1675  // Request Timeout
1676  buffer->push(4, 3);
1677 
1678  sts = fp.applyRequests(fps);
1679  TRACE_REQUIRE_EQUAL(sts, true);
1680  TRACE_REQUIRE_EQUAL(fps.size(), 0);
1681  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1682 
1683  usleep(1500000);
1684  sts = fp.applyRequests(fps);
1685  TRACE_REQUIRE_EQUAL(sts, true);
1686  TRACE_REQUIRE_EQUAL(fps.size(), 3);
1687 
1688  // Also, missing request timeout
1689  auto list = fp.GetSentWindowList(1);
1690  TRACE_REQUIRE_EQUAL(list.size(), 1);
1691  TRACE_REQUIRE_EQUAL(list.begin()->first, 4);
1692  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1693 
1694  usleep(1500000);
1695 
1696  while (fps.size() > 0)
1697  {
1698  ids[fps.front()->fragmentID()]++;
1699  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
1700  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1701  type = artdaq::Fragment::ContainerFragmentType;
1702  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1703  auto cf = artdaq::ContainerFragment(*fps.front());
1704  TRACE_REQUIRE_EQUAL(cf.block_count(), 0);
1705  TRACE_REQUIRE_EQUAL(cf.missing_data(), true);
1706  type = artdaq::Fragment::EmptyFragmentType;
1707  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1708  fps.pop_front();
1709  }
1710  TRACE_REQUIRE_EQUAL(ids[1], 1);
1711  TRACE_REQUIRE_EQUAL(ids[2], 1);
1712  TRACE_REQUIRE_EQUAL(ids[3], 1);
1713  ids.clear();
1714 
1715  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1716  fps.clear();
1717 
1718  // Data-taking has passed request
1719  fp.AddFragmentsToBuffer(gen.Generate(12));
1720 
1721  buffer->push(5, 4);
1722 
1723  list = fp.GetSentWindowList(1); // Out-of-order list is only updated in getNext calls
1724  TRACE_REQUIRE_EQUAL(list.size(), 1);
1725  sts = fp.applyRequests(fps);
1726  list = fp.GetSentWindowList(1);
1727  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 6);
1728  TRACE_REQUIRE_EQUAL(list.size(), 0);
1729  TRACE_REQUIRE_EQUAL(sts, true);
1730  TRACE_REQUIRE_EQUAL(fps.size(), 3);
1731  while (fps.size() > 0)
1732  {
1733  ids[fps.front()->fragmentID()]++;
1734  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
1735  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
1736  type = artdaq::Fragment::ContainerFragmentType;
1737  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1738  auto cf = artdaq::ContainerFragment(*fps.front());
1739  TRACE_REQUIRE_EQUAL(cf.block_count(), 0);
1740  TRACE_REQUIRE_EQUAL(cf.missing_data(), true);
1741  type = artdaq::Fragment::EmptyFragmentType;
1742  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1743  fps.pop_front();
1744  }
1745  TRACE_REQUIRE_EQUAL(ids[1], 1);
1746  TRACE_REQUIRE_EQUAL(ids[2], 1);
1747  TRACE_REQUIRE_EQUAL(ids[3], 1);
1748  ids.clear();
1749  fps.clear();
1750 
1751  // Out-of-order windows
1752  buffer->push(7, 13);
1753 
1754  sts = fp.applyRequests(fps);
1755  TRACE_REQUIRE_EQUAL(sts, true);
1756  TRACE_REQUIRE_EQUAL(fps.size(), 3);
1757  while (fps.size() > 0)
1758  {
1759  ids[fps.front()->fragmentID()]++;
1760  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 13);
1761  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 7);
1762  type = artdaq::Fragment::ContainerFragmentType;
1763  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1764  auto cf = artdaq::ContainerFragment(*fps.front());
1765  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1766  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1767  type = artdaq::Fragment::FirstUserFragmentType;
1768  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1769  fps.pop_front();
1770  }
1771  TRACE_REQUIRE_EQUAL(ids[1], 1);
1772  TRACE_REQUIRE_EQUAL(ids[2], 1);
1773  TRACE_REQUIRE_EQUAL(ids[3], 1);
1774  ids.clear();
1775  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 6);
1776  fps.clear();
1777 
1778  list = fp.GetSentWindowList(1);
1779  TRACE_REQUIRE_EQUAL(list.size(), 1);
1780  TRACE_REQUIRE_EQUAL(list.begin()->first, 7);
1781 
1782  buffer->push(6, 12);
1783 
1784  sts = fp.applyRequests(fps);
1785  TRACE_REQUIRE_EQUAL(sts, true);
1786  TRACE_REQUIRE_EQUAL(fps.size(), 3);
1787  while (fps.size() > 0)
1788  {
1789  ids[fps.front()->fragmentID()]++;
1790  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
1791  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 6);
1792  type = artdaq::Fragment::ContainerFragmentType;
1793  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1794  auto cf = artdaq::ContainerFragment(*fps.front());
1795  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1796  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1797  type = artdaq::Fragment::FirstUserFragmentType;
1798  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1799  fps.pop_front();
1800  }
1801  TRACE_REQUIRE_EQUAL(ids[1], 1);
1802  TRACE_REQUIRE_EQUAL(ids[2], 1);
1803  TRACE_REQUIRE_EQUAL(ids[3], 1);
1804  ids.clear();
1805  fps.clear();
1806  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 8);
1807 
1808  list = fp.GetSentWindowList(1);
1809  TRACE_REQUIRE_EQUAL(list.size(), 0);
1810 
1811  fp.AddFragmentsToBuffer(gen.Generate(1, {1, 2}));
1812 
1813  buffer->push(8, 15);
1814 
1815  sts = fp.applyRequests(fps);
1816  TRACE_REQUIRE_EQUAL(sts, true);
1817  TRACE_REQUIRE_EQUAL(fps.size(), 2);
1818  while (fps.size() > 0)
1819  {
1820  ids[fps.front()->fragmentID()]++;
1821  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 15);
1822  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 8);
1823  type = artdaq::Fragment::ContainerFragmentType;
1824  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1825  auto cf = artdaq::ContainerFragment(*fps.front());
1826  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1827  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1828  type = artdaq::Fragment::FirstUserFragmentType;
1829  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1830  fps.pop_front();
1831  }
1832  TRACE_REQUIRE_EQUAL(ids[1], 1);
1833  TRACE_REQUIRE_EQUAL(ids[2], 1);
1834  TRACE_REQUIRE_EQUAL(ids[3], 0);
1835  ids.clear();
1836  fps.clear();
1837  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 8);
1838 
1839  gen.setTimestamp(14); // Reset timestamp
1840  fp.AddFragmentsToBuffer(gen.Generate(1, {3}));
1841 
1842  sts = fp.applyRequests(fps);
1843  TRACE_REQUIRE_EQUAL(sts, true);
1844  TRACE_REQUIRE_EQUAL(fps.size(), 1);
1845  while (fps.size() > 0)
1846  {
1847  ids[fps.front()->fragmentID()]++;
1848  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 15);
1849  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 8);
1850  type = artdaq::Fragment::ContainerFragmentType;
1851  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1852  auto cf = artdaq::ContainerFragment(*fps.front());
1853  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
1854  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
1855  type = artdaq::Fragment::FirstUserFragmentType;
1856  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
1857  fps.pop_front();
1858  }
1859  TRACE_REQUIRE_EQUAL(ids[1], 0);
1860  TRACE_REQUIRE_EQUAL(ids[2], 0);
1861  TRACE_REQUIRE_EQUAL(ids[3], 1);
1862  ids.clear();
1863  fps.clear();
1864  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 9);
1865 
1866  TLOG(TLVL_INFO) << "WindowMode_Function_MultipleIDs test case END";
1867 }
1868 
1869 BOOST_AUTO_TEST_CASE(SequenceIDMode_MultipleIDs)
1870 {
1871  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1872  TLOG(TLVL_INFO) << "SequenceIDMode_MultipleIDs test case BEGIN";
1873  fhicl::ParameterSet ps;
1874  ps.put<int>("board_id", 1);
1875  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1876  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1877  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1878  ps.put<bool>("separate_data_thread", true);
1879  ps.put<bool>("separate_monitoring_thread", false);
1880  ps.put<int64_t>("hardware_poll_interval_us", 0);
1881  ps.put<std::string>("request_mode", "SequenceID");
1882 
1883  auto buffer = std::make_shared<artdaq::RequestBuffer>();
1884  buffer->setRunning(true);
1886  artdaq::FragmentBuffer fp(ps);
1887  fp.SetRequestBuffer(buffer);
1888 
1889  buffer->push(1, 1);
1890  fp.AddFragmentsToBuffer(gen.Generate(1));
1891 
1892  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
1893 
1894  // Test that Fragment with matching Sequence ID and timestamp is returned
1895  artdaq::FragmentPtrs fps;
1896  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1897  auto sts = fp.applyRequests(fps);
1898  auto type = artdaq::Fragment::FirstUserFragmentType;
1899  TRACE_REQUIRE_EQUAL(sts, true);
1900  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1901 
1902  for (auto ii = 0; ii < 3; ++ii)
1903  {
1904  ids[fps.front()->fragmentID()]++;
1905  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1906  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1907  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1908  fps.pop_front();
1909  }
1910  TRACE_REQUIRE_EQUAL(ids[1], 1);
1911  TRACE_REQUIRE_EQUAL(ids[2], 1);
1912  TRACE_REQUIRE_EQUAL(ids[3], 1);
1913  ids.clear();
1914 
1915  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
1916  fps.clear();
1917 
1918  // Test that no Fragment is returned when one does not exist in the buffer
1919  buffer->push(2, 5);
1920 
1921  sts = fp.applyRequests(fps);
1922  TRACE_REQUIRE_EQUAL(sts, true);
1923  TRACE_REQUIRE_EQUAL(fps.size(), 0u);
1924 
1925  // Test that Fragment with matching Sequence ID and non-matching timestamp is returned
1926  fp.AddFragmentsToBuffer(gen.Generate(1));
1927 
1928  sts = fp.applyRequests(fps);
1929  TRACE_REQUIRE_EQUAL(sts, true);
1930  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1931  for (auto ii = 0; ii < 3; ++ii)
1932  {
1933  ids[fps.front()->fragmentID()]++;
1934  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
1935  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1936  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1937  fps.pop_front();
1938  }
1939  TRACE_REQUIRE_EQUAL(ids[1], 1);
1940  TRACE_REQUIRE_EQUAL(ids[2], 1);
1941  TRACE_REQUIRE_EQUAL(ids[3], 1);
1942  ids.clear();
1943 
1944  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1945  fps.clear();
1946 
1947  // Test out-of-order requests, with non-matching timestamps
1948  fp.AddFragmentsToBuffer(gen.Generate(2));
1949 
1950  buffer->push(4, 7);
1951 
1952  sts = fp.applyRequests(fps);
1953  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
1954  TRACE_REQUIRE_EQUAL(sts, true);
1955  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1956  for (auto ii = 0; ii < 3; ++ii)
1957  {
1958  ids[fps.front()->fragmentID()]++;
1959  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
1960  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1961  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1962  fps.pop_front();
1963  }
1964  TRACE_REQUIRE_EQUAL(ids[1], 1);
1965  TRACE_REQUIRE_EQUAL(ids[2], 1);
1966  TRACE_REQUIRE_EQUAL(ids[3], 1);
1967  ids.clear();
1968  fps.clear();
1969 
1970  buffer->push(3, 6);
1971 
1972  sts = fp.applyRequests(fps);
1973  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 5);
1974  TRACE_REQUIRE_EQUAL(sts, true);
1975  TRACE_REQUIRE_EQUAL(fps.size(), 3u);
1976  for (auto ii = 0; ii < 3; ++ii)
1977  {
1978  ids[fps.front()->fragmentID()]++;
1979  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
1980  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1981  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
1982  fps.pop_front();
1983  }
1984  TRACE_REQUIRE_EQUAL(ids[1], 1);
1985  TRACE_REQUIRE_EQUAL(ids[2], 1);
1986  TRACE_REQUIRE_EQUAL(ids[3], 1);
1987  ids.clear();
1988 
1989  TLOG(TLVL_INFO) << "SequenceIDMode_MultipleIDs test case END";
1990 }
1991 
1992 BOOST_AUTO_TEST_CASE(IgnoreRequests_StateMachine)
1993 {
1994  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
1995  TLOG(TLVL_INFO) << "IgnoreRequests_StateMachine test case BEGIN";
1996  fhicl::ParameterSet ps;
1997  ps.put<int>("fragment_id", 1);
1998  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1999  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
2000  ps.put<std::string>("request_mode", "ignored");
2001 
2002  auto buffer = std::make_shared<artdaq::RequestBuffer>();
2003  buffer->setRunning(true);
2004 
2005  artdaq::FragmentBuffer fp(ps);
2006  fp.SetRequestBuffer(buffer);
2007 
2008  buffer->push(53, 35);
2009 
2011 
2012  fp.AddFragmentsToBuffer(gen.Generate(1));
2013 
2014  artdaq::FragmentPtrs fps;
2015  auto sts = fp.applyRequests(fps);
2016 
2017  TRACE_REQUIRE_EQUAL(sts, true);
2018  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
2019  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2020  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
2021  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
2022  fps.clear();
2023 
2024  fp.Reset(false);
2025  sts = fp.applyRequests(fps);
2026 
2027  TRACE_REQUIRE_EQUAL(sts, true);
2028  TRACE_REQUIRE_EQUAL(fps.size(), 0u);
2029 
2030  fp.AddFragmentsToBuffer(gen.Generate(1));
2031 
2032  sts = fp.applyRequests(fps);
2033 
2034  TRACE_REQUIRE_EQUAL(sts, true);
2035  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
2036  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2037  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
2038  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
2039  fps.clear();
2040 
2041  fp.Stop();
2042  fp.AddFragmentsToBuffer(gen.Generate(1));
2043 
2044  sts = fp.applyRequests(fps);
2045 
2046  TRACE_REQUIRE_EQUAL(sts, false);
2047  TRACE_REQUIRE_EQUAL(fps.size(), 0u);
2048 
2049  TLOG(TLVL_INFO) << "IgnoreRequests_StateMachine test case END";
2050 }
2051 
2052 BOOST_AUTO_TEST_CASE(SingleMode_StateMachine)
2053 {
2054  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
2055  TLOG(TLVL_INFO) << "SingleMode_StateMachine test case BEGIN";
2056  fhicl::ParameterSet ps;
2057  ps.put<int>("fragment_id", 1);
2058  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
2059  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
2060  ps.put<std::string>("request_mode", "single");
2061 
2062  auto type = artdaq::Fragment::FirstUserFragmentType;
2063  auto buffer = std::make_shared<artdaq::RequestBuffer>();
2064  buffer->setRunning(true);
2066  artdaq::FragmentBuffer fp(ps);
2067  fp.SetRequestBuffer(buffer);
2068 
2069  buffer->push(1, 1);
2070  fp.AddFragmentsToBuffer(gen.Generate(1));
2071  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
2072 
2073  artdaq::FragmentPtrs fps;
2074  auto sts = fp.applyRequests(fps);
2075  TRACE_REQUIRE_EQUAL(sts, true);
2076  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
2077  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2078  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
2079  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
2080  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
2081  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
2082  fps.clear();
2083 
2084  fp.Reset(false);
2085  buffer->reset();
2086  sts = fp.applyRequests(fps);
2087  TRACE_REQUIRE_EQUAL(sts, true);
2088  TRACE_REQUIRE_EQUAL(fps.size(), 0u);
2089 
2090  buffer->push(1, 1);
2091  fp.AddFragmentsToBuffer(gen.Generate(1));
2092  sts = fp.applyRequests(fps);
2093  TRACE_REQUIRE_EQUAL(sts, true);
2094  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
2095  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2096  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
2097  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
2098  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
2099  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 2);
2100  fps.clear();
2101 
2102  fp.Stop();
2103  buffer->push(2, 5);
2104  sts = fp.applyRequests(fps);
2105  TRACE_REQUIRE_EQUAL(sts, true);
2106  TRACE_REQUIRE_EQUAL(fps.size(), 1u);
2107  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2108  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
2109  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
2110  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
2111  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 3);
2112  fps.clear();
2113 
2114  buffer->setRunning(false);
2115  fp.AddFragmentsToBuffer(gen.Generate(2));
2116  buffer->push(4, 7);
2117 
2118  sts = fp.applyRequests(fps);
2119  TRACE_REQUIRE_EQUAL(sts, false);
2120  TRACE_REQUIRE_EQUAL(fps.size(), 0);
2121 
2122  TLOG(TLVL_INFO) << "SingleMode_StateMachine test case END";
2123 }
2124 
2125 BOOST_AUTO_TEST_CASE(WindowMode_RateTests)
2126 {
2127  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
2128  TLOG(TLVL_INFO) << "WindowMode_RateTests test case BEGIN";
2129  fhicl::ParameterSet ps;
2130  ps.put<int>("fragment_id", 1);
2131 
2132  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
2133  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
2134  ps.put<size_t>("data_buffer_depth_fragments", 2 * RATE_TEST_COUNT);
2135  ps.put<bool>("circular_buffer_mode", false);
2136  ps.put<std::string>("request_mode", "window");
2137  ps.put<size_t>("missing_request_window_timeout_us", 500000);
2138  ps.put<size_t>("window_close_timeout_us", 500000);
2139 
2140  auto buffer = std::make_shared<artdaq::RequestBuffer>();
2141  buffer->setRunning(true);
2143  artdaq::FragmentBuffer fp(ps);
2144  fp.SetRequestBuffer(buffer);
2145 
2146  auto beginop = std::chrono::steady_clock::now();
2147 
2148  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests BEGIN";
2149  size_t req_seq = 1;
2150  for (; req_seq < RATE_TEST_COUNT + 1; ++req_seq)
2151  {
2152  buffer->push(req_seq, req_seq);
2153  }
2154  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests END.Time elapsed = " << artdaq::TimeUtils::GetElapsedTime(beginop)
2155  << "(" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " reqs/s) ";
2156 
2157  beginop = std::chrono::steady_clock::now();
2158  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments BEGIN";
2159  fp.AddFragmentsToBuffer(gen.Generate(RATE_TEST_COUNT));
2160  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments END. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(beginop)
2161  << " (" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " frags/s)";
2162 
2163  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
2164 
2165  beginop = std::chrono::steady_clock::now();
2166  TLOG(TLVL_INFO) << "Applying requests BEGIN";
2167  artdaq::FragmentPtrs fps;
2168  auto sts = fp.applyRequests(fps);
2169  TLOG(TLVL_INFO) << "Applying requests END. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(beginop)
2170  << " (" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " reqs/s)";
2171  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), RATE_TEST_COUNT + 1);
2172  TRACE_REQUIRE_EQUAL(sts, true);
2173  TRACE_REQUIRE_EQUAL(fps.size(), RATE_TEST_COUNT);
2174  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2175  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
2176  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
2177  auto type = artdaq::Fragment::ContainerFragmentType;
2178  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
2179  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
2180  auto cf = artdaq::ContainerFragment(*fps.front());
2181  TRACE_REQUIRE_EQUAL(cf.block_count(), 1);
2182  TRACE_REQUIRE_EQUAL(cf.missing_data(), false);
2183  type = artdaq::Fragment::FirstUserFragmentType;
2184  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
2185  fps.clear();
2186 
2187  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests BEGIN";
2188  for (; req_seq < (2 * RATE_TEST_COUNT) + 1; ++req_seq)
2189  {
2190  buffer->push(req_seq, req_seq);
2191  }
2192  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests END. Time elapsed = " << artdaq::TimeUtils::GetElapsedTime(beginop)
2193  << "(" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " reqs/s) ";
2194 
2195  beginop = std::chrono::steady_clock::now();
2196  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments Individually BEGIN";
2197  for (int ii = 0; ii < RATE_TEST_COUNT; ++ii)
2198  fp.AddFragmentsToBuffer(gen.Generate(1));
2199  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments Individually END. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(beginop)
2200  << " (" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " frags/s)";
2201 
2202  TLOG(TLVL_INFO) << "WindowMode_RateTests test case END";
2203 }
2204 
2205 BOOST_AUTO_TEST_CASE(CircularBufferMode_RateTests)
2206 {
2207  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
2208  TLOG(TLVL_INFO) << "CircularBufferMode_RateTests test case BEGIN";
2209  fhicl::ParameterSet ps;
2210  ps.put<int>("fragment_id", 1);
2211  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
2212  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
2213  ps.put<size_t>("data_buffer_depth_fragments", RATE_TEST_COUNT / 2);
2214  ps.put<bool>("circular_buffer_mode", true);
2215  ps.put<std::string>("request_mode", "window");
2216  ps.put<size_t>("missing_request_window_timeout_us", 500000);
2217  ps.put<size_t>("window_close_timeout_us", 500000);
2218 
2219  auto buffer = std::make_shared<artdaq::RequestBuffer>();
2220  buffer->setRunning(true);
2222  artdaq::FragmentBuffer fp(ps);
2223  fp.SetRequestBuffer(buffer);
2224 
2225  auto beginop = std::chrono::steady_clock::now();
2226 
2227  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests BEGIN";
2228  for (size_t ii = 1; ii < RATE_TEST_COUNT + 1; ++ii)
2229  {
2230  buffer->push(ii, ii);
2231  }
2232  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests END. Time elapsed = " << artdaq::TimeUtils::GetElapsedTime(beginop)
2233  << "(" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " reqs / s) ";
2234 
2235  beginop = std::chrono::steady_clock::now();
2236  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments BEGIN";
2237  fp.AddFragmentsToBuffer(gen.Generate(RATE_TEST_COUNT));
2238  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments END. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(beginop)
2239  << " (" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " frags/s)";
2240 
2241  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), 1);
2242 
2243  beginop = std::chrono::steady_clock::now();
2244  TLOG(TLVL_INFO) << "Applying requests BEGIN";
2245  artdaq::FragmentPtrs fps;
2246  auto sts = fp.applyRequests(fps);
2247  TLOG(TLVL_INFO) << "Applying requests END. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(beginop)
2248  << " (" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " reqs/s)";
2249  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), RATE_TEST_COUNT + 1);
2250  TRACE_REQUIRE_EQUAL(sts, true);
2251  TRACE_REQUIRE_EQUAL(fps.size(), RATE_TEST_COUNT);
2252  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2253  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
2254  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
2255  auto type = artdaq::Fragment::ContainerFragmentType;
2256  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
2257  auto cf = artdaq::ContainerFragment(*fps.front());
2258  TRACE_REQUIRE_EQUAL(cf.block_count(), 0);
2259  TRACE_REQUIRE_EQUAL(cf.missing_data(), true);
2260  type = artdaq::Fragment::EmptyFragmentType;
2261  TRACE_REQUIRE_EQUAL(cf.fragment_type(), type);
2262  fps.clear();
2263 
2264  TLOG(TLVL_INFO) << "CircularBufferMode_RateTests test case END";
2265 }
2266 
2267 BOOST_AUTO_TEST_CASE(WindowMode_RateTests_threaded)
2268 {
2269  artdaq::configureMessageFacility("FragmentBuffer_t", true, MESSAGEFACILITY_DEBUG);
2270  TLOG(TLVL_INFO) << "WindowMode_RateTests_threaded test case BEGIN";
2271  fhicl::ParameterSet ps;
2272  ps.put<int>("fragment_id", 1);
2273  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
2274  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
2275  ps.put<size_t>("data_buffer_depth_fragments", RATE_TEST_COUNT);
2276  ps.put<bool>("circular_buffer_mode", false);
2277  ps.put<std::string>("request_mode", "window");
2278  ps.put<size_t>("missing_request_window_timeout_us", 500000);
2279  ps.put<size_t>("window_close_timeout_us", 500000);
2280 
2281  auto buffer = std::make_shared<artdaq::RequestBuffer>();
2282  buffer->setRunning(true);
2284  artdaq::FragmentBuffer fp(ps);
2285  fp.SetRequestBuffer(buffer);
2286 
2287  std::atomic<int> thread_sync = 0;
2288  auto gen_requests = [&]() {
2289  ++thread_sync;
2290  while (thread_sync < 3) {}
2291  auto beginop = std::chrono::steady_clock::now();
2292  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests BEGIN";
2293  for (size_t ii = 1; ii < RATE_TEST_COUNT + 1; ++ii)
2294  {
2295  buffer->push(ii, ii);
2296  }
2297  TLOG(TLVL_INFO) << "Generating " << RATE_TEST_COUNT << " requests END. Time elapsed = " << artdaq::TimeUtils::GetElapsedTime(beginop)
2298  << "(" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " reqs / s) ";
2299  };
2300 
2301  auto gen_frags = [&]() {
2302  ++thread_sync;
2303  while (thread_sync < 3) {}
2304  auto beginop = std::chrono::steady_clock::now();
2305  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments BEGIN";
2306  for (int ii = 0; ii < RATE_TEST_COUNT; ++ii)
2307  fp.AddFragmentsToBuffer(gen.Generate(1));
2308  TLOG(TLVL_INFO) << "Generating/adding " << RATE_TEST_COUNT << " Fragments END. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(beginop)
2309  << " (" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(beginop) << " frags/s)";
2310  };
2311 
2312  auto apply_requests = [&]() {
2313  ++thread_sync;
2314  while (thread_sync < 3) {}
2315  artdaq::FragmentPtrs fps;
2316  auto begin_test = std::chrono::steady_clock::now();
2317  while (fps.size() < RATE_TEST_COUNT)
2318  {
2319  auto beginop = std::chrono::steady_clock::now();
2320  TLOG(TLVL_INFO) << "Applying requests BEGIN";
2321  auto sts = fp.applyRequests(fps);
2322  TRACE_REQUIRE_EQUAL(sts, true);
2323  TLOG(TLVL_INFO) << "Applying requests END. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(beginop);
2324  }
2325  TLOG(TLVL_INFO) << "All request replies received. Time elapsed=" << artdaq::TimeUtils::GetElapsedTime(begin_test)
2326  << " (" << RATE_TEST_COUNT / artdaq::TimeUtils::GetElapsedTime(begin_test) << " reqs/s)";
2327  TRACE_REQUIRE_EQUAL(fp.GetNextSequenceID(), RATE_TEST_COUNT + 1);
2328 
2329  TRACE_REQUIRE_EQUAL(fps.size(), RATE_TEST_COUNT);
2330  TRACE_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
2331  TRACE_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
2332  TRACE_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
2333  auto type = artdaq::Fragment::ContainerFragmentType;
2334  TRACE_REQUIRE_EQUAL(fps.front()->type(), type);
2335  fps.clear();
2336  };
2337 
2338  std::thread t1(gen_requests);
2339  std::thread t2(gen_frags);
2340  std::thread t3(apply_requests);
2341 
2342  t1.join();
2343  t2.join();
2344  t3.join();
2345 
2346  TLOG(TLVL_INFO) << "WindowMode_RateTests_threaded test case END";
2347 }
2348 BOOST_AUTO_TEST_SUITE_END()
void AddFragmentsToBuffer(FragmentPtrs frags)
Add Fragments to the FragmentBuffer.
bool applyRequests(FragmentPtrs &frags)
See if any requests have been received, and add the corresponding data Fragment objects to the output...
void SetRequestBuffer(std::shared_ptr< RequestBuffer > buffer)
Set the pointer to the RequestBuffer used to retrieve requests.
std::map< Fragment::sequence_id_t, std::chrono::steady_clock::time_point > GetSentWindowList(Fragment::fragment_id_t id)
Get the map of Window-mode requests fulfilled by this Fragment Geneerator for the given Fragment ID...
CommandableFragmentGenerator derived class for testing.
void Stop()
Inform the FragmentBuffer that it should stop.
artdaq::FragmentPtrs Generate(size_t n, std::vector< artdaq::Fragment::fragment_id_t > fragmentIds=std::vector< artdaq::Fragment::fragment_id_t >())
Generate Fragments.
void Reset(bool stop)
Reset the FragmentBuffer (flushes all Fragments from buffers)
artdaq::Fragment::sequence_id_t GetNextSequenceID() const
Get the next sequence ID expected by this FragmentBuffer. This is used to track sent windows and miss...
FragmentBuffer is a FragmentGenerator-derived abstract class that defines the interface for a Fragmen...
artdaq::Fragment::timestamp_t getTimestamp()
Get the timestamp that will be used for the next Fragment.
FragmentBufferTestGenerator(const fhicl::ParameterSet &ps)
FragmentBufferTestGenerator Constructor.
void setTimestamp(artdaq::Fragment::timestamp_t ts)
Set the timestamp to be used for the next Fragment.