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