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