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