artdaq  v3_02_01
CommandableFragmentGenerator_t.cc
1 #define TRACE_NAME "CommandableFragmentGenerator_t"
2 
3 #define BOOST_TEST_MODULE CommandableFragmentGenerator_t
4 #include <boost/test/auto_unit_test.hpp>
5 
6 #include "artdaq-core/Data/Fragment.hh"
7 #include "artdaq-core/Data/ContainerFragment.hh"
8 #include "artdaq/Application/CommandableFragmentGenerator.hh"
9 #include "artdaq/DAQrate/RequestSender.hh"
10 
11 #define MULTICAST_MODE 0
12 
13 namespace artdaqtest
14 {
15  class CommandableFragmentGeneratorTest;
16 }
17 
23 {
24 public:
28  explicit CommandableFragmentGeneratorTest(const fhicl::ParameterSet& ps);
29 
31 
32 protected:
40  bool getNext_(artdaq::FragmentPtrs& frags) override;
41 
46  bool checkHWStatus_() override { return !hwFail_.load(); }
47 
51  void start() override;
52 
56  void stopNoMutex() override;
57 
61  void stop() override;
62 
66  void pause() override;
67 
71  void resume() override;
72 
73 public:
78  void setFireCount(size_t count) { fireCount_ = count; }
79 
83  void setHwFail() { hwFail_ = true; }
84 
88  void waitForFrags() {
89  auto start_time = std::chrono::steady_clock::now();
90  while (fireCount_ > 0) { usleep(1000); }
91  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" ;
92  }
93 private:
94  std::atomic<size_t> fireCount_;
95  std::atomic<bool> hwFail_;
96  artdaq::Fragment::timestamp_t ts_;
97  bool hw_stop_;
98 };
99 
101  : CommandableFragmentGenerator(ps)
102  , fireCount_(1)
103  , hwFail_(false)
104  , ts_(0)
105  , hw_stop_(false)
106 {}
107 
108 bool
110 {
111  while (fireCount_ > 0)
112  {
113  frags.emplace_back(new artdaq::Fragment(ev_counter(), fragment_id(), artdaq::Fragment::FirstUserFragmentType, ++ts_));
114  fireCount_--;
115  }
116 
117  return !hw_stop_;
118 }
119 
120 void
122 
123 void
125 
126 void
128 
129 void
131 
132 void
134 
135 BOOST_AUTO_TEST_SUITE(CommandableFragmentGenerator_t)
136 
137 BOOST_AUTO_TEST_CASE(Simple)
138 {
139  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
140  TLOG(TLVL_INFO) << "Simple test case BEGIN" ;
141  fhicl::ParameterSet ps;
142  ps.put<int>("board_id", 1);
143  ps.put<int>("fragment_id", 1);
145  artdaq::FragmentPtrs fps;
146  auto sts = testGen.getNext(fps);
147  BOOST_REQUIRE_EQUAL(sts, true);
148  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
149  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
150  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
151  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
152  TLOG(TLVL_INFO) << "Simple test case END" ;
153 }
154 
155 BOOST_AUTO_TEST_CASE(IgnoreRequests)
156 {
157  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
158  TLOG(TLVL_INFO) << "IgnoreRequests test case BEGIN" ;
159  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
160  const int DELAY_TIME = 1;
161  fhicl::ParameterSet ps;
162  ps.put<int>("board_id", 1);
163  ps.put<int>("fragment_id", 1);
164  ps.put<int>("request_port", REQUEST_PORT);
165 #if MULTICAST_MODE
166  ps.put<std::string>("request_address", "227.18.12.29");
167 #else
168  ps.put<std::string>("request_address", "localhost");
169 #endif
170  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
171  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
172  ps.put<bool>("separate_data_thread", true);
173  ps.put<bool>("separate_monitoring_thread", false);
174  ps.put<int64_t>("hardware_poll_interval_us", 0);
175  ps.put<std::string>("request_mode", "ignored");
176  ps.put("request_delay_ms", DELAY_TIME);
177  ps.put("send_requests", true);
178 
179  artdaq::RequestSender t(ps);
181  gen.StartCmd(1, 0xFFFFFFFF, 1);
182  t.AddRequest(53, 35);
183 
184  artdaq::FragmentPtrs fps;
185  auto sts = gen.getNext(fps);
186  BOOST_REQUIRE_EQUAL(sts, true);
187  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
188  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
189  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
190  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
191  gen.StopCmd(0xFFFFFFFF, 1);
192  gen.joinThreads();
193  TLOG(TLVL_INFO) << "IgnoreRequests test case END" ;
194 }
195 
196 BOOST_AUTO_TEST_CASE(SingleMode)
197 {
198  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
199  TLOG(TLVL_INFO) << "SingleMode test case BEGIN" ;
200  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
201  const int DELAY_TIME = 100;
202  fhicl::ParameterSet ps;
203  ps.put<int>("board_id", 1);
204  ps.put<int>("fragment_id", 1);
205  ps.put<int>("request_port", REQUEST_PORT);
206 #if MULTICAST_MODE
207  ps.put<std::string>("request_address", "227.18.12.30");
208 #else
209  ps.put<std::string>("request_address", "localhost");
210 #endif
211  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
212  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
213  ps.put<bool>("separate_data_thread", true);
214  ps.put<bool>("separate_monitoring_thread", false);
215  ps.put<int64_t>("hardware_poll_interval_us", 0);
216  ps.put<std::string>("request_mode", "single");
217  ps.put("request_delay_ms", DELAY_TIME);
218  ps.put("send_requests", true);
219 
220  artdaq::RequestSender t(ps);
221  t.AddRequest(1, 1);
222 
224  gen.StartCmd(1, 0xFFFFFFFF, 1);
225  gen.waitForFrags();
226  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
227 
228  artdaq::FragmentPtrs fps;
229  auto sts = gen.getNext(fps);
230  auto type = artdaq::Fragment::FirstUserFragmentType;
231  BOOST_REQUIRE_EQUAL(sts, true);
232  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
233  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
234  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
235  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
236  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
237  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
238  fps.clear();
239 
240  t.AddRequest(2, 5);
241  sts = gen.getNext(fps);
242  BOOST_REQUIRE_EQUAL(sts, true);
243  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
244  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
245  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
246  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
247  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
248  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
249  fps.clear();
250 
251  gen.setFireCount(2);
252  gen.waitForFrags();
253  t.AddRequest(4, 7);
254  sts = gen.getNext(fps);
255  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 5);
256  BOOST_REQUIRE_EQUAL(sts, true);
257  BOOST_REQUIRE_EQUAL(fps.size(), 2);
258  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
259  auto ts = artdaq::Fragment::InvalidTimestamp;
260  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
261  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
262  auto emptyType = artdaq::Fragment::EmptyFragmentType;
263  BOOST_REQUIRE_EQUAL(fps.front()->type(), emptyType);
264  fps.pop_front();
265  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
266  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
267  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
268  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
269  fps.clear();
270 
271  gen.StopCmd(0xFFFFFFFF, 1);
272  gen.joinThreads();
273  TLOG(TLVL_INFO) << "SingleMode test case END" ;
274 }
275 
276 BOOST_AUTO_TEST_CASE(BufferMode)
277 {
278  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
279  TLOG(TLVL_INFO) << "BufferMode test case BEGIN" ;
280  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
281  const int DELAY_TIME = 100;
282  fhicl::ParameterSet ps;
283  ps.put<int>("board_id", 1);
284  ps.put<int>("fragment_id", 1);
285  ps.put<int>("request_port", REQUEST_PORT);
286 #if MULTICAST_MODE
287  ps.put<std::string>("request_address", "227.18.12.31");
288 #else
289  ps.put<std::string>("request_address", "localhost");
290 #endif
291  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
292  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
293  ps.put<bool>("separate_data_thread", true);
294  ps.put<bool>("separate_monitoring_thread", false);
295  ps.put<int64_t>("hardware_poll_interval_us", 0);
296  ps.put<std::string>("request_mode", "buffer");
297  ps.put("request_delay_ms", DELAY_TIME);
298  ps.put("send_requests", true);
299 
300  artdaq::RequestSender t(ps);
301  t.AddRequest(1, 1);
302 
304  gen.StartCmd(1, 0xFFFFFFFF, 1);
305  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
306 
307 
308  artdaq::FragmentPtrs fps;
309  auto sts = gen.getNext(fps);
310  BOOST_REQUIRE_EQUAL(sts, true);
311  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
312  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
313  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
314  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
315  auto type = artdaq::Fragment::ContainerFragmentType;
316  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
317  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
318  auto cf = artdaq::ContainerFragment(*fps.front());
319  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
320  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
321  type = artdaq::Fragment::FirstUserFragmentType;
322  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
323  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
324  fps.clear();
325 
326  t.AddRequest(2, 5);
327  sts = gen.getNext(fps);
328  BOOST_REQUIRE_EQUAL(sts, true);
329  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
330  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
331  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
332  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
333  type = artdaq::Fragment::ContainerFragmentType;
334  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
335  auto cf2 = artdaq::ContainerFragment(*fps.front());
336  BOOST_REQUIRE_EQUAL(cf2.block_count(), 0);
337  BOOST_REQUIRE_EQUAL(cf2.missing_data(), false);
338  type = artdaq::Fragment::EmptyFragmentType;
339  BOOST_REQUIRE_EQUAL(cf2.fragment_type(), type);
340  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
341  fps.clear();
342 
343  gen.setFireCount(2);
344  gen.waitForFrags();
345  t.AddRequest(4, 7);
346  sts = gen.getNext(fps);
347  BOOST_REQUIRE_EQUAL(sts, true);
348  BOOST_REQUIRE_EQUAL(fps.size(), 2);
349 
350  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
351  auto ts = artdaq::Fragment::InvalidTimestamp;
352  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), ts);
353  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
354  auto emptyType = artdaq::Fragment::EmptyFragmentType;
355  BOOST_REQUIRE_EQUAL(fps.front()->type(), emptyType);
356  BOOST_REQUIRE_EQUAL(fps.front()->size(), artdaq::detail::RawFragmentHeader::num_words());
357  fps.pop_front();
358  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
359  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 7);
360  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
361  type = artdaq::Fragment::ContainerFragmentType;
362  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
363  auto cf3 = artdaq::ContainerFragment(*fps.front());
364  BOOST_REQUIRE_EQUAL(cf3.block_count(), 2);
365  BOOST_REQUIRE_EQUAL(cf3.missing_data(), false);
366  type = artdaq::Fragment::FirstUserFragmentType;
367  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
368  fps.clear();
369  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 5);
370 
371 
372  gen.StopCmd(0xFFFFFFFF, 1);
373  gen.joinThreads();
374 
375 
376  TLOG(TLVL_INFO) << "BufferMode test case END" ;
377 }
378 
379 BOOST_AUTO_TEST_CASE(WindowMode_Function)
380 {
381  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
382  TLOG(TLVL_INFO) << "WindowMode_Function test case BEGIN" ;
383  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
384  const int DELAY_TIME = 100;
385  fhicl::ParameterSet ps;
386  ps.put<int>("board_id", 1);
387  ps.put<int>("fragment_id", 1);
388  ps.put<int>("request_port", REQUEST_PORT);
389 #if MULTICAST_MODE
390  ps.put<std::string>("request_address", "227.18.12.32");
391 #else
392  ps.put<std::string>("request_address", "localhost");
393 #endif
394  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
395  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 0);
396  ps.put<bool>("separate_data_thread", true);
397  ps.put<bool>("separate_monitoring_thread", false);
398  ps.put<int64_t>("hardware_poll_interval_us", 0);
399  ps.put<size_t>("data_buffer_depth_fragments", 5);
400  ps.put<std::string>("request_mode", "window");
401  ps.put<size_t>("missing_request_window_timeout_us", 500000);
402  ps.put<size_t>("window_close_timeout_us", 500000);
403  ps.put("request_delay_ms", DELAY_TIME);
404  ps.put("send_requests", true);
405 
406  artdaq::RequestSender t(ps);
407  t.AddRequest(1, 1);
408 
410  gen.StartCmd(1, 0xFFFFFFFF, 1);
411  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 1);
412 
413  artdaq::FragmentPtrs fps;
414  auto sts = gen.getNext(fps);
415  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
416  BOOST_REQUIRE_EQUAL(sts, true);
417  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
418  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
419  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
420  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
421  auto type = artdaq::Fragment::ContainerFragmentType;
422  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
423  BOOST_REQUIRE_GE(fps.front()->sizeBytes(), 2 * sizeof(artdaq::detail::RawFragmentHeader) + sizeof(artdaq::ContainerFragment::Metadata));
424  auto cf = artdaq::ContainerFragment(*fps.front());
425  BOOST_REQUIRE_EQUAL(cf.block_count(), 1);
426  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
427  type = artdaq::Fragment::FirstUserFragmentType;
428  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
429  fps.clear();
430 
431  // No data for request
432  t.AddRequest(2, 2);
433  sts = gen.getNext(fps);
434  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 2);
435  BOOST_REQUIRE_EQUAL(sts, true);
436  BOOST_REQUIRE_EQUAL(fps.size(), 0);
437 
438  gen.setFireCount(1);
439  gen.waitForFrags();
440  sts = gen.getNext(fps);
441  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
442  BOOST_REQUIRE_EQUAL(sts, true);
443  BOOST_REQUIRE_EQUAL(fps.size(), 1);
444  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
445  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
446  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
447  type = artdaq::Fragment::ContainerFragmentType;
448  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
449  auto cf2 = artdaq::ContainerFragment(*fps.front());
450  BOOST_REQUIRE_EQUAL(cf2.block_count(), 1);
451  BOOST_REQUIRE_EQUAL(cf2.missing_data(), false);
452  type = artdaq::Fragment::FirstUserFragmentType;
453  BOOST_REQUIRE_EQUAL(cf2.fragment_type(), type);
454  fps.clear();
455 
456  // Request Timeout
457  t.AddRequest(4, 3);
458  sts = gen.getNext(fps);
459  BOOST_REQUIRE_EQUAL(sts, true);
460  BOOST_REQUIRE_EQUAL(fps.size(), 0);
461  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
462 
463 
464  usleep(1500000);
465  sts = gen.getNext(fps);
466  BOOST_REQUIRE_EQUAL(sts, true);
467  BOOST_REQUIRE_EQUAL(fps.size(), 1);
468 
469  // Also, missing request timeout
470  auto list = gen.getOutOfOrderWindowList();
471  BOOST_REQUIRE_EQUAL(list.size(), 1);
472  BOOST_REQUIRE_EQUAL(list.begin()->first, 4);
473  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
474 
475  usleep(1500000);
476 
477 
478  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
479  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
480  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 4);
481  type = artdaq::Fragment::ContainerFragmentType;
482  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
483  auto cf3 = artdaq::ContainerFragment(*fps.front());
484  BOOST_REQUIRE_EQUAL(cf3.block_count(), 0);
485  BOOST_REQUIRE_EQUAL(cf3.missing_data(), true);
486  type = artdaq::Fragment::EmptyFragmentType;
487  BOOST_REQUIRE_EQUAL(cf3.fragment_type(), type);
488  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 3);
489  fps.clear();
490 
491  // Data-taking has passed request
492  gen.setFireCount(12);
493  gen.waitForFrags();
494  t.AddRequest(5, 4);
495  list = gen.getOutOfOrderWindowList(); // Out-of-order list is only updated in getNext calls
496  BOOST_REQUIRE_EQUAL(list.size(), 1);
497  sts = gen.getNext(fps);
498  list = gen.getOutOfOrderWindowList(); // Out-of-order list is only updated in getNext calls
499  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
500  BOOST_REQUIRE_EQUAL(list.size(), 0);
501  BOOST_REQUIRE_EQUAL(sts, true);
502  BOOST_REQUIRE_EQUAL(fps.size(), 1);
503  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
504  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
505  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 5);
506  type = artdaq::Fragment::ContainerFragmentType;
507  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
508  auto cf4 = artdaq::ContainerFragment(*fps.front());
509  BOOST_REQUIRE_EQUAL(cf4.block_count(), 0);
510  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
511  type = artdaq::Fragment::EmptyFragmentType;
512  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
513  fps.clear();
514 
515 
516  // Out-of-order windows
517  t.AddRequest(7, 13);
518  sts = gen.getNext(fps);
519  BOOST_REQUIRE_EQUAL(sts, true);
520  BOOST_REQUIRE_EQUAL(fps.size(), 1);
521  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
522  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 13);
523  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 7);
524  type = artdaq::Fragment::ContainerFragmentType;
525  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
526  auto cf5 = artdaq::ContainerFragment(*fps.front());
527  BOOST_REQUIRE_EQUAL(cf5.block_count(), 1);
528  BOOST_REQUIRE_EQUAL(cf5.missing_data(), false);
529  type = artdaq::Fragment::FirstUserFragmentType;
530  BOOST_REQUIRE_EQUAL(cf5.fragment_type(), type);
531  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 6);
532  fps.clear();
533 
534  list = gen.getOutOfOrderWindowList();
535  BOOST_REQUIRE_EQUAL(list.size(), 1);
536  BOOST_REQUIRE_EQUAL(list.begin()->first, 7);
537 
538  t.AddRequest(6, 12);
539  sts = gen.getNext(fps);
540  BOOST_REQUIRE_EQUAL(sts, true);
541  BOOST_REQUIRE_EQUAL(fps.size(), 1);
542  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
543  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
544  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 6);
545  type = artdaq::Fragment::ContainerFragmentType;
546  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
547  auto cf6 = artdaq::ContainerFragment(*fps.front());
548  BOOST_REQUIRE_EQUAL(cf6.block_count(), 1);
549  BOOST_REQUIRE_EQUAL(cf6.missing_data(), false);
550  type = artdaq::Fragment::FirstUserFragmentType;
551  BOOST_REQUIRE_EQUAL(cf6.fragment_type(), type);
552  fps.clear();
553  BOOST_REQUIRE_EQUAL(gen.ev_counter(), 8);
554 
555  list = gen.getOutOfOrderWindowList();
556  BOOST_REQUIRE_EQUAL(list.size(), 0);
557 
558  usleep(1500000);
559 
560  gen.StopCmd(0xFFFFFFFF, 1);
561  TLOG(TLVL_INFO) << "WindowMode_Function test case END" ;
562  gen.joinThreads();
563 
564 }
565 
566 // 1. Both start and end before any data in buffer "RequestBeforeBuffer"
567 // 2. Start before buffer, end in buffer "RequestStartsBeforeBuffer"
568 // 3. Start befoer buffer, end after buffer "RequestOutsideBuffer"
569 // 4. Start and end in buffer "RequestInBuffer"
570 // 5. Start in buffer, end after buffer "RequestEndsAfterBuffer"
571 // 6. Start and end after buffer "RequestAfterBuffer"
572 BOOST_AUTO_TEST_CASE(WindowMode_RequestBeforeBuffer)
573 {
574  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
575  TLOG(TLVL_INFO) << "WindowMode_RequestBeforeBuffer test case BEGIN" ;
576  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
577  const int DELAY_TIME = 100;
578  fhicl::ParameterSet ps;
579  ps.put<int>("board_id", 1);
580  ps.put<int>("fragment_id", 1);
581  ps.put<int>("request_port", REQUEST_PORT);
582 #if MULTICAST_MODE
583  ps.put<std::string>("request_address", "227.18.12.32");
584 #else
585  ps.put<std::string>("request_address", "localhost");
586 #endif
587  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
588  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
589  ps.put<bool>("separate_data_thread", true);
590  ps.put<bool>("separate_monitoring_thread", false);
591  ps.put<int64_t>("hardware_poll_interval_us", 0);
592  ps.put<size_t>("data_buffer_depth_fragments", 5);
593  ps.put<std::string>("request_mode", "window");
594  ps.put("request_delay_ms", DELAY_TIME);
595  ps.put("send_requests", true);
596 
597  artdaq::RequestSender t(ps);
598 
600  gen.StartCmd(1, 0xFFFFFFFF, 1);
601 
602  artdaq::FragmentPtrs fps;
603  int sts;
604  artdaq::Fragment::type_t type;
605 
606  // 1. Both start and end before any data in buffer
607  // -- Should return ContainerFragment with MissingData bit set and zero Fragments
608  gen.setFireCount(9); // Buffer start is at ts 6, end at 10
609  gen.waitForFrags();
610  t.AddRequest(1, 1); // Requesting data from ts 1 to 3
611 
612  sts = gen.getNext(fps);
613  BOOST_REQUIRE_EQUAL(sts, true);
614  BOOST_REQUIRE_EQUAL(fps.size(), 1);
615  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
616  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
617  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
618  type = artdaq::Fragment::ContainerFragmentType;
619  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
620  auto cf4 = artdaq::ContainerFragment(*fps.front());
621  BOOST_REQUIRE_EQUAL(cf4.block_count(), 0);
622  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
623  type = artdaq::Fragment::EmptyFragmentType;
624  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
625 
626  gen.StopCmd(0xFFFFFFFF, 1);
627  TLOG(TLVL_INFO) << "WindowMode_RequestBeforeBuffer test case END" ;
628 
629 }
631 {
632  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
633  TLOG(TLVL_INFO) << "WindowMode_RequestStartsBeforeBuffer test case BEGIN" ;
634  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
635  const int DELAY_TIME = 100;
636  fhicl::ParameterSet ps;
637  ps.put<int>("board_id", 1);
638  ps.put<int>("fragment_id", 1);
639  ps.put<int>("request_port", REQUEST_PORT);
640 #if MULTICAST_MODE
641  ps.put<std::string>("request_address", "227.18.12.32");
642 #else
643  ps.put<std::string>("request_address", "localhost");
644 #endif
645  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
646  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
647  ps.put<bool>("separate_data_thread", true);
648  ps.put<bool>("separate_monitoring_thread", false);
649  ps.put<int64_t>("hardware_poll_interval_us", 0);
650  ps.put<size_t>("data_buffer_depth_fragments", 5);
651  ps.put<std::string>("request_mode", "window");
652  ps.put("request_delay_ms", DELAY_TIME);
653  ps.put("send_requests", true);
654 
655  artdaq::RequestSender t(ps);
656 
658  gen.StartCmd(1, 0xFFFFFFFF, 1);
659 
660  artdaq::FragmentPtrs fps;
661  int sts;
662  artdaq::Fragment::type_t type;
663 
664  gen.waitForFrags();
665  gen.setFireCount(9); // Buffer contains 6 to 10
666  gen.waitForFrags();
667 
668  // 2. Start before buffer, end in buffer
669  // -- Should return ContainerFragment with MissingData bit set and one or more Fragments
670  t.AddRequest(1, 4); // Requesting data from ts 4 to 6
671 
672  sts = gen.getNext(fps);
673  BOOST_REQUIRE_EQUAL(sts, true);
674  BOOST_REQUIRE_EQUAL(fps.size(), 1);
675  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
676  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 4);
677  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
678  type = artdaq::Fragment::ContainerFragmentType;
679  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
680  auto cf4 = artdaq::ContainerFragment(*fps.front());
681  BOOST_REQUIRE_EQUAL(cf4.block_count(), 1);
682  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
683  type = artdaq::Fragment::FirstUserFragmentType;
684  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
685 
686  gen.StopCmd(0xFFFFFFFF, 1);
687  gen.joinThreads();
688  TLOG(TLVL_INFO) << "WindowMode_RequestStartsBeforeBuffer test case END" ;
689 
690 }
691 BOOST_AUTO_TEST_CASE(WindowMode_RequestOutsideBuffer)
692 {
693  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
694  TLOG(TLVL_INFO) << "WindowMode_RequestOutsideBuffer test case BEGIN" ;
695  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
696  const int DELAY_TIME = 100;
697  fhicl::ParameterSet ps;
698  ps.put<int>("board_id", 1);
699  ps.put<int>("fragment_id", 1);
700  ps.put<int>("request_port", REQUEST_PORT);
701 #if MULTICAST_MODE
702  ps.put<std::string>("request_address", "227.18.12.32");
703 #else
704  ps.put<std::string>("request_address", "localhost");
705 #endif
706  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
707  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 4);
708  ps.put<size_t>("window_close_timeout_us", 500000);
709  ps.put<bool>("separate_data_thread", true);
710  ps.put<bool>("separate_monitoring_thread", false);
711  ps.put<int64_t>("hardware_poll_interval_us", 0);
712  ps.put<size_t>("data_buffer_depth_fragments", 5);
713  ps.put<std::string>("request_mode", "window");
714  ps.put("request_delay_ms", DELAY_TIME);
715  ps.put("send_requests", true);
716 
717  artdaq::RequestSender t(ps);
718 
720  gen.StartCmd(1, 0xFFFFFFFF, 1);
721 
722  artdaq::FragmentPtrs fps;
723  int sts;
724  artdaq::Fragment::type_t type;
725 
726  gen.waitForFrags();
727  gen.setFireCount(9); // Buffer contains 6 to 10
728  gen.waitForFrags();
729 
730  // 3. Start before buffer, end after buffer
731  // -- Should not return until buffer passes end or timeout (check both cases), MissingData bit set
732 
733  t.AddRequest(1, 6); // Requesting data from ts 6 to 9, buffer will contain 10
734  sts = gen.getNext(fps);
735  BOOST_REQUIRE_EQUAL(sts, true);
736  BOOST_REQUIRE_EQUAL(fps.size(), 1);
737  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
738  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 6);
739  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
740  type = artdaq::Fragment::ContainerFragmentType;
741  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
742  auto cf = artdaq::ContainerFragment(*fps.front());
743  BOOST_REQUIRE_EQUAL(cf.block_count(), 4);
744  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
745  type = artdaq::Fragment::FirstUserFragmentType;
746  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
747  fps.clear();
748 
749  t.AddRequest(2, 9); // Requesting data from ts 9 to 12
750  sts = gen.getNext(fps);
751  BOOST_REQUIRE_EQUAL(sts, true);
752  BOOST_REQUIRE_EQUAL(fps.size(), 0);
753 
754  gen.setFireCount(3); // Buffer start is at ts 10, end at 13
755  gen.waitForFrags();
756 
757  sts = gen.getNext(fps);
758  BOOST_REQUIRE_EQUAL(sts, true);
759  BOOST_REQUIRE_EQUAL(fps.size(), 1);
760  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
761  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 9);
762  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
763  type = artdaq::Fragment::ContainerFragmentType;
764  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
765  auto cf2 = artdaq::ContainerFragment(*fps.front());
766  BOOST_REQUIRE_EQUAL(cf2.block_count(), 3);
767  BOOST_REQUIRE_EQUAL(cf2.missing_data(), true);
768  type = artdaq::Fragment::FirstUserFragmentType;
769  BOOST_REQUIRE_EQUAL(cf2.fragment_type(), type);
770  fps.clear();
771 
772 
773 
774  t.AddRequest(3, 12); // Requesting data from ts 11 to 14
775 
776  sts = gen.getNext(fps);
777  BOOST_REQUIRE_EQUAL(sts, true);
778  BOOST_REQUIRE_EQUAL(fps.size(), 0);
779 
780  usleep(550000);
781 
782  sts = gen.getNext(fps);
783  BOOST_REQUIRE_EQUAL(sts, true);
784  BOOST_REQUIRE_EQUAL(fps.size(), 1);
785  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
786  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 12);
787  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 3);
788  type = artdaq::Fragment::ContainerFragmentType;
789  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
790  auto cf4 = artdaq::ContainerFragment(*fps.front());
791  BOOST_REQUIRE_EQUAL(cf4.block_count(), 1);
792  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
793  type = artdaq::Fragment::FirstUserFragmentType;
794  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
795 
796  gen.StopCmd(0xFFFFFFFF, 1);
797  gen.joinThreads();
798  TLOG(TLVL_INFO) << "WindowMode_RequestOutsideBuffer test case END" ;
799 
800 }
801 BOOST_AUTO_TEST_CASE(WindowMode_RequestInBuffer)
802 {
803  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
804  TLOG(TLVL_INFO) << "WindowMode_RequestInBuffer test case BEGIN" ;
805  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
806  const int DELAY_TIME = 100;
807  fhicl::ParameterSet ps;
808  ps.put<int>("board_id", 1);
809  ps.put<int>("fragment_id", 1);
810  ps.put<int>("request_port", REQUEST_PORT);
811 #if MULTICAST_MODE
812  ps.put<std::string>("request_address", "227.18.12.32");
813 #else
814  ps.put<std::string>("request_address", "localhost");
815 #endif
816  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
817  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
818  ps.put<bool>("separate_data_thread", true);
819  ps.put<bool>("separate_monitoring_thread", false);
820  ps.put<int64_t>("hardware_poll_interval_us", 0);
821  ps.put<size_t>("data_buffer_depth_fragments", 5);
822  ps.put<std::string>("request_mode", "window");
823  ps.put("request_delay_ms", DELAY_TIME);
824  ps.put("send_requests", true);
825 
826  artdaq::RequestSender t(ps);
827 
829  gen.StartCmd(1, 0xFFFFFFFF, 1);
830 
831  artdaq::FragmentPtrs fps;
832  int sts;
833  artdaq::Fragment::type_t type;
834  gen.waitForFrags();
835 
836  // 4. Start and end in buffer
837  // -- Should return ContainerFragment with one or more Fragments
838  gen.setFireCount(5); // Buffer start is at ts 2, end at 6
839  gen.waitForFrags();
840  t.AddRequest(1, 3); // Requesting data from ts 3 to 5
841 
842  sts = gen.getNext(fps);
843  BOOST_REQUIRE_EQUAL(sts, true);
844  BOOST_REQUIRE_EQUAL(fps.size(), 1);
845  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
846  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 3);
847  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
848  type = artdaq::Fragment::ContainerFragmentType;
849  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
850  auto cf4 = artdaq::ContainerFragment(*fps.front());
851  BOOST_REQUIRE_EQUAL(cf4.block_count(), 3);
852  BOOST_REQUIRE_EQUAL(cf4.missing_data(), false);
853  type = artdaq::Fragment::FirstUserFragmentType;
854  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
855 
856  gen.StopCmd(0xFFFFFFFF, 1);
857  TLOG(TLVL_INFO) << "WindowMode_RequestInBuffer test case END" ;
858 
859 }
861 {
862  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
863  TLOG(TLVL_INFO) << "WindowMode_RequestEndsAfterBuffer test case BEGIN" ;
864  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
865  const int DELAY_TIME = 100;
866  fhicl::ParameterSet ps;
867  ps.put<int>("board_id", 1);
868  ps.put<int>("fragment_id", 1);
869  ps.put<int>("request_port", REQUEST_PORT);
870 #if MULTICAST_MODE
871  ps.put<std::string>("request_address", "227.18.12.32");
872 #else
873  ps.put<std::string>("request_address", "localhost");
874 #endif
875  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
876  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
877  ps.put<size_t>("window_close_timeout_us", 500000);
878  ps.put<bool>("separate_data_thread", true);
879  ps.put<bool>("separate_monitoring_thread", false);
880  ps.put<int64_t>("hardware_poll_interval_us", 0);
881  ps.put<size_t>("data_buffer_depth_fragments", 5);
882  ps.put<std::string>("request_mode", "window");
883  ps.put("request_delay_ms", DELAY_TIME);
884  ps.put("send_requests", true);
885 
886  artdaq::RequestSender t(ps);
887 
889  gen.StartCmd(1, 0xFFFFFFFF, 1);
890 
891  artdaq::FragmentPtrs fps;
892  int sts;
893  artdaq::Fragment::type_t type;
894  gen.waitForFrags();
895  gen.setFireCount(5); // Buffer contains 2 to 6
896  gen.waitForFrags();
897 
898  // 5. Start in buffer, end after buffer
899  // -- Should not return until buffer passes end or timeout (check both cases). MissingData bit set if timeout
900  t.AddRequest(1, 5); // Requesting data from ts 5 to 7
901  sts = gen.getNext(fps);
902  BOOST_REQUIRE_EQUAL(sts, true);
903  BOOST_REQUIRE_EQUAL(fps.size(), 0);
904 
905  gen.setFireCount(2); // Buffer contains 4 to 8
906  gen.waitForFrags();
907  sts = gen.getNext(fps);
908  BOOST_REQUIRE_EQUAL(sts, true);
909  BOOST_REQUIRE_EQUAL(fps.size(), 1);
910  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
911  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 5);
912  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
913  type = artdaq::Fragment::ContainerFragmentType;
914  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
915  auto cf = artdaq::ContainerFragment(*fps.front());
916  BOOST_REQUIRE_EQUAL(cf.block_count(), 3);
917  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
918  type = artdaq::Fragment::FirstUserFragmentType;
919  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
920  fps.clear();
921 
922  t.AddRequest(2, 8); // Requesting data from ts 8 to 10
923 
924  sts = gen.getNext(fps);
925  BOOST_REQUIRE_EQUAL(sts, true);
926  BOOST_REQUIRE_EQUAL(fps.size(), 0);
927 
928  usleep(550000);
929 
930  sts = gen.getNext(fps);
931  BOOST_REQUIRE_EQUAL(sts, true);
932  BOOST_REQUIRE_EQUAL(fps.size(), 1);
933  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
934  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 8);
935  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
936  type = artdaq::Fragment::ContainerFragmentType;
937  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
938  auto cf4 = artdaq::ContainerFragment(*fps.front());
939  BOOST_REQUIRE_EQUAL(cf4.block_count(), 1);
940  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
941  type = artdaq::Fragment::FirstUserFragmentType;
942  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
943 
944  gen.StopCmd(0xFFFFFFFF, 1);
945  gen.joinThreads();
946  TLOG(TLVL_INFO) << "WindowMode_RequestEndsAfterBuffer test case END" ;
947 
948 }
949 BOOST_AUTO_TEST_CASE(WindowMode_RequestAfterBuffer)
950 {
951  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
952  TLOG(TLVL_INFO) << "WindowMode_RequestAfterBuffer test case BEGIN" ;
953  const int REQUEST_PORT = (seedAndRandom() % (32768 - 1024)) + 1024;
954  const int DELAY_TIME = 100;
955  fhicl::ParameterSet ps;
956  ps.put<int>("board_id", 1);
957  ps.put<int>("fragment_id", 1);
958  ps.put<int>("request_port", REQUEST_PORT);
959 #if MULTICAST_MODE
960  ps.put<std::string>("request_address", "227.18.12.32");
961 #else
962  ps.put<std::string>("request_address", "localhost");
963 #endif
964  ps.put<artdaq::Fragment::timestamp_t>("request_window_offset", 0);
965  ps.put<artdaq::Fragment::timestamp_t>("request_window_width", 3);
966  ps.put<size_t>("window_close_timeout_us", 500000);
967  ps.put<bool>("separate_data_thread", true);
968  ps.put<bool>("separate_monitoring_thread", false);
969  ps.put<int64_t>("hardware_poll_interval_us", 0);
970  ps.put<size_t>("data_buffer_depth_fragments", 5);
971  ps.put<std::string>("request_mode", "window");
972  ps.put("request_delay_ms", DELAY_TIME);
973  ps.put("send_requests", true);
974 
975  artdaq::RequestSender t(ps);
976 
978  gen.StartCmd(1, 0xFFFFFFFF, 1);
979 
980  artdaq::FragmentPtrs fps;
981  int sts;
982  artdaq::Fragment::type_t type;
983  gen.waitForFrags();
984 
985  // 6. Start and end after buffer
986  // -- Should not return until buffer passes end or timeout (check both cases). MissingData bit set if timeout
987  gen.setFireCount(9); // Buffer start is 6, end at 10
988  gen.waitForFrags();
989  t.AddRequest(1, 11); // Requesting data from ts 11 to 13
990 
991  sts = gen.getNext(fps);
992  BOOST_REQUIRE_EQUAL(sts, true);
993  BOOST_REQUIRE_EQUAL(fps.size(), 0);
994  gen.setFireCount(1); // Buffer start is 7, end at 11
995  gen.waitForFrags();
996  sts = gen.getNext(fps);
997  BOOST_REQUIRE_EQUAL(sts, true);
998  BOOST_REQUIRE_EQUAL(fps.size(), 0);
999 
1000  gen.setFireCount(3); // Buffer start is 10, end at 14
1001  gen.waitForFrags();
1002  sts = gen.getNext(fps);
1003  BOOST_REQUIRE_EQUAL(sts, true);
1004  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1005  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1006  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 11);
1007  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1008  type = artdaq::Fragment::ContainerFragmentType;
1009  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1010  auto cf = artdaq::ContainerFragment(*fps.front());
1011  BOOST_REQUIRE_EQUAL(cf.block_count(), 3);
1012  BOOST_REQUIRE_EQUAL(cf.missing_data(), false);
1013  type = artdaq::Fragment::FirstUserFragmentType;
1014  BOOST_REQUIRE_EQUAL(cf.fragment_type(), type);
1015  fps.clear();
1016 
1017  t.AddRequest(2, 16); // Requesting data from ts 15 to 17
1018  sts = gen.getNext(fps);
1019  BOOST_REQUIRE_EQUAL(sts, true);
1020  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1021 
1022  usleep(550000);
1023 
1024  sts = gen.getNext(fps);
1025  BOOST_REQUIRE_EQUAL(sts, true);
1026  BOOST_REQUIRE_EQUAL(fps.size(), 1);
1027  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1028  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 16);
1029  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 2);
1030  type = artdaq::Fragment::ContainerFragmentType;
1031  BOOST_REQUIRE_EQUAL(fps.front()->type(), type);
1032  auto cf4 = artdaq::ContainerFragment(*fps.front());
1033  BOOST_REQUIRE_EQUAL(cf4.block_count(), 0);
1034  BOOST_REQUIRE_EQUAL(cf4.missing_data(), true);
1035  type = artdaq::Fragment::EmptyFragmentType;
1036  BOOST_REQUIRE_EQUAL(cf4.fragment_type(), type);
1037 
1038  gen.StopCmd(0xFFFFFFFF, 1);
1039  gen.joinThreads();
1040  TLOG(TLVL_INFO) << "WindowMode_RequestAfterBuffer test case END" ;
1041 
1042 }
1043 
1044 BOOST_AUTO_TEST_CASE(HardwareFailure_NonThreaded)
1045 {
1046  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1047  TLOG(TLVL_INFO) << "HardwareFailure_NonThreaded test case BEGIN" ;
1048  fhicl::ParameterSet ps;
1049  ps.put<int>("board_id", 1);
1050  ps.put<int>("fragment_id", 1);
1051  ps.put<bool>("separate_data_thread", false);
1052  ps.put<bool>("separate_monitoring_thread", false);
1053  ps.put<int64_t>("hardware_poll_interval_us", 10);
1054 
1056  gen.StartCmd(1, 0xFFFFFFFF, 1);
1057 
1058  artdaq::FragmentPtrs fps;
1059  auto sts = gen.getNext(fps);
1060  BOOST_REQUIRE_EQUAL(sts, true);
1061  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
1062  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1063  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1064  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1065  fps.clear();
1066 
1067  gen.setFireCount(1);
1068  gen.setHwFail();
1069  usleep(10000);
1070  sts = gen.getNext(fps);
1071  BOOST_REQUIRE_EQUAL(sts, false);
1072  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1073 
1074  gen.StopCmd(0xFFFFFFFF, 1);
1075  gen.joinThreads();
1076  TLOG(TLVL_INFO) << "HardwareFailure_NonThreaded test case END" ;
1077 }
1078 
1079 BOOST_AUTO_TEST_CASE(HardwareFailure_Threaded)
1080 {
1081  artdaq::configureMessageFacility("CommandableFragmentGenerator_t");
1082  TLOG(TLVL_INFO) << "HardwareFailure_Threaded test case BEGIN" ;
1083  fhicl::ParameterSet ps;
1084  ps.put<int>("board_id", 1);
1085  ps.put<int>("fragment_id", 1);
1086  ps.put<bool>("separate_data_thread", true);
1087  ps.put<bool>("separate_monitoring_thread", true);
1088  ps.put<int64_t>("hardware_poll_interval_us", 750000);
1089 
1091  gen.StartCmd(1, 0xFFFFFFFF, 1);
1092 
1093 
1094 
1095  artdaq::FragmentPtrs fps;
1096  auto sts = gen.getNext(fps);
1097  BOOST_REQUIRE_EQUAL(sts, true);
1098  BOOST_REQUIRE_EQUAL(fps.size(), 1u);
1099  BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1100  BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 1);
1101  BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1102  fps.clear();
1103 
1104  gen.setHwFail();
1105  //gen.setFireCount(1);
1106  //sts = gen.getNext(fps);
1107  //BOOST_REQUIRE_EQUAL(sts, true);
1108  //BOOST_REQUIRE_EQUAL(fps.size(), 1);
1109  //BOOST_REQUIRE_EQUAL(fps.front()->fragmentID(), 1);
1110  //BOOST_REQUIRE_EQUAL(fps.front()->timestamp(), 2);
1111  //BOOST_REQUIRE_EQUAL(fps.front()->sequenceID(), 1);
1112  //fps.clear();
1113 
1114  sleep(1);
1115 
1116  gen.setFireCount(1);
1117  sts = gen.getNext(fps);
1118  BOOST_REQUIRE_EQUAL(sts, false);
1119  BOOST_REQUIRE_EQUAL(fps.size(), 0);
1120 
1121  gen.StopCmd(0xFFFFFFFF, 1);
1122  gen.joinThreads();
1123  TLOG(TLVL_INFO) << "HardwareFailure_Threaded test case END" ;
1124 }
1125 
1126 BOOST_AUTO_TEST_SUITE_END()
bool getNext_(artdaq::FragmentPtrs &frags) override
Generate data and return it to CommandableFragmentGenerator.
CommandableFragmentGenerator derived class for testing.
The RequestSender contains methods used to send data requests and Routing tokens. ...
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...
bool checkHWStatus_() override
Returns whether the hwFail flag has not been set.
void stopNoMutex() override
Perform immediate stop actions. No-Op.
void start() override
Perform start actions. No-Op.
CommandableFragmentGenerator is a FragmentGenerator-derived abstract class that defines the interface...
void resume() override
Perform resume actions. No-Op.
void pause() override
Perform pause actions. No-Op.
size_t ev_counter() const
Get the current value of the event counter.
std::map< Fragment::sequence_id_t, std::chrono::steady_clock::time_point > getOutOfOrderWindowList() const
Access the windows_sent_ooo_ map.
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.