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