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