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