artdaq  v3_07_01
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(BufferMode_KeepLatest)
409 {
410  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
411  TLOG(TLVL_INFO) << "BufferMode_KeepLatest 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>("separate_monitoring_thread", false);
427  ps.put<int64_t>("hardware_poll_interval_us", 0);
428  ps.put<std::string>("request_mode", "buffer");
429  ps.put("request_delay_ms", DELAY_TIME);
430  ps.put("send_requests", true);
431  ps.put("buffer_mode_keep_latest", true);
432 
433  artdaq::RequestSender t(ps);
434  t.SetRunNumber(1);
435  t.AddRequest(1, 1);
436 
438  gen.StartCmd(1, 0xFFFFFFFF, 1);
439  gen.waitForFrags();
440  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
441 
442  artdaq::FragmentPtrs fps;
443  auto sts = gen.getNext(fps);
444  BOOST_REQUIRE_EQUAL(sts, true);
445  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
446  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
447  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
448  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
449  auto type = artdaq::Fragment::ContainerFragmentType;
450  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
451  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
452  auto cf = artdaq::ContainerFragment(*fps.front());
453  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
454  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
455  type = artdaq::Fragment::FirstUserFragmentType;
456  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
457  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
458  fps.clear();
459 
460  t.AddRequest(2, 5);
461  sts = gen.getNext(fps);
462  BOOST_REQUIRE_EQUAL(sts, true);
463  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
464  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
465  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
466  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
467  type = artdaq::Fragment::ContainerFragmentType;
468  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
469  auto cf2 = artdaq::ContainerFragment(*fps.front());
470  BOOST_REQUIRE_EQUAL(cf2.block_count(), 1);
471  BOOST_REQUIRE_EQUAL(cf2.missing_data(), false);
472  type = artdaq::Fragment::FirstUserFragmentType;
473  BOOST_REQUIRE_EQUAL(cf2.fragment_type(), type);
474  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
475  fps.clear();
476 
477  gen.setFireCount(2);
478  gen.waitForFrags();
479  t.AddRequest(4, 7);
480  sts = gen.getNext(fps);
481  BOOST_REQUIRE_EQUAL(sts, true);
482  BOOST_REQUIRE_EQUAL(fps.size(), 2);
483 
484  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
485  auto ts = artdaq::Fragment::InvalidTimestamp;
486  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
487  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
488  auto emptyType = artdaq::Fragment::EmptyFragmentType;
489  BOOST_REQUIRE_EQUAL(fps.front()->type(), emptyType);
490  BOOST_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
491  fps.pop_front();
492  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
493  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
494  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
495  type = artdaq::Fragment::ContainerFragmentType;
496  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
497  auto cf3 = artdaq::ContainerFragment(*fps.front());
498  BOOST_REQUIRE_EQUAL(cf3.block_count(), 2);
499  BOOST_REQUIRE_EQUAL(cf3.missing_data(), false);
500  type = artdaq::Fragment::FirstUserFragmentType;
501  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
502  fps.clear();
503  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 5);
504 
505  gen.StopCmd(0xFFFFFFFF, 1);
506  gen.joinThreads();
507 
508  TLOG(TLVL_INFO) << "BufferMode_KeepLatest test case END";
509 }
510 BOOST_AUTO_TEST_CASE(CircularBufferMode)
511 {
512  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
513  TLOG(TLVL_INFO) << "CircularBufferMode test case BEGIN";
514  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
515  const int DELAY_TIME = 100;
516  fhicl::ParameterSet ps;
517  ps.put<int>("board_id", 1);
518  ps.put<int>("fragment_id", 1);
519  ps.put<int>("request_port", REQUEST_PORT);
520 #if MULTICAST_MODE
521  ps.put<std::string>("request_address", "227.18.12.31");
522 #else
523  ps.put<std::string>("request_address", "localhost");
524 #endif
525  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
526  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
527  ps.put<bool>("separate_data_thread", true);
528  ps.put<bool>("circular_buffer_mode", true);
529  ps.put<int>("data_buffer_depth_fragments", 3);
530  ps.put<bool>("separate_monitoring_thread", false);
531  ps.put<int64_t>("hardware_poll_interval_us", 0);
532  ps.put<std::string>("request_mode", "buffer");
533  ps.put("request_delay_ms", DELAY_TIME);
534  ps.put("send_requests", true);
535 
536  artdaq::RequestSender t(ps);
537  t.SetRunNumber(1);
538  t.AddRequest(1, 1);
539 
541  gen.StartCmd(1, 0xFFFFFFFF, 1);
542  gen.waitForFrags();
543  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
544 
545  artdaq::FragmentPtrs fps;
546  auto sts = gen.getNext(fps);
547  BOOST_REQUIRE_EQUAL(sts, true);
548  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
549  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
550  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
551  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
552  auto type = artdaq::Fragment::ContainerFragmentType;
553  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
554  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
555  auto cf = artdaq::ContainerFragment(*fps.front());
556  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
557  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
558  type = artdaq::Fragment::FirstUserFragmentType;
559  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
560  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
561  fps.clear();
562 
563  t.AddRequest(2, 5);
564  sts = gen.getNext(fps);
565  BOOST_REQUIRE_EQUAL(sts, true);
566  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
567  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
568  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
569  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
570  type = artdaq::Fragment::ContainerFragmentType;
571  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
572  auto cf2 = artdaq::ContainerFragment(*fps.front());
573  BOOST_REQUIRE_EQUAL(cf2.block_count(), 0);
574  BOOST_REQUIRE_EQUAL(cf2.missing_data(), false);
575  type = artdaq::Fragment::EmptyFragmentType;
576  BOOST_REQUIRE_EQUAL(cf2.fragment_type(), type);
577  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
578  fps.clear();
579 
580  gen.setFireCount(3);
581  gen.waitForFrags();
582  t.AddRequest(4, 7);
583  sts = gen.getNext(fps);
584  BOOST_REQUIRE_EQUAL(sts, true);
585  BOOST_REQUIRE_EQUAL(fps.size(), 2);
586 
587  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
588  auto ts = artdaq::Fragment::InvalidTimestamp;
589  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
590  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
591  auto emptyType = artdaq::Fragment::EmptyFragmentType;
592  BOOST_REQUIRE_EQUAL(fps.front()->type(), emptyType);
593  BOOST_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
594  fps.pop_front();
595  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
596  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
597  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
598  type = artdaq::Fragment::ContainerFragmentType;
599  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
600  auto cf3 = artdaq::ContainerFragment(*fps.front());
601  BOOST_REQUIRE_EQUAL(cf3.block_count(), 3);
602  BOOST_REQUIRE_EQUAL(cf3.missing_data(), false);
603  type = artdaq::Fragment::FirstUserFragmentType;
604  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
605  fps.clear();
606  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 5);
607 
608  gen.setFireCount(5);
609  gen.waitForFrags();
610  t.AddRequest(5, 8);
611  sts = gen.getNext(fps);
612  BOOST_REQUIRE_EQUAL(sts, true);
613  BOOST_REQUIRE_EQUAL(fps.size(), 1);
614 
615  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
616  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 8);
617  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
618  type = artdaq::Fragment::ContainerFragmentType;
619  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
620  auto cf4 = artdaq::ContainerFragment(*fps.front());
621  BOOST_REQUIRE_EQUAL(cf4.block_count(), 3);
622  BOOST_REQUIRE_EQUAL(cf4.missing_data(), false);
623  type = artdaq::Fragment::FirstUserFragmentType;
624  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
625  BOOST_REQUIRE_EQUAL(cf4.at(0)->timestamp(), 7);
626  BOOST_REQUIRE_EQUAL(cf4.at(1)->timestamp(), 8);
627  BOOST_REQUIRE_EQUAL(cf4.at(2)->timestamp(), 9);
628  fps.clear();
629  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
630 
631  gen.StopCmd(0xFFFFFFFF, 1);
632  gen.joinThreads();
633 
634  TLOG(TLVL_INFO) << "CircularBufferMode test case END";
635 }
636 
637 BOOST_AUTO_TEST_CASE(WindowMode_Function)
638 {
639  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
640  TLOG(TLVL_INFO) << "WindowMode_Function test case BEGIN";
641  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
642  const int DELAY_TIME = 100;
643  fhicl::ParameterSet ps;
644  ps.put<int>("board_id", 1);
645  ps.put<int>("fragment_id", 1);
646  ps.put<int>("request_port", REQUEST_PORT);
647 #if MULTICAST_MODE
648  ps.put<std::string>("request_address", "227.18.12.32");
649 #else
650  ps.put<std::string>("request_address", "localhost");
651 #endif
652  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
653  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
654  ps.put<bool>("separate_data_thread", true);
655  ps.put<bool>("separate_monitoring_thread", false);
656  ps.put<int64_t>("hardware_poll_interval_us", 0);
657  ps.put<size_t>("data_buffer_depth_fragments", 5);
658  ps.put<bool>("circular_buffer_mode", true);
659  ps.put<std::string>("request_mode", "window");
660  ps.put<size_t>("missing_request_window_timeout_us", 500000);
661  ps.put<size_t>("window_close_timeout_us", 500000);
662  ps.put("request_delay_ms", DELAY_TIME);
663  ps.put("send_requests", true);
664 
665  artdaq::RequestSender t(ps);
666  t.SetRunNumber(1);
667  t.AddRequest(1, 1);
668 
670  gen.StartCmd(1, 0xFFFFFFFF, 1);
671  gen.waitForFrags();
672  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
673 
674  artdaq::FragmentPtrs fps;
675  auto sts = gen.getNext(fps);
676  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
677  BOOST_REQUIRE_EQUAL(sts, true);
678  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
679  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
680  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
681  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
682  auto type = artdaq::Fragment::ContainerFragmentType;
683  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
684  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
685  auto cf = artdaq::ContainerFragment(*fps.front());
686  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
687  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
688  type = artdaq::Fragment::FirstUserFragmentType;
689  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
690  fps.clear();
691 
692  // No data for request
693  t.AddRequest(2, 2);
694  sts = gen.getNext(fps);
695  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
696  BOOST_REQUIRE_EQUAL(sts, true);
697  BOOST_REQUIRE_EQUAL(fps.size(), 0);
698 
699  gen.setFireCount(1);
700  gen.waitForFrags();
701  sts = gen.getNext(fps);
702  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
703  BOOST_REQUIRE_EQUAL(sts, true);
704  BOOST_REQUIRE_EQUAL(fps.size(), 1);
705  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
706  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
707  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
708  type = artdaq::Fragment::ContainerFragmentType;
709  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
710  auto cf2 = artdaq::ContainerFragment(*fps.front());
711  BOOST_REQUIRE_EQUAL(cf2.block_count(), 1);
712  BOOST_REQUIRE_EQUAL(cf2.missing_data(), false);
713  type = artdaq::Fragment::FirstUserFragmentType;
714  BOOST_REQUIRE_EQUAL(cf2.fragment_type(), type);
715  fps.clear();
716 
717  // Request Timeout
718  t.AddRequest(4, 3);
719  sts = gen.getNext(fps);
720  BOOST_REQUIRE_EQUAL(sts, true);
721  BOOST_REQUIRE_EQUAL(fps.size(), 0);
722  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
723 
724  usleep(1500000);
725  sts = gen.getNext(fps);
726  BOOST_REQUIRE_EQUAL(sts, true);
727  BOOST_REQUIRE_EQUAL(fps.size(), 1);
728 
729  // Also, missing request timeout
730  auto list = gen.GetSentWindowList(1);
731  BOOST_REQUIRE_EQUAL(list.size(), 1);
732  BOOST_REQUIRE_EQUAL(list.begin()->first, 4);
733  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
734 
735  usleep(1500000);
736 
737  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
738  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
739  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
740  type = artdaq::Fragment::ContainerFragmentType;
741  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
742  auto cf3 = artdaq::ContainerFragment(*fps.front());
743  BOOST_REQUIRE_EQUAL(cf3.block_count(), 0);
744  BOOST_REQUIRE_EQUAL(cf3.missing_data(), true);
745  type = artdaq::Fragment::EmptyFragmentType;
746  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
747  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
748  fps.clear();
749 
750  // Data-taking has passed request
751  gen.setFireCount(12);
752  gen.waitForFrags();
753  t.AddRequest(5, 4);
754  list = gen.GetSentWindowList(1); // Out-of-order list is only updated in getNext calls
755  BOOST_REQUIRE_EQUAL(list.size(), 1);
756  sts = gen.getNext(fps);
757  list = gen.GetSentWindowList(1);
758  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
759  BOOST_REQUIRE_EQUAL(list.size(), 0);
760  BOOST_REQUIRE_EQUAL(sts, true);
761  BOOST_REQUIRE_EQUAL(fps.size(), 1);
762  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
763  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
764  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
765  type = artdaq::Fragment::ContainerFragmentType;
766  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
767  auto cf4 = artdaq::ContainerFragment(*fps.front());
768  BOOST_REQUIRE_EQUAL(cf4.block_count(), 0);
769  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
770  type = artdaq::Fragment::EmptyFragmentType;
771  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
772  fps.clear();
773 
774  // Out-of-order windows
775  t.AddRequest(7, 13);
776  sts = gen.getNext(fps);
777  BOOST_REQUIRE_EQUAL(sts, true);
778  BOOST_REQUIRE_EQUAL(fps.size(), 1);
779  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
780  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 13);
781  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 7);
782  type = artdaq::Fragment::ContainerFragmentType;
783  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
784  auto cf5 = artdaq::ContainerFragment(*fps.front());
785  BOOST_REQUIRE_EQUAL(cf5.block_count(), 1);
786  BOOST_REQUIRE_EQUAL(cf5.missing_data(), false);
787  type = artdaq::Fragment::FirstUserFragmentType;
788  BOOST_REQUIRE_EQUAL(cf5.fragment_type(), type);
789  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
790  fps.clear();
791 
792  list = gen.GetSentWindowList(1);
793  BOOST_REQUIRE_EQUAL(list.size(), 1);
794  BOOST_REQUIRE_EQUAL(list.begin()->first, 7);
795 
796  t.AddRequest(6, 12);
797  sts = gen.getNext(fps);
798  BOOST_REQUIRE_EQUAL(sts, true);
799  BOOST_REQUIRE_EQUAL(fps.size(), 1);
800  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
801  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
802  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 6);
803  type = artdaq::Fragment::ContainerFragmentType;
804  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
805  auto cf6 = artdaq::ContainerFragment(*fps.front());
806  BOOST_REQUIRE_EQUAL(cf6.block_count(), 1);
807  BOOST_REQUIRE_EQUAL(cf6.missing_data(), false);
808  type = artdaq::Fragment::FirstUserFragmentType;
809  BOOST_REQUIRE_EQUAL(cf6.fragment_type(), type);
810  fps.clear();
811  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 8);
812 
813  list = gen.GetSentWindowList(1);
814  BOOST_REQUIRE_EQUAL(list.size(), 0);
815 
816  usleep(1500000);
817 
818  gen.StopCmd(0xFFFFFFFF, 1);
819  TLOG(TLVL_INFO) << "WindowMode_Function test case END";
820  gen.joinThreads();
821 }
822 
823 // 1. Both start and end before any data in buffer "RequestBeforeBuffer"
824 // 2. Start before buffer, end in buffer "RequestStartsBeforeBuffer"
825 // 3. Start befoer buffer, end after buffer "RequestOutsideBuffer"
826 // 4. Start and end in buffer "RequestInBuffer"
827 // 5. Start in buffer, end after buffer "RequestEndsAfterBuffer"
828 // 6. Start and end after buffer "RequestAfterBuffer"
829 BOOST_AUTO_TEST_CASE(WindowMode_RequestBeforeBuffer)
830 {
831  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
832  TLOG(TLVL_INFO) << "WindowMode_RequestBeforeBuffer test case BEGIN";
833  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
834  const int DELAY_TIME = 100;
835  fhicl::ParameterSet ps;
836  ps.put<int>("board_id", 1);
837  ps.put<int>("fragment_id", 1);
838  ps.put<int>("request_port", REQUEST_PORT);
839 #if MULTICAST_MODE
840  ps.put<std::string>("request_address", "227.18.12.32");
841 #else
842  ps.put<std::string>("request_address", "localhost");
843 #endif
844  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
845  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
846  ps.put<bool>("separate_data_thread", true);
847  ps.put<bool>("separate_monitoring_thread", false);
848  ps.put<bool>("circular_buffer_mode", true);
849  ps.put<int64_t>("hardware_poll_interval_us", 0);
850  ps.put<size_t>("data_buffer_depth_fragments", 5);
851  ps.put<std::string>("request_mode", "window");
852  ps.put("request_delay_ms", DELAY_TIME);
853  ps.put("send_requests", true);
854 
855  artdaq::RequestSender t(ps);
856  t.SetRunNumber(1);
857 
859  gen.StartCmd(1, 0xFFFFFFFF, 1);
860  gen.waitForFrags();
861 
862  artdaq::FragmentPtrs fps;
863  int sts;
864  artdaq::Fragment::type_t type;
865 
866  // 1. Both start and end before any data in buffer
867  // -- Should return ContainerFragment with MissingData bit set and zero Fragments
868  gen.setFireCount(9); // Buffer start is at ts 6, end at 10
869  gen.waitForFrags();
870  t.AddRequest(1, 1); // Requesting data from ts 1 to 3
871 
872  sts = gen.getNext(fps);
873  BOOST_REQUIRE_EQUAL(sts, true);
874  BOOST_REQUIRE_EQUAL(fps.size(), 1);
875  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
876  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
877  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
878  type = artdaq::Fragment::ContainerFragmentType;
879  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
880  auto cf4 = artdaq::ContainerFragment(*fps.front());
881  BOOST_REQUIRE_EQUAL(cf4.block_count(), 0);
882  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
883  type = artdaq::Fragment::EmptyFragmentType;
884  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
885 
886  gen.StopCmd(0xFFFFFFFF, 1);
887  TLOG(TLVL_INFO) << "WindowMode_RequestBeforeBuffer test case END";
888 }
890 {
891  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
892  TLOG(TLVL_INFO) << "WindowMode_RequestStartsBeforeBuffer test case BEGIN";
893  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
894  const int DELAY_TIME = 100;
895  fhicl::ParameterSet ps;
896  ps.put<int>("board_id", 1);
897  ps.put<int>("fragment_id", 1);
898  ps.put<int>("request_port", REQUEST_PORT);
899 #if MULTICAST_MODE
900  ps.put<std::string>("request_address", "227.18.12.32");
901 #else
902  ps.put<std::string>("request_address", "localhost");
903 #endif
904  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
905  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
906  ps.put<bool>("separate_data_thread", true);
907  ps.put<bool>("separate_monitoring_thread", false);
908  ps.put<int64_t>("hardware_poll_interval_us", 0);
909  ps.put<size_t>("data_buffer_depth_fragments", 5);
910  ps.put<bool>("circular_buffer_mode", true);
911  ps.put<std::string>("request_mode", "window");
912  ps.put("request_delay_ms", DELAY_TIME);
913  ps.put("send_requests", true);
914 
915  artdaq::RequestSender t(ps);
916  t.SetRunNumber(1);
917 
919  gen.StartCmd(1, 0xFFFFFFFF, 1);
920  gen.waitForFrags();
921 
922  artdaq::FragmentPtrs fps;
923  int sts;
924  artdaq::Fragment::type_t type;
925 
926  gen.waitForFrags();
927  gen.setFireCount(9); // Buffer contains 6 to 10
928  gen.waitForFrags();
929 
930  // 2. Start before buffer, end in buffer
931  // -- Should return ContainerFragment with MissingData bit set and one or more Fragments
932  t.AddRequest(1, 4); // Requesting data from ts 4 to 6
933 
934  sts = gen.getNext(fps);
935  BOOST_REQUIRE_EQUAL(sts, true);
936  BOOST_REQUIRE_EQUAL(fps.size(), 1);
937  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
938  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
939  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
940  type = artdaq::Fragment::ContainerFragmentType;
941  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
942  auto cf4 = artdaq::ContainerFragment(*fps.front());
943  BOOST_REQUIRE_EQUAL(cf4.block_count(), 1);
944  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
945  type = artdaq::Fragment::FirstUserFragmentType;
946  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
947 
948  gen.StopCmd(0xFFFFFFFF, 1);
949  gen.joinThreads();
950  TLOG(TLVL_INFO) << "WindowMode_RequestStartsBeforeBuffer test case END";
951 }
952 BOOST_AUTO_TEST_CASE(WindowMode_RequestOutsideBuffer)
953 {
954  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
955  TLOG(TLVL_INFO) << "WindowMode_RequestOutsideBuffer test case BEGIN";
956  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
957  const int DELAY_TIME = 100;
958  fhicl::ParameterSet ps;
959  ps.put<int>("board_id", 1);
960  ps.put<int>("fragment_id", 1);
961  ps.put<int>("request_port", REQUEST_PORT);
962 #if MULTICAST_MODE
963  ps.put<std::string>("request_address", "227.18.12.32");
964 #else
965  ps.put<std::string>("request_address", "localhost");
966 #endif
967  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
968  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 4);
969  ps.put<size_t>("window_close_timeout_us", 500000);
970  ps.put<bool>("separate_data_thread", true);
971  ps.put<bool>("separate_monitoring_thread", false);
972  ps.put<int64_t>("hardware_poll_interval_us", 0);
973  ps.put<bool>("circular_buffer_mode", true);
974  ps.put<size_t>("data_buffer_depth_fragments", 5);
975  ps.put<std::string>("request_mode", "window");
976  ps.put("request_delay_ms", DELAY_TIME);
977  ps.put("send_requests", true);
978 
979  artdaq::RequestSender t(ps);
980  t.SetRunNumber(1);
981 
983  gen.StartCmd(1, 0xFFFFFFFF, 1);
984  gen.waitForFrags();
985 
986  artdaq::FragmentPtrs fps;
987  int sts;
988  artdaq::Fragment::type_t type;
989 
990  gen.waitForFrags();
991  gen.setFireCount(9); // Buffer contains 6 to 10
992  gen.waitForFrags();
993 
994  // 3. Start before buffer, end after buffer
995  // -- Should not return until buffer passes end or timeout (check both cases), MissingData bit set
996 
997  t.AddRequest(1, 6); // Requesting data from ts 6 to 9, buffer will contain 10
998  sts = gen.getNext(fps);
999  BOOST_REQUIRE_EQUAL(sts, true);
1000  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1001  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1002  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 6);
1003  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1004  type = artdaq::Fragment::ContainerFragmentType;
1005  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1006  auto cf = artdaq::ContainerFragment(*fps.front());
1007  BOOST_REQUIRE_EQUAL(cf.block_count(), 4);
1008  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1009  type = artdaq::Fragment::FirstUserFragmentType;
1010  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1011  fps.clear();
1012 
1013  t.AddRequest(2, 9); // Requesting data from ts 9 to 12
1014  sts = gen.getNext(fps);
1015  BOOST_REQUIRE_EQUAL(sts, true);
1016  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1017 
1018  gen.setFireCount(3); // Buffer start is at ts 10, end at 13
1019  gen.waitForFrags();
1020 
1021  sts = gen.getNext(fps);
1022  BOOST_REQUIRE_EQUAL(sts, true);
1023  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1024  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1025  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 9);
1026  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1027  type = artdaq::Fragment::ContainerFragmentType;
1028  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1029  auto cf2 = artdaq::ContainerFragment(*fps.front());
1030  BOOST_REQUIRE_EQUAL(cf2.block_count(), 3);
1031  BOOST_REQUIRE_EQUAL(cf2.missing_data(), true);
1032  type = artdaq::Fragment::FirstUserFragmentType;
1033  BOOST_REQUIRE_EQUAL(cf2.fragment_type(), type);
1034  fps.clear();
1035 
1036  t.AddRequest(3, 12); // Requesting data from ts 11 to 14
1037 
1038  sts = gen.getNext(fps);
1039  BOOST_REQUIRE_EQUAL(sts, true);
1040  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1041 
1042  usleep(550000);
1043 
1044  sts = gen.getNext(fps);
1045  BOOST_REQUIRE_EQUAL(sts, true);
1046  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1047  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1048  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
1049  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1050  type = artdaq::Fragment::ContainerFragmentType;
1051  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1052  auto cf4 = artdaq::ContainerFragment(*fps.front());
1053  BOOST_REQUIRE_EQUAL(cf4.block_count(), 1);
1054  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
1055  type = artdaq::Fragment::FirstUserFragmentType;
1056  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
1057 
1058  gen.StopCmd(0xFFFFFFFF, 1);
1059  gen.joinThreads();
1060  TLOG(TLVL_INFO) << "WindowMode_RequestOutsideBuffer test case END";
1061 }
1062 BOOST_AUTO_TEST_CASE(WindowMode_RequestInBuffer)
1063 {
1064  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1065  TLOG(TLVL_INFO) << "WindowMode_RequestInBuffer test case BEGIN";
1066  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1067  const int DELAY_TIME = 100;
1068  fhicl::ParameterSet ps;
1069  ps.put<int>("board_id", 1);
1070  ps.put<int>("fragment_id", 1);
1071  ps.put<int>("request_port", REQUEST_PORT);
1072 #if MULTICAST_MODE
1073  ps.put<std::string>("request_address", "227.18.12.32");
1074 #else
1075  ps.put<std::string>("request_address", "localhost");
1076 #endif
1077  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1078  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
1079  ps.put<bool>("separate_data_thread", true);
1080  ps.put<bool>("separate_monitoring_thread", false);
1081  ps.put<int64_t>("hardware_poll_interval_us", 0);
1082  ps.put<bool>("circular_buffer_mode", true);
1083  ps.put<size_t>("data_buffer_depth_fragments", 5);
1084  ps.put<std::string>("request_mode", "window");
1085  ps.put("request_delay_ms", DELAY_TIME);
1086  ps.put("send_requests", true);
1087 
1088  artdaq::RequestSender t(ps);
1089  t.SetRunNumber(1);
1090 
1092  gen.StartCmd(1, 0xFFFFFFFF, 1);
1093 
1094  artdaq::FragmentPtrs fps;
1095  int sts;
1096  artdaq::Fragment::type_t type;
1097  gen.waitForFrags();
1098 
1099  // 4. Start and end in buffer
1100  // -- Should return ContainerFragment with one or more Fragments
1101  gen.setFireCount(5); // Buffer start is at ts 2, end at 6
1102  gen.waitForFrags();
1103  t.AddRequest(1, 3); // Requesting data from ts 3 to 5
1104 
1105  sts = gen.getNext(fps);
1106  BOOST_REQUIRE_EQUAL(sts, true);
1107  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1108  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1109  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
1110  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1111  type = artdaq::Fragment::ContainerFragmentType;
1112  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1113  auto cf4 = artdaq::ContainerFragment(*fps.front());
1114  BOOST_REQUIRE_EQUAL(cf4.block_count(), 3);
1115  BOOST_REQUIRE_EQUAL(cf4.missing_data(), false);
1116  type = artdaq::Fragment::FirstUserFragmentType;
1117  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
1118 
1119  gen.StopCmd(0xFFFFFFFF, 1);
1120  TLOG(TLVL_INFO) << "WindowMode_RequestInBuffer test case END";
1121 }
1123 {
1124  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1125  TLOG(TLVL_INFO) << "WindowMode_RequestEndsAfterBuffer test case BEGIN";
1126  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1127  const int DELAY_TIME = 100;
1128  fhicl::ParameterSet ps;
1129  ps.put<int>("board_id", 1);
1130  ps.put<int>("fragment_id", 1);
1131  ps.put<int>("request_port", REQUEST_PORT);
1132 #if MULTICAST_MODE
1133  ps.put<std::string>("request_address", "227.18.12.32");
1134 #else
1135  ps.put<std::string>("request_address", "localhost");
1136 #endif
1137  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1138  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
1139  ps.put<size_t>("window_close_timeout_us", 500000);
1140  ps.put<bool>("separate_data_thread", true);
1141  ps.put<bool>("separate_monitoring_thread", false);
1142  ps.put<int64_t>("hardware_poll_interval_us", 0);
1143  ps.put<bool>("circular_buffer_mode", true);
1144  ps.put<size_t>("data_buffer_depth_fragments", 5);
1145  ps.put<std::string>("request_mode", "window");
1146  ps.put("request_delay_ms", DELAY_TIME);
1147  ps.put("send_requests", true);
1148 
1149  artdaq::RequestSender t(ps);
1150  t.SetRunNumber(1);
1151 
1153  gen.StartCmd(1, 0xFFFFFFFF, 1);
1154 
1155  artdaq::FragmentPtrs fps;
1156  int sts;
1157  artdaq::Fragment::type_t type;
1158  gen.waitForFrags();
1159  gen.setFireCount(5); // Buffer contains 2 to 6
1160  gen.waitForFrags();
1161 
1162  // 5. Start in buffer, end after buffer
1163  // -- Should not return until buffer passes end or timeout (check both cases). MissingData bit set if timeout
1164  t.AddRequest(1, 5); // Requesting data from ts 5 to 7
1165  sts = gen.getNext(fps);
1166  BOOST_REQUIRE_EQUAL(sts, true);
1167  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1168 
1169  gen.setFireCount(2); // Buffer contains 4 to 8
1170  gen.waitForFrags();
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(), 5);
1176  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1177  type = artdaq::Fragment::ContainerFragmentType;
1178  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1179  auto cf = artdaq::ContainerFragment(*fps.front());
1180  BOOST_REQUIRE_EQUAL(cf.block_count(), 3);
1181  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1182  type = artdaq::Fragment::FirstUserFragmentType;
1183  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1184  fps.clear();
1185 
1186  t.AddRequest(2, 8); // Requesting data from ts 8 to 10
1187 
1188  sts = gen.getNext(fps);
1189  BOOST_REQUIRE_EQUAL(sts, true);
1190  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1191 
1192  usleep(550000);
1193 
1194  sts = gen.getNext(fps);
1195  BOOST_REQUIRE_EQUAL(sts, true);
1196  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1197  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1198  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 8);
1199  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1200  type = artdaq::Fragment::ContainerFragmentType;
1201  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1202  auto cf4 = artdaq::ContainerFragment(*fps.front());
1203  BOOST_REQUIRE_EQUAL(cf4.block_count(), 1);
1204  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
1205  type = artdaq::Fragment::FirstUserFragmentType;
1206  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
1207 
1208  gen.StopCmd(0xFFFFFFFF, 1);
1209  gen.joinThreads();
1210  TLOG(TLVL_INFO) << "WindowMode_RequestEndsAfterBuffer test case END";
1211 }
1212 BOOST_AUTO_TEST_CASE(WindowMode_RequestAfterBuffer)
1213 {
1214  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1215  TLOG(TLVL_INFO) << "WindowMode_RequestAfterBuffer test case BEGIN";
1216  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1217  const int DELAY_TIME = 100;
1218  fhicl::ParameterSet ps;
1219  ps.put<int>("board_id", 1);
1220  ps.put<int>("fragment_id", 1);
1221  ps.put<int>("request_port", REQUEST_PORT);
1222 #if MULTICAST_MODE
1223  ps.put<std::string>("request_address", "227.18.12.32");
1224 #else
1225  ps.put<std::string>("request_address", "localhost");
1226 #endif
1227  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1228  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
1229  ps.put<size_t>("window_close_timeout_us", 500000);
1230  ps.put<bool>("separate_data_thread", true);
1231  ps.put<bool>("separate_monitoring_thread", false);
1232  ps.put<int64_t>("hardware_poll_interval_us", 0);
1233  ps.put<bool>("circular_buffer_mode", true);
1234  ps.put<size_t>("data_buffer_depth_fragments", 5);
1235  ps.put<std::string>("request_mode", "window");
1236  ps.put("request_delay_ms", DELAY_TIME);
1237  ps.put("send_requests", true);
1238 
1239  artdaq::RequestSender t(ps);
1240  t.SetRunNumber(1);
1241 
1243  gen.StartCmd(1, 0xFFFFFFFF, 1);
1244 
1245  artdaq::FragmentPtrs fps;
1246  int sts;
1247  artdaq::Fragment::type_t type;
1248  gen.waitForFrags();
1249 
1250  // 6. Start and end after buffer
1251  // -- Should not return until buffer passes end or timeout (check both cases). MissingData bit set if timeout
1252  gen.setFireCount(9); // Buffer start is 6, end at 10
1253  gen.waitForFrags();
1254  t.AddRequest(1, 11); // Requesting data from ts 11 to 13
1255 
1256  sts = gen.getNext(fps);
1257  BOOST_REQUIRE_EQUAL(sts, true);
1258  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1259  gen.setFireCount(1); // Buffer start is 7, end at 11
1260  gen.waitForFrags();
1261  sts = gen.getNext(fps);
1262  BOOST_REQUIRE_EQUAL(sts, true);
1263  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1264 
1265  gen.setFireCount(3); // Buffer start is 10, end at 14
1266  gen.waitForFrags();
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(), 11);
1272  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1273  type = artdaq::Fragment::ContainerFragmentType;
1274  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1275  auto cf = artdaq::ContainerFragment(*fps.front());
1276  BOOST_REQUIRE_EQUAL(cf.block_count(), 3);
1277  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1278  type = artdaq::Fragment::FirstUserFragmentType;
1279  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1280  fps.clear();
1281 
1282  t.AddRequest(2, 16); // Requesting data from ts 15 to 17
1283  sts = gen.getNext(fps);
1284  BOOST_REQUIRE_EQUAL(sts, true);
1285  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1286 
1287  usleep(550000);
1288 
1289  sts = gen.getNext(fps);
1290  BOOST_REQUIRE_EQUAL(sts, true);
1291  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1292  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1293  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 16);
1294  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1295  type = artdaq::Fragment::ContainerFragmentType;
1296  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1297  auto cf4 = artdaq::ContainerFragment(*fps.front());
1298  BOOST_REQUIRE_EQUAL(cf4.block_count(), 0);
1299  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
1300  type = artdaq::Fragment::EmptyFragmentType;
1301  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
1302 
1303  gen.StopCmd(0xFFFFFFFF, 1);
1304  gen.joinThreads();
1305  TLOG(TLVL_INFO) << "WindowMode_RequestAfterBuffer test case END";
1306 }
1307 
1308 BOOST_AUTO_TEST_CASE(HardwareFailure_NonThreaded)
1309 {
1310  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1311  TLOG(TLVL_INFO) << "HardwareFailure_NonThreaded test case BEGIN";
1312  fhicl::ParameterSet ps;
1313  ps.put<int>("board_id", 1);
1314  ps.put<int>("fragment_id", 1);
1315  ps.put<bool>("separate_data_thread", false);
1316  ps.put<bool>("separate_monitoring_thread", false);
1317  ps.put<int64_t>("hardware_poll_interval_us", 10);
1318 
1320  gen.StartCmd(1, 0xFFFFFFFF, 1);
1321 
1322  artdaq::FragmentPtrs fps;
1323  auto sts = gen.getNext(fps);
1324  BOOST_REQUIRE_EQUAL(sts, true);
1325  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
1326  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1327  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1328  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1329  fps.clear();
1330 
1331  gen.setFireCount(1);
1332  gen.setHwFail();
1333  usleep(10000);
1334  sts = gen.getNext(fps);
1335  BOOST_REQUIRE_EQUAL(sts, false);
1336  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1337 
1338  gen.StopCmd(0xFFFFFFFF, 1);
1339  gen.joinThreads();
1340  TLOG(TLVL_INFO) << "HardwareFailure_NonThreaded test case END";
1341 }
1342 
1343 BOOST_AUTO_TEST_CASE(HardwareFailure_Threaded)
1344 {
1345  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1346  TLOG(TLVL_INFO) << "HardwareFailure_Threaded test case BEGIN";
1347  fhicl::ParameterSet ps;
1348  ps.put<int>("board_id", 1);
1349  ps.put<int>("fragment_id", 1);
1350  ps.put<bool>("separate_data_thread", true);
1351  ps.put<bool>("separate_monitoring_thread", true);
1352  ps.put<int64_t>("hardware_poll_interval_us", 750000);
1353 
1355  gen.StartCmd(1, 0xFFFFFFFF, 1);
1356  gen.waitForFrags();
1357 
1358  artdaq::FragmentPtrs fps;
1359  auto sts = gen.getNext(fps);
1360  BOOST_REQUIRE_EQUAL(sts, true);
1361  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
1362  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1363  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1364  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1365  fps.clear();
1366 
1367  gen.setHwFail();
1368  //gen.setFireCount(1);
1369  //sts = gen.getNext(fps);
1370  //BOOST_REQUIRE_EQUAL(sts, true);
1371  //BOOST_REQUIRE_EQUAL(fps.size(), 1);
1372  //BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1373  //BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
1374  //BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1375  //fps.clear();
1376 
1377  sleep(1);
1378 
1379  gen.setFireCount(1);
1380  sts = gen.getNext(fps);
1381  BOOST_REQUIRE_EQUAL(sts, false);
1382  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1383 
1384  gen.StopCmd(0xFFFFFFFF, 1);
1385  gen.joinThreads();
1386  TLOG(TLVL_INFO) << "HardwareFailure_Threaded test case END";
1387 }
1388 
1389 BOOST_AUTO_TEST_CASE(IgnoreRequests_MultipleIDs)
1390 {
1391  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1392  TLOG(TLVL_INFO) << "IgnoreRequests_MultipleIDs test case BEGIN";
1393  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1394  const int DELAY_TIME = 1;
1395  fhicl::ParameterSet ps;
1396  ps.put<int>("board_id", 1);
1397  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1398  ps.put<int>("request_port", REQUEST_PORT);
1399 #if MULTICAST_MODE
1400  ps.put<std::string>("request_address", "227.18.12.29");
1401 #else
1402  ps.put<std::string>("request_address", "localhost");
1403 #endif
1404  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1405  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1406  ps.put<bool>("separate_data_thread", true);
1407  ps.put<bool>("separate_monitoring_thread", false);
1408  ps.put<int64_t>("hardware_poll_interval_us", 0);
1409  ps.put<std::string>("request_mode", "ignored");
1410  ps.put("request_delay_ms", DELAY_TIME);
1411  ps.put("send_requests", true);
1412 
1413  artdaq::RequestSender t(ps);
1415  gen.StartCmd(1, 0xFFFFFFFF, 1);
1416  gen.waitForFrags();
1417  t.AddRequest(53, 35);
1418 
1419  artdaq::FragmentPtrs fps;
1420  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1421  auto sts = gen.getNext(fps);
1422  BOOST_REQUIRE_EQUAL(sts, true);
1423  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
1424  while (fps.size() > 0)
1425  {
1426  ids[fps.front()->fragmentID()]++;
1427  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1428  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1429  fps.pop_front();
1430  }
1431 
1432  BOOST_REQUIRE_EQUAL(ids[1], 1);
1433  BOOST_REQUIRE_EQUAL(ids[2], 1);
1434  BOOST_REQUIRE_EQUAL(ids[3], 1);
1435  ids.clear();
1436 
1437  fps.clear();
1438  gen.setEnabledIds(0x6); // Fragment id 3 disabled
1439  gen.setFireCount(1);
1440  gen.waitForFrags();
1441  sts = gen.getNext(fps);
1442 
1443  BOOST_REQUIRE_EQUAL(sts, true);
1444  BOOST_REQUIRE_EQUAL(fps.size(), 2u);
1445  while (fps.size() > 0)
1446  {
1447  ids[fps.front()->fragmentID()]++;
1448  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
1449  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1450  fps.pop_front();
1451  }
1452  BOOST_REQUIRE_EQUAL(ids[1], 1);
1453  BOOST_REQUIRE_EQUAL(ids[2], 1);
1454 
1455  gen.StopCmd(0xFFFFFFFF, 1);
1456  gen.joinThreads();
1457  TLOG(TLVL_INFO) << "IgnoreRequests_MultipleIDs test case END";
1458 }
1459 
1460 BOOST_AUTO_TEST_CASE(SingleMode_MultipleIDs)
1461 {
1462  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1463  TLOG(TLVL_INFO) << "SingleMode_MultipleIDs test case BEGIN";
1464  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1465  const int DELAY_TIME = 100;
1466  fhicl::ParameterSet ps;
1467  ps.put<int>("board_id", 1);
1468  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1469  ps.put<int>("request_port", REQUEST_PORT);
1470 #if MULTICAST_MODE
1471  ps.put<std::string>("request_address", "227.18.12.30");
1472 #else
1473  ps.put<std::string>("request_address", "localhost");
1474 #endif
1475  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1476  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1477  ps.put<bool>("separate_data_thread", true);
1478  ps.put<bool>("separate_monitoring_thread", false);
1479  ps.put<int64_t>("hardware_poll_interval_us", 0);
1480  ps.put<std::string>("request_mode", "single");
1481  ps.put("request_delay_ms", DELAY_TIME);
1482  ps.put("send_requests", true);
1483 
1484  artdaq::RequestSender t(ps);
1485  t.SetRunNumber(1);
1486  t.AddRequest(1, 1);
1487 
1489  gen.StartCmd(1, 0xFFFFFFFF, 1);
1490  gen.waitForFrags();
1491  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
1492 
1493  artdaq::FragmentPtrs fps;
1494  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1495  auto sts = gen.getNext(fps);
1496  auto type = artdaq::Fragment::FirstUserFragmentType;
1497  BOOST_REQUIRE_EQUAL(sts, true);
1498  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
1499  while (fps.size() > 0)
1500  {
1501  ids[fps.front()->fragmentID()]++;
1502  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1503  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1504  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1505  fps.pop_front();
1506  }
1507  BOOST_REQUIRE_EQUAL(ids[1], 1);
1508  BOOST_REQUIRE_EQUAL(ids[2], 1);
1509  BOOST_REQUIRE_EQUAL(ids[3], 1);
1510  ids.clear();
1511 
1512  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
1513  fps.clear();
1514 
1515  t.AddRequest(2, 5);
1516  sts = gen.getNext(fps);
1517  BOOST_REQUIRE_EQUAL(sts, true);
1518  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
1519  while (fps.size() > 0)
1520  {
1521  ids[fps.front()->fragmentID()]++;
1522  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
1523  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1524  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1525  fps.pop_front();
1526  }
1527  BOOST_REQUIRE_EQUAL(ids[1], 1);
1528  BOOST_REQUIRE_EQUAL(ids[2], 1);
1529  BOOST_REQUIRE_EQUAL(ids[3], 1);
1530  ids.clear();
1531 
1532  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
1533  fps.clear();
1534 
1535  gen.setFireCount(2);
1536  gen.waitForFrags();
1537  t.AddRequest(4, 7);
1538  sts = gen.getNext(fps);
1539  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 5);
1540  BOOST_REQUIRE_EQUAL(sts, true);
1541  BOOST_REQUIRE_EQUAL(fps.size(), 6);
1542  auto ts = artdaq::Fragment::InvalidTimestamp;
1543  auto emptyType = artdaq::Fragment::EmptyFragmentType;
1544  for (auto ii = 0; ii < 3; ++ii)
1545  {
1546  ids[fps.front()->fragmentID()]++;
1547  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
1548  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1549  BOOST_REQUIRE_EQUAL(fps.front()->type(), emptyType);
1550  fps.pop_front();
1551  }
1552  BOOST_REQUIRE_EQUAL(ids[1], 1);
1553  BOOST_REQUIRE_EQUAL(ids[2], 1);
1554  BOOST_REQUIRE_EQUAL(ids[3], 1);
1555  ids.clear();
1556  for (auto ii = 0; ii < 3; ++ii)
1557  {
1558  ids[fps.front()->fragmentID()]++;
1559  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
1560  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1561  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1562  fps.pop_front();
1563  }
1564  BOOST_REQUIRE_EQUAL(ids[1], 1);
1565  BOOST_REQUIRE_EQUAL(ids[2], 1);
1566  BOOST_REQUIRE_EQUAL(ids[3], 1);
1567  ids.clear();
1568  fps.clear();
1569 
1570  // Single mode should generate 3 Fragments, 2 new ones and one old one
1571  gen.setEnabledIds(0x6); // Fragment ID 3 disabled
1572  gen.setFireCount(1);
1573  gen.waitForFrags();
1574  t.AddRequest(5, 9);
1575  sts = gen.getNext(fps);
1576  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
1577  BOOST_REQUIRE_EQUAL(sts, true);
1578  BOOST_REQUIRE_EQUAL(fps.size(), 3);
1579  for (auto ii = 0; ii < 3; ++ii)
1580  {
1581  ids[fps.front()->fragmentID()]++;
1582  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 9);
1583  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
1584  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1585  fps.pop_front();
1586  }
1587  BOOST_REQUIRE_EQUAL(ids[1], 1);
1588  BOOST_REQUIRE_EQUAL(ids[2], 1);
1589  BOOST_REQUIRE_EQUAL(ids[3], 1);
1590  ids.clear();
1591  fps.clear();
1592 
1593  gen.StopCmd(0xFFFFFFFF, 1);
1594  gen.joinThreads();
1595  TLOG(TLVL_INFO) << "SingleMode_MultipleIDs test case END";
1596 }
1597 
1598 BOOST_AUTO_TEST_CASE(BufferMode_MultipleIDs)
1599 {
1600  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1601  TLOG(TLVL_INFO) << "BufferMode_MultipleIDs test case BEGIN";
1602  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1603  const int DELAY_TIME = 100;
1604  fhicl::ParameterSet ps;
1605  ps.put<int>("board_id", 1);
1606  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1607  ps.put<int>("request_port", REQUEST_PORT);
1608 #if MULTICAST_MODE
1609  ps.put<std::string>("request_address", "227.18.12.31");
1610 #else
1611  ps.put<std::string>("request_address", "localhost");
1612 #endif
1613  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1614  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1615  ps.put<bool>("separate_data_thread", true);
1616  ps.put<bool>("separate_monitoring_thread", false);
1617  ps.put<int64_t>("hardware_poll_interval_us", 0);
1618  ps.put<std::string>("request_mode", "buffer");
1619  ps.put("request_delay_ms", DELAY_TIME);
1620  ps.put("send_requests", true);
1621 
1622  artdaq::RequestSender t(ps);
1623  t.SetRunNumber(1);
1624  t.AddRequest(1, 1);
1625 
1627  gen.StartCmd(1, 0xFFFFFFFF, 1);
1628  gen.waitForFrags();
1629  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
1630 
1631  artdaq::FragmentPtrs fps;
1632  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1633  auto sts = gen.getNext(fps);
1634  BOOST_REQUIRE_EQUAL(sts, true);
1635  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
1636  auto type = artdaq::Fragment::ContainerFragmentType;
1637  while (fps.size() > 0)
1638  {
1639  ids[fps.front()->fragmentID()]++;
1640  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1641  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1642  type = artdaq::Fragment::ContainerFragmentType;
1643  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1644  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
1645  auto cf = artdaq::ContainerFragment(*fps.front());
1646  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
1647  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1648  type = artdaq::Fragment::FirstUserFragmentType;
1649  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1650  fps.pop_front();
1651  }
1652  BOOST_REQUIRE_EQUAL(ids[1], 1);
1653  BOOST_REQUIRE_EQUAL(ids[2], 1);
1654  BOOST_REQUIRE_EQUAL(ids[3], 1);
1655  ids.clear();
1656  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
1657  fps.clear();
1658 
1659  t.AddRequest(2, 5);
1660  sts = gen.getNext(fps);
1661  BOOST_REQUIRE_EQUAL(sts, true);
1662  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
1663  while (fps.size() > 0)
1664  {
1665  ids[fps.front()->fragmentID()]++;
1666  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
1667  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1668  type = artdaq::Fragment::ContainerFragmentType;
1669  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1670  auto cf = artdaq::ContainerFragment(*fps.front());
1671  BOOST_REQUIRE_EQUAL(cf.block_count(), 0);
1672  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1673  type = artdaq::Fragment::EmptyFragmentType;
1674  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1675  fps.pop_front();
1676  }
1677  BOOST_REQUIRE_EQUAL(ids[1], 1);
1678  BOOST_REQUIRE_EQUAL(ids[2], 1);
1679  BOOST_REQUIRE_EQUAL(ids[3], 1);
1680  ids.clear();
1681  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
1682  fps.clear();
1683 
1684  gen.setFireCount(2);
1685  gen.waitForFrags();
1686  t.AddRequest(4, 7);
1687  sts = gen.getNext(fps);
1688  BOOST_REQUIRE_EQUAL(sts, true);
1689  BOOST_REQUIRE_EQUAL(fps.size(), 6);
1690 
1691  auto ts = artdaq::Fragment::InvalidTimestamp;
1692  auto emptyType = artdaq::Fragment::EmptyFragmentType;
1693  for (auto ii = 0; ii < 3; ++ii)
1694  {
1695  ids[fps.front()->fragmentID()]++;
1696  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
1697  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1698  BOOST_REQUIRE_EQUAL(fps.front()->type(), emptyType);
1699  BOOST_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
1700  fps.pop_front();
1701  }
1702  BOOST_REQUIRE_EQUAL(ids[1], 1);
1703  BOOST_REQUIRE_EQUAL(ids[2], 1);
1704  BOOST_REQUIRE_EQUAL(ids[3], 1);
1705  ids.clear();
1706  for (auto ii = 0; ii < 3; ++ii)
1707  {
1708  ids[fps.front()->fragmentID()]++;
1709  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
1710  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1711  type = artdaq::Fragment::ContainerFragmentType;
1712  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1713  auto cf3 = artdaq::ContainerFragment(*fps.front());
1714  BOOST_REQUIRE_EQUAL(cf3.block_count(), 2);
1715  BOOST_REQUIRE_EQUAL(cf3.missing_data(), false);
1716  type = artdaq::Fragment::FirstUserFragmentType;
1717  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
1718  fps.pop_front();
1719  }
1720  BOOST_REQUIRE_EQUAL(ids[1], 1);
1721  BOOST_REQUIRE_EQUAL(ids[2], 1);
1722  BOOST_REQUIRE_EQUAL(ids[3], 1);
1723  ids.clear();
1724 
1725  fps.clear();
1726  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 5);
1727 
1728  gen.setEnabledIds(0x6); // Fragment id 3 disabled
1729  gen.setFireCount(2);
1730  gen.waitForFrags();
1731  t.AddRequest(5, 8);
1732  sts = gen.getNext(fps);
1733  BOOST_REQUIRE_EQUAL(sts, true);
1734  BOOST_REQUIRE_EQUAL(fps.size(), 3);
1735 
1736  for (auto ii = 0; ii < 3; ++ii)
1737  {
1738  ids[fps.front()->fragmentID()]++;
1739  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 8);
1740  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
1741  type = artdaq::Fragment::ContainerFragmentType;
1742  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1743  auto cf3 = artdaq::ContainerFragment(*fps.front());
1744  if (fps.front()->fragmentID() != 3)
1745  {
1746  BOOST_REQUIRE_EQUAL(cf3.block_count(), 2);
1747  BOOST_REQUIRE_EQUAL(cf3.missing_data(), false);
1748  type = artdaq::Fragment::FirstUserFragmentType;
1749  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
1750  }
1751  else
1752  {
1753  BOOST_REQUIRE_EQUAL(cf3.block_count(), 0);
1754  BOOST_REQUIRE_EQUAL(cf3.missing_data(), false);
1755  type = artdaq::Fragment::EmptyFragmentType;
1756  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
1757  }
1758  fps.pop_front();
1759  }
1760  BOOST_REQUIRE_EQUAL(ids[1], 1);
1761  BOOST_REQUIRE_EQUAL(ids[2], 1);
1762  BOOST_REQUIRE_EQUAL(ids[3], 1);
1763  ids.clear();
1764 
1765  fps.clear();
1766  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
1767 
1768  gen.StopCmd(0xFFFFFFFF, 1);
1769  gen.joinThreads();
1770 
1771  TLOG(TLVL_INFO) << "BufferMode_MultipleIDs test case END";
1772 }
1773 
1774 BOOST_AUTO_TEST_CASE(CircularBufferMode_MultipleIDs)
1775 {
1776  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1777  TLOG(TLVL_INFO) << "CircularBufferMode_MultipleIDs test case BEGIN";
1778  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1779  const int DELAY_TIME = 100;
1780  fhicl::ParameterSet ps;
1781  ps.put<int>("board_id", 1);
1782  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1783  ps.put<int>("request_port", REQUEST_PORT);
1784 #if MULTICAST_MODE
1785  ps.put<std::string>("request_address", "227.18.12.31");
1786 #else
1787  ps.put<std::string>("request_address", "localhost");
1788 #endif
1789  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
1790  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
1791  ps.put<bool>("separate_data_thread", true);
1792  ps.put<bool>("circular_buffer_mode", true);
1793  ps.put<int>("data_buffer_depth_fragments", 3);
1794  ps.put<bool>("separate_monitoring_thread", false);
1795  ps.put<int64_t>("hardware_poll_interval_us", 0);
1796  ps.put<std::string>("request_mode", "buffer");
1797  ps.put("request_delay_ms", DELAY_TIME);
1798  ps.put("send_requests", true);
1799 
1800  artdaq::RequestSender t(ps);
1801  t.SetRunNumber(1);
1802  t.AddRequest(1, 1);
1803 
1805  gen.StartCmd(1, 0xFFFFFFFF, 1);
1806  gen.waitForFrags();
1807  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
1808 
1809  artdaq::FragmentPtrs fps;
1810  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
1811  auto sts = gen.getNext(fps);
1812  auto type = artdaq::Fragment::ContainerFragmentType;
1813  BOOST_REQUIRE_EQUAL(sts, true);
1814  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
1815  while (fps.size() > 0)
1816  {
1817  ids[fps.front()->fragmentID()]++;
1818  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1819  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1820  type = artdaq::Fragment::ContainerFragmentType;
1821  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1822  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
1823  auto cf = artdaq::ContainerFragment(*fps.front());
1824  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
1825  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1826  type = artdaq::Fragment::FirstUserFragmentType;
1827  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1828  fps.pop_front();
1829  }
1830  BOOST_REQUIRE_EQUAL(ids[1], 1);
1831  BOOST_REQUIRE_EQUAL(ids[2], 1);
1832  BOOST_REQUIRE_EQUAL(ids[3], 1);
1833  ids.clear();
1834 
1835  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
1836  fps.clear();
1837 
1838  t.AddRequest(2, 5);
1839  sts = gen.getNext(fps);
1840  BOOST_REQUIRE_EQUAL(sts, true);
1841  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
1842  while (fps.size() > 0)
1843  {
1844  ids[fps.front()->fragmentID()]++;
1845  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
1846  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1847  type = artdaq::Fragment::ContainerFragmentType;
1848  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1849  auto cf = artdaq::ContainerFragment(*fps.front());
1850  BOOST_REQUIRE_EQUAL(cf.block_count(), 0);
1851  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1852  type = artdaq::Fragment::EmptyFragmentType;
1853  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
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  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
1862  fps.clear();
1863 
1864  gen.setFireCount(3);
1865  gen.waitForFrags();
1866  t.AddRequest(4, 7);
1867  sts = gen.getNext(fps);
1868  BOOST_REQUIRE_EQUAL(sts, true);
1869  BOOST_REQUIRE_EQUAL(fps.size(), 6);
1870 
1871  auto ts = artdaq::Fragment::InvalidTimestamp;
1872  auto emptyType = artdaq::Fragment::EmptyFragmentType;
1873  for (auto ii = 0; ii < 3; ++ii)
1874  {
1875  ids[fps.front()->fragmentID()]++;
1876  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
1877  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
1878  BOOST_REQUIRE_EQUAL(fps.front()->type(), emptyType);
1879  BOOST_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
1880  fps.pop_front();
1881  }
1882  BOOST_REQUIRE_EQUAL(ids[1], 1);
1883  BOOST_REQUIRE_EQUAL(ids[2], 1);
1884  BOOST_REQUIRE_EQUAL(ids[3], 1);
1885  ids.clear();
1886  for (auto ii = 0; ii < 3; ++ii)
1887  {
1888  ids[fps.front()->fragmentID()]++;
1889  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
1890  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
1891  type = artdaq::Fragment::ContainerFragmentType;
1892  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1893  auto cf3 = artdaq::ContainerFragment(*fps.front());
1894  BOOST_REQUIRE_EQUAL(cf3.block_count(), 3);
1895  BOOST_REQUIRE_EQUAL(cf3.missing_data(), false);
1896  type = artdaq::Fragment::FirstUserFragmentType;
1897  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
1898  fps.pop_front();
1899  }
1900  BOOST_REQUIRE_EQUAL(ids[1], 1);
1901  BOOST_REQUIRE_EQUAL(ids[2], 1);
1902  BOOST_REQUIRE_EQUAL(ids[3], 1);
1903  ids.clear();
1904 
1905  fps.clear();
1906  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 5);
1907 
1908  gen.setFireCount(5);
1909  gen.waitForFrags();
1910  t.AddRequest(5, 8);
1911  sts = gen.getNext(fps);
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(), 8);
1918  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
1919  type = artdaq::Fragment::ContainerFragmentType;
1920  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1921  auto cf = artdaq::ContainerFragment(*fps.front());
1922  BOOST_REQUIRE_EQUAL(cf.block_count(), 3);
1923  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1924  type = artdaq::Fragment::FirstUserFragmentType;
1925  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1926  BOOST_REQUIRE_EQUAL(cf.at(0)->timestamp(), 7);
1927  BOOST_REQUIRE_EQUAL(cf.at(1)->timestamp(), 8);
1928  BOOST_REQUIRE_EQUAL(cf.at(2)->timestamp(), 9);
1929  fps.pop_front();
1930  }
1931  BOOST_REQUIRE_EQUAL(ids[1], 1);
1932  BOOST_REQUIRE_EQUAL(ids[2], 1);
1933  BOOST_REQUIRE_EQUAL(ids[3], 1);
1934  ids.clear();
1935 
1936  fps.clear();
1937  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
1938 
1939  gen.setFireCount(1);
1940  gen.waitForFrags();
1941  gen.setEnabledIds(0x6); // Disable Fragment ID 3
1942  gen.setFireCount(4);
1943  gen.waitForFrags();
1944  t.AddRequest(6, 10);
1945  sts = gen.getNext(fps);
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(), 10);
1952  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 6);
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.missing_data(), false);
1957  type = artdaq::Fragment::FirstUserFragmentType;
1958  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1959 
1960  if (fps.front()->fragmentID() != 3)
1961  {
1962  BOOST_REQUIRE_EQUAL(cf.block_count(), 3);
1963  BOOST_REQUIRE_EQUAL(cf.at(0)->timestamp(), 12);
1964  BOOST_REQUIRE_EQUAL(cf.at(1)->timestamp(), 13);
1965  BOOST_REQUIRE_EQUAL(cf.at(2)->timestamp(), 14);
1966  }
1967  else
1968  {
1969  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
1970  BOOST_REQUIRE_EQUAL(cf.at(0)->timestamp(), 10);
1971  }
1972  fps.pop_front();
1973  }
1974  BOOST_REQUIRE_EQUAL(ids[1], 1);
1975  BOOST_REQUIRE_EQUAL(ids[2], 1);
1976  BOOST_REQUIRE_EQUAL(ids[3], 1);
1977  ids.clear();
1978 
1979  fps.clear();
1980  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 7);
1981 
1982  gen.StopCmd(0xFFFFFFFF, 1);
1983  gen.joinThreads();
1984 
1985  TLOG(TLVL_INFO) << "CircularBufferMode_MultipleIDs test case END";
1986 }
1987 
1988 BOOST_AUTO_TEST_CASE(WindowMode_Function_MultipleIDs)
1989 {
1990  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1991  TLOG(TLVL_INFO) << "WindowMode_Function_MultipleIDs test case BEGIN";
1992  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
1993  const int DELAY_TIME = 100;
1994  fhicl::ParameterSet ps;
1995  ps.put<int>("board_id", 1);
1996  ps.put<std::vector<int>>("fragment_ids", {1, 2, 3});
1997  ps.put<int>("request_port", REQUEST_PORT);
1998 #if MULTICAST_MODE
1999  ps.put<std::string>("request_address", "227.18.12.32");
2000 #else
2001  ps.put<std::string>("request_address", "localhost");
2002 #endif
2003  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
2004  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
2005  ps.put<bool>("separate_data_thread", true);
2006  ps.put<bool>("separate_monitoring_thread", false);
2007  ps.put<int64_t>("hardware_poll_interval_us", 0);
2008  ps.put<size_t>("data_buffer_depth_fragments", 5);
2009  ps.put<bool>("circular_buffer_mode", true);
2010  ps.put<std::string>("request_mode", "window");
2011  ps.put<size_t>("missing_request_window_timeout_us", 500000);
2012  ps.put<size_t>("window_close_timeout_us", 500000);
2013  ps.put("request_delay_ms", DELAY_TIME);
2014  ps.put("send_requests", true);
2015 
2016  artdaq::RequestSender t(ps);
2017  t.SetRunNumber(1);
2018  t.AddRequest(1, 1);
2019 
2021  gen.StartCmd(1, 0xFFFFFFFF, 1);
2022  gen.waitForFrags();
2023  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
2024 
2025  artdaq::FragmentPtrs fps;
2026  std::map<artdaq::Fragment::fragment_id_t, size_t> ids;
2027  auto sts = gen.getNext(fps);
2028  auto type = artdaq::Fragment::ContainerFragmentType;
2029  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
2030  BOOST_REQUIRE_EQUAL(sts, true);
2031  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
2032  while (fps.size() > 0)
2033  {
2034  ids[fps.front()->fragmentID()]++;
2035  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
2036  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
2037  type = artdaq::Fragment::ContainerFragmentType;
2038  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2039  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
2040  auto cf = artdaq::ContainerFragment(*fps.front());
2041  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
2042  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
2043  type = artdaq::Fragment::FirstUserFragmentType;
2044  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2045  fps.pop_front();
2046  }
2047  BOOST_REQUIRE_EQUAL(ids[1], 1);
2048  BOOST_REQUIRE_EQUAL(ids[2], 1);
2049  BOOST_REQUIRE_EQUAL(ids[3], 1);
2050  ids.clear();
2051  fps.clear();
2052 
2053  // No data for request
2054  t.AddRequest(2, 2);
2055  sts = gen.getNext(fps);
2056  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
2057  BOOST_REQUIRE_EQUAL(sts, true);
2058  BOOST_REQUIRE_EQUAL(fps.size(), 0);
2059 
2060  gen.setFireCount(1);
2061  gen.waitForFrags();
2062  sts = gen.getNext(fps);
2063  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
2064  BOOST_REQUIRE_EQUAL(sts, true);
2065  BOOST_REQUIRE_EQUAL(fps.size(), 3u);
2066  while (fps.size() > 0)
2067  {
2068  ids[fps.front()->fragmentID()]++;
2069  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
2070  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
2071  type = artdaq::Fragment::ContainerFragmentType;
2072  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2073  auto cf = artdaq::ContainerFragment(*fps.front());
2074  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
2075  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
2076  type = artdaq::Fragment::FirstUserFragmentType;
2077  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2078  fps.pop_front();
2079  }
2080  BOOST_REQUIRE_EQUAL(ids[1], 1);
2081  BOOST_REQUIRE_EQUAL(ids[2], 1);
2082  BOOST_REQUIRE_EQUAL(ids[3], 1);
2083  ids.clear();
2084  fps.clear();
2085 
2086  // Request Timeout
2087  t.AddRequest(4, 3);
2088  sts = gen.getNext(fps);
2089  BOOST_REQUIRE_EQUAL(sts, true);
2090  BOOST_REQUIRE_EQUAL(fps.size(), 0);
2091  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
2092 
2093  usleep(1500000);
2094  sts = gen.getNext(fps);
2095  BOOST_REQUIRE_EQUAL(sts, true);
2096  BOOST_REQUIRE_EQUAL(fps.size(), 3);
2097 
2098  // Also, missing request timeout
2099  auto list = gen.GetSentWindowList(1);
2100  BOOST_REQUIRE_EQUAL(list.size(), 1);
2101  BOOST_REQUIRE_EQUAL(list.begin()->first, 4);
2102  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
2103 
2104  usleep(1500000);
2105 
2106  while (fps.size() > 0)
2107  {
2108  ids[fps.front()->fragmentID()]++;
2109  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
2110  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
2111  type = artdaq::Fragment::ContainerFragmentType;
2112  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2113  auto cf = artdaq::ContainerFragment(*fps.front());
2114  BOOST_REQUIRE_EQUAL(cf.block_count(), 0);
2115  BOOST_REQUIRE_EQUAL(cf.missing_data(), true);
2116  type = artdaq::Fragment::EmptyFragmentType;
2117  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2118  fps.pop_front();
2119  }
2120  BOOST_REQUIRE_EQUAL(ids[1], 1);
2121  BOOST_REQUIRE_EQUAL(ids[2], 1);
2122  BOOST_REQUIRE_EQUAL(ids[3], 1);
2123  ids.clear();
2124 
2125  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
2126  fps.clear();
2127 
2128  // Data-taking has passed request
2129  gen.setFireCount(12);
2130  gen.waitForFrags();
2131  t.AddRequest(5, 4);
2132  list = gen.GetSentWindowList(1); // Out-of-order list is only updated in getNext calls
2133  BOOST_REQUIRE_EQUAL(list.size(), 1);
2134  sts = gen.getNext(fps);
2135  list = gen.GetSentWindowList(1);
2136  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
2137  BOOST_REQUIRE_EQUAL(list.size(), 0);
2138  BOOST_REQUIRE_EQUAL(sts, true);
2139  BOOST_REQUIRE_EQUAL(fps.size(), 3);
2140  while (fps.size() > 0)
2141  {
2142  ids[fps.front()->fragmentID()]++;
2143  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
2144  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
2145  type = artdaq::Fragment::ContainerFragmentType;
2146  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2147  auto cf = artdaq::ContainerFragment(*fps.front());
2148  BOOST_REQUIRE_EQUAL(cf.block_count(), 0);
2149  BOOST_REQUIRE_EQUAL(cf.missing_data(), true);
2150  type = artdaq::Fragment::EmptyFragmentType;
2151  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2152  fps.pop_front();
2153  }
2154  BOOST_REQUIRE_EQUAL(ids[1], 1);
2155  BOOST_REQUIRE_EQUAL(ids[2], 1);
2156  BOOST_REQUIRE_EQUAL(ids[3], 1);
2157  ids.clear();
2158  fps.clear();
2159 
2160  // Out-of-order windows
2161  t.AddRequest(7, 13);
2162  sts = gen.getNext(fps);
2163  BOOST_REQUIRE_EQUAL(sts, true);
2164  BOOST_REQUIRE_EQUAL(fps.size(), 3);
2165  while (fps.size() > 0)
2166  {
2167  ids[fps.front()->fragmentID()]++;
2168  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 13);
2169  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 7);
2170  type = artdaq::Fragment::ContainerFragmentType;
2171  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2172  auto cf = artdaq::ContainerFragment(*fps.front());
2173  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
2174  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
2175  type = artdaq::Fragment::FirstUserFragmentType;
2176  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2177  fps.pop_front();
2178  }
2179  BOOST_REQUIRE_EQUAL(ids[1], 1);
2180  BOOST_REQUIRE_EQUAL(ids[2], 1);
2181  BOOST_REQUIRE_EQUAL(ids[3], 1);
2182  ids.clear();
2183  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
2184  fps.clear();
2185 
2186  list = gen.GetSentWindowList(1);
2187  BOOST_REQUIRE_EQUAL(list.size(), 1);
2188  BOOST_REQUIRE_EQUAL(list.begin()->first, 7);
2189 
2190  t.AddRequest(6, 12);
2191  sts = gen.getNext(fps);
2192  BOOST_REQUIRE_EQUAL(sts, true);
2193  BOOST_REQUIRE_EQUAL(fps.size(), 3);
2194  while (fps.size() > 0)
2195  {
2196  ids[fps.front()->fragmentID()]++;
2197  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
2198  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 6);
2199  type = artdaq::Fragment::ContainerFragmentType;
2200  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2201  auto cf = artdaq::ContainerFragment(*fps.front());
2202  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
2203  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
2204  type = artdaq::Fragment::FirstUserFragmentType;
2205  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2206  fps.pop_front();
2207  }
2208  BOOST_REQUIRE_EQUAL(ids[1], 1);
2209  BOOST_REQUIRE_EQUAL(ids[2], 1);
2210  BOOST_REQUIRE_EQUAL(ids[3], 1);
2211  ids.clear();
2212  fps.clear();
2213  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 8);
2214 
2215  list = gen.GetSentWindowList(1);
2216  BOOST_REQUIRE_EQUAL(list.size(), 0);
2217 
2218  gen.setEnabledIds(0x6); // Disable Fragment ID 3
2219  gen.setFireCount(1);
2220  gen.waitForFrags();
2221 
2222  t.AddRequest(8, 15);
2223  sts = gen.getNext(fps);
2224  BOOST_REQUIRE_EQUAL(sts, true);
2225  BOOST_REQUIRE_EQUAL(fps.size(), 2);
2226  while (fps.size() > 0)
2227  {
2228  ids[fps.front()->fragmentID()]++;
2229  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 15);
2230  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 8);
2231  type = artdaq::Fragment::ContainerFragmentType;
2232  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2233  auto cf = artdaq::ContainerFragment(*fps.front());
2234  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
2235  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
2236  type = artdaq::Fragment::FirstUserFragmentType;
2237  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2238  fps.pop_front();
2239  }
2240  BOOST_REQUIRE_EQUAL(ids[1], 1);
2241  BOOST_REQUIRE_EQUAL(ids[2], 1);
2242  BOOST_REQUIRE_EQUAL(ids[3], 0);
2243  ids.clear();
2244  fps.clear();
2245  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 8);
2246 
2247  gen.setEnabledIds(0x8); // Disable Fragment IDs 1 and 2
2248  gen.setTimestamp(14); // Reset timestamp
2249  gen.setFireCount(1);
2250  gen.waitForFrags();
2251 
2252  sts = gen.getNext(fps);
2253  BOOST_REQUIRE_EQUAL(sts, true);
2254  BOOST_REQUIRE_EQUAL(fps.size(), 1);
2255  while (fps.size() > 0)
2256  {
2257  ids[fps.front()->fragmentID()]++;
2258  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 15);
2259  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 8);
2260  type = artdaq::Fragment::ContainerFragmentType;
2261  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
2262  auto cf = artdaq::ContainerFragment(*fps.front());
2263  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
2264  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
2265  type = artdaq::Fragment::FirstUserFragmentType;
2266  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
2267  fps.pop_front();
2268  }
2269  BOOST_REQUIRE_EQUAL(ids[1], 0);
2270  BOOST_REQUIRE_EQUAL(ids[2], 0);
2271  BOOST_REQUIRE_EQUAL(ids[3], 1);
2272  ids.clear();
2273  fps.clear();
2274  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 9);
2275 
2276  gen.StopCmd(0xFFFFFFFF, 1);
2277  TLOG(TLVL_INFO) << "WindowMode_Function_MultipleIDs test case END";
2278  gen.joinThreads();
2279 }
2280 
2281 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.