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