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