artdaq_core  v3_06_11
Fragment_t.cc
1 #include "artdaq-core/Data/Fragment.hh"
2 #include "artdaq-core/Data/detail/RawFragmentHeader.hh"
3 
4 #define BOOST_TEST_MODULE(Fragment_t)
5 #include <cetlib/quiet_unit_test.hpp>
6 
11 {
12  uint64_t field1;
13  uint32_t field2;
14  uint32_t field3;
15 };
16 
21 {
22  uint64_t field1;
23  uint32_t field2;
24  uint32_t field3;
25  uint64_t field4;
26  uint16_t field5;
27 };
28 
33 {
34  uint64_t fields[300];
35 };
36 
37 BOOST_AUTO_TEST_SUITE(Fragment_test)
38 
39 BOOST_AUTO_TEST_CASE(Construct)
40 {
41  // 01-Mar-2013, KAB - I'm constructing these tests based on the
42  // constructors that I already see in the class, but I have to
43  // wonder if these truly correspond to the behavior that we want.
45  BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)0);
46  BOOST_REQUIRE_EQUAL(f1.size(), (size_t)artdaq::detail::RawFragmentHeader::num_words());
51  BOOST_REQUIRE_EQUAL(f1.hasMetadata(), false);
52 
53  artdaq::Fragment f2(7);
54  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)7);
55  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)artdaq::detail::RawFragmentHeader::num_words() + 7);
57  BOOST_REQUIRE(f2.type() == artdaq::Fragment::InvalidFragmentType);
58  BOOST_REQUIRE(f2.sequenceID() == artdaq::Fragment::InvalidSequenceID);
59  BOOST_REQUIRE(f2.fragmentID() == artdaq::Fragment::InvalidFragmentID);
60  BOOST_REQUIRE_EQUAL(f2.hasMetadata(), false);
61 
62  artdaq::Fragment f3(101, 202);
63  BOOST_REQUIRE_EQUAL(f3.dataSize(), (size_t)0);
64  BOOST_REQUIRE_EQUAL(f3.size(), (size_t)artdaq::detail::RawFragmentHeader::num_words());
66  BOOST_REQUIRE(f3.type() == artdaq::Fragment::DataFragmentType);
67  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (artdaq::Fragment::sequence_id_t)101);
68  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (artdaq::Fragment::fragment_id_t)202);
69  BOOST_REQUIRE_EQUAL(f3.hasMetadata(), false);
70 
71  std::vector<artdaq::RawDataType> d{1, 2, 3};
72  auto f4 = artdaq::Fragment::dataFrag(101, 202, &d[0], 3);
73  BOOST_REQUIRE_EQUAL(f4->dataSize(), (size_t)3);
74  BOOST_REQUIRE_EQUAL(f4->size(), (size_t)artdaq::detail::RawFragmentHeader::num_words() + 3);
76  BOOST_REQUIRE(f4->type() == artdaq::Fragment::DataFragmentType);
77  BOOST_REQUIRE_EQUAL(f4->sequenceID(), (artdaq::Fragment::sequence_id_t)101);
78  BOOST_REQUIRE_EQUAL(f4->fragmentID(), (artdaq::Fragment::fragment_id_t)202);
79  BOOST_REQUIRE_EQUAL(f4->hasMetadata(), false);
80 
81  // Verify that only "user" fragment types may be specified
82  // in the constructor
83  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 0), cet::exception);
84  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 225), cet::exception);
85  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 255), cet::exception);
86  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::Fragment::InvalidFragmentType), cet::exception);
87  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::detail::RawFragmentHeader::FIRST_SYSTEM_TYPE), cet::exception);
88  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::detail::RawFragmentHeader::LAST_SYSTEM_TYPE), cet::exception);
89 
94  artdaq::Fragment fragC(101, 202, 1);
95  artdaq::Fragment fragD(101, 202, 2);
96  artdaq::Fragment fragE(101, 202, 3);
97  artdaq::Fragment fragF(101, 202, 100);
98  artdaq::Fragment fragG(101, 202, 200);
99  artdaq::Fragment fragH(101, 202, 224);
100 
101  TLOG(TLVL_INFO) << "Example Fragment: " << f1;
102  BOOST_REQUIRE_EQUAL(f1.typeString(), "0");
103 }
104 
105 BOOST_AUTO_TEST_CASE(FragmentType)
106 {
107  artdaq::Fragment frag(15);
108 
109  // test "user" fragment types
110  BOOST_REQUIRE_THROW(frag.setUserType(0), cet::exception);
111  BOOST_REQUIRE_THROW(frag.setUserType(225), cet::exception);
112  BOOST_REQUIRE_THROW(frag.setUserType(255), cet::exception);
113  BOOST_REQUIRE_THROW(frag.setUserType(artdaq::Fragment::InvalidFragmentType), cet::exception);
114  BOOST_REQUIRE_THROW(frag.setUserType(artdaq::detail::RawFragmentHeader::FIRST_SYSTEM_TYPE), cet::exception);
115  BOOST_REQUIRE_THROW(frag.setUserType(artdaq::detail::RawFragmentHeader::LAST_SYSTEM_TYPE), cet::exception);
116 
119  frag.setUserType(1);
120  frag.setUserType(2);
121  frag.setUserType(3);
122  frag.setUserType(100);
123  frag.setUserType(200);
124  frag.setUserType(224);
125 
126  // test "system" fragment types
127  BOOST_REQUIRE_THROW(frag.setSystemType(0), cet::exception);
128  BOOST_REQUIRE_THROW(frag.setSystemType(1), cet::exception);
129  BOOST_REQUIRE_THROW(frag.setSystemType(224), cet::exception);
130  BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::Fragment::InvalidFragmentType), cet::exception);
131  BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::detail::RawFragmentHeader::FIRST_USER_TYPE), cet::exception);
132  BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::detail::RawFragmentHeader::LAST_USER_TYPE), cet::exception);
133 
136  frag.setSystemType(225);
137  frag.setSystemType(230);
138  frag.setSystemType(240);
139  frag.setSystemType(250);
140  frag.setSystemType(255);
141 
143  BOOST_REQUIRE(map.size() > 0);
145  BOOST_REQUIRE(map.size() > 0);
146 }
147 
148 BOOST_AUTO_TEST_CASE(SequenceID)
149 {
150  artdaq::Fragment f1;
151  f1.setSequenceID(0);
152  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0);
153  f1.setSequenceID(1);
154  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)1);
155  f1.setSequenceID(0xffff);
156  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0xffff);
157  f1.setSequenceID(0x0000ffffffffffff);
158  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0x0000ffffffffffff);
159 
160  artdaq::Fragment f2(0x12345, 0xab);
161  BOOST_REQUIRE_EQUAL(f2.sequenceID(), (uint64_t)0x12345);
162 
163  artdaq::Fragment f3(0x0000567812345678, 0xab);
164  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint64_t)0x0000567812345678);
165 }
166 
167 BOOST_AUTO_TEST_CASE(FragmentID)
168 {
169  artdaq::Fragment f1;
170  f1.setFragmentID(0);
171  BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)0);
172  f1.setFragmentID(1);
173  BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)1);
174  f1.setFragmentID(0xffff);
175  BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)0xffff);
176 
177  artdaq::Fragment f2(0x12345, 0xab);
178  BOOST_REQUIRE_EQUAL(f2.fragmentID(), (uint16_t)0xab);
179 
180  artdaq::Fragment f3(0x0000567812345678, 0xffff);
181  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xffff);
182 }
183 
184 BOOST_AUTO_TEST_CASE(Resize)
185 {
186  // basic fragment
187  artdaq::Fragment f1;
188  f1.resize(1234);
189  BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)1234);
190  BOOST_REQUIRE_EQUAL(f1.size(), (size_t)1234 +
192 
193  // fragment with metadata
194  MetadataTypeOne mdOneA;
195  artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
196  f2.resize(129);
197  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)129);
198  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)129 + 2 +
200 }
201 
202 BOOST_AUTO_TEST_CASE(Empty)
203 {
204  artdaq::Fragment f1;
205  BOOST_REQUIRE_EQUAL(f1.empty(), true);
206  f1.resize(1234);
207  BOOST_REQUIRE_EQUAL(f1.empty(), false);
208 
209  MetadataTypeOne mdOneA;
210  artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
211  BOOST_REQUIRE_EQUAL(f2.empty(), false);
212  f2.resize(129);
213  BOOST_REQUIRE_EQUAL(f2.empty(), false);
214  f2.resize(0);
215  BOOST_REQUIRE_EQUAL(f2.empty(), true);
216  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)0);
217  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)2 +
219 
220  artdaq::Fragment f3;
221  BOOST_REQUIRE_EQUAL(f3.empty(), true);
222  f3.setMetadata(mdOneA);
223  BOOST_REQUIRE_EQUAL(f3.empty(), true);
224 
225  artdaq::Fragment f4(14);
226  BOOST_REQUIRE_EQUAL(f4.empty(), false);
227  f4.setMetadata(mdOneA);
228  BOOST_REQUIRE_EQUAL(f4.empty(), false);
229 }
230 
231 BOOST_AUTO_TEST_CASE(Clear)
232 {
233  artdaq::Fragment f1;
234  BOOST_REQUIRE_EQUAL(f1.empty(), true);
235  f1.resize(1234);
236  BOOST_REQUIRE_EQUAL(f1.empty(), false);
237  f1.clear();
238  BOOST_REQUIRE_EQUAL(f1.empty(), true);
239 
240  MetadataTypeOne mdOneA;
241  artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
242  BOOST_REQUIRE_EQUAL(f2.empty(), false);
243  f2.resize(129);
244  BOOST_REQUIRE_EQUAL(f2.empty(), false);
245  f2.clear();
246  BOOST_REQUIRE_EQUAL(f2.empty(), true);
247  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)0);
248  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)2 +
250 
251  artdaq::Fragment f3;
252  BOOST_REQUIRE_EQUAL(f3.empty(), true);
253  BOOST_REQUIRE_EQUAL(f3.hasMetadata(), false);
254  f3.setMetadata(mdOneA);
255  BOOST_REQUIRE_EQUAL(f3.empty(), true);
256  BOOST_REQUIRE_EQUAL(f3.hasMetadata(), true);
257  f3.clear();
258  BOOST_REQUIRE_EQUAL(f3.empty(), true);
259  BOOST_REQUIRE_EQUAL(f3.hasMetadata(), true);
260 
261  artdaq::Fragment f4(14);
262  BOOST_REQUIRE_EQUAL(f4.empty(), false);
263  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), false);
264  f4.setMetadata(mdOneA);
265  BOOST_REQUIRE_EQUAL(f4.empty(), false);
266  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), true);
267  f4.clear();
268  BOOST_REQUIRE_EQUAL(f4.empty(), true);
269  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), true);
270 }
271 
272 BOOST_AUTO_TEST_CASE(Addresses)
273 {
274  // no metadata
275  artdaq::Fragment f1(200);
276  BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)200);
277  BOOST_REQUIRE_EQUAL(f1.size(), (size_t)200 +
279  artdaq::RawDataType* haddr = f1.headerAddress();
280  artdaq::RawDataType* daddr = f1.dataAddress();
281  BOOST_REQUIRE_EQUAL(daddr,
282  (haddr + artdaq::detail::RawFragmentHeader::num_words())); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
283 
284  BOOST_REQUIRE_THROW(f1.metadataAddress(), cet::exception);
285 
286  BOOST_REQUIRE_EQUAL(haddr, &(*(f1.headerBegin())));
287  BOOST_REQUIRE_EQUAL(daddr, &(*(f1.dataBegin())));
288  BOOST_REQUIRE_EQUAL(daddr + 200, &(*(f1.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
289 
290  // Const versions
291  const artdaq::Fragment cf1(f1);
292  BOOST_REQUIRE_EQUAL(cf1.dataSize(), (size_t)200);
293  BOOST_REQUIRE_EQUAL(cf1.size(), (size_t)200 +
295  const artdaq::RawDataType* chaddr = cf1.headerBegin();
296  const artdaq::RawDataType* cdaddr = cf1.dataBegin();
297  BOOST_REQUIRE_EQUAL(cdaddr,
298  (chaddr + artdaq::detail::RawFragmentHeader::num_words())); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
299 
300  BOOST_REQUIRE_EQUAL(cdaddr + 200, &(*(cf1.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
301 
302  // metadata with integer number of longwords
303  MetadataTypeOne mdOneA;
304  artdaq::Fragment f2(135, 101, 0, 3, mdOneA);
305  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)135);
306  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)135 + 2 +
308  haddr = f2.headerAddress();
309  daddr = f2.dataAddress();
310  artdaq::RawDataType* maddr = f2.metadataAddress();
311  BOOST_REQUIRE_EQUAL(maddr, haddr + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
313  BOOST_REQUIRE_EQUAL(daddr, maddr + 2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
314  BOOST_REQUIRE_EQUAL(haddr, &(*(f2.headerBegin())));
315  BOOST_REQUIRE_EQUAL(daddr, &(*(f2.dataBegin())));
316  BOOST_REQUIRE_EQUAL(daddr + 135, &(*(f2.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
317 
318  // metadata with fractional number of longwords
319  MetadataTypeTwo mdTwoA;
320  artdaq::Fragment f3(77, 101, 0, 3, mdTwoA);
321  BOOST_REQUIRE_EQUAL(f3.dataSize(), (size_t)77);
322  BOOST_REQUIRE_EQUAL(f3.size(), (size_t)77 + 4 + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
324  haddr = f3.headerAddress();
325  daddr = f3.dataAddress();
326  maddr = f3.metadataAddress();
327  BOOST_REQUIRE_EQUAL(maddr, haddr + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
329  BOOST_REQUIRE_EQUAL(daddr, maddr + 4); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
330  BOOST_REQUIRE_EQUAL(haddr, &(*(f3.headerBegin())));
331  BOOST_REQUIRE_EQUAL(daddr, &(*(f3.dataBegin())));
332  BOOST_REQUIRE_EQUAL(daddr + 77, &(*(f3.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
333 }
334 
335 BOOST_AUTO_TEST_CASE(Metadata)
336 {
337  artdaq::Fragment f1(42);
338  BOOST_REQUIRE_EQUAL(f1.hasMetadata(), false);
339 
340  BOOST_REQUIRE_THROW(f1.metadata<MetadataTypeOne>(), cet::exception);
341 
342  MetadataTypeOne mdOneA;
343  mdOneA.field1 = 5;
344  mdOneA.field2 = 10;
345  mdOneA.field3 = 15;
346 
347  BOOST_REQUIRE_THROW(f1.updateMetadata(mdOneA), cet::exception);
348 
349  f1.setMetadata(mdOneA);
350  auto* mdOnePtr = f1.metadata<MetadataTypeOne>();
351  BOOST_REQUIRE_EQUAL(mdOnePtr->field1, (uint64_t)5);
352  BOOST_REQUIRE_EQUAL(mdOnePtr->field2, (uint32_t)10);
353  BOOST_REQUIRE_EQUAL(mdOnePtr->field3, (uint32_t)15);
354 
355  MetadataTypeOne mdOneB;
356  BOOST_REQUIRE_THROW(f1.setMetadata(mdOneB), cet::exception);
357 
358  f1.updateMetadata(*mdOnePtr);
359 
360  MetadataTypeTwo mdTwoA;
361  mdTwoA.field1 = 10;
362  mdTwoA.field2 = 20;
363  mdTwoA.field3 = 30;
364  mdTwoA.field4 = 40;
365  mdTwoA.field5 = 50;
366 
367  BOOST_REQUIRE_THROW(f1.updateMetadata(mdTwoA), cet::exception);
368 
369  artdaq::Fragment f2(10, 1, 2, 3, mdTwoA);
370  auto* mdTwoPtr = f2.metadata<MetadataTypeTwo>();
371  BOOST_REQUIRE_EQUAL(mdTwoPtr->field1, (uint64_t)10);
372  BOOST_REQUIRE_EQUAL(mdTwoPtr->field2, (uint32_t)20);
373  BOOST_REQUIRE_EQUAL(mdTwoPtr->field3, (uint32_t)30);
374  BOOST_REQUIRE_EQUAL(mdTwoPtr->field4, (uint32_t)40);
375  BOOST_REQUIRE_EQUAL(mdTwoPtr->field5, (uint32_t)50);
376 
377  artdaq::Fragment f3(0xabcdef, 0xc3a5, 123);
378  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
379  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
380  BOOST_REQUIRE_EQUAL(f3.type(), (uint16_t)123);
381  f3.resize(5);
382  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
383  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
384  BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
385  artdaq::RawDataType* dataPtr = f3.dataAddress();
386  dataPtr[0] = 0x12345678; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
387  dataPtr[1] = 0xabcd; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
388  dataPtr[2] = 0x456789ab; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
389  dataPtr[3] = 0x3c3c3c3c; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
390  dataPtr[4] = 0x5a5a5a5a; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
391  BOOST_REQUIRE_EQUAL(dataPtr[0], (uint64_t)0x12345678); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
392  BOOST_REQUIRE_EQUAL(dataPtr[1], (uint64_t)0xabcd); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
393  BOOST_REQUIRE_EQUAL(dataPtr[2], (uint64_t)0x456789ab); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
394  BOOST_REQUIRE_EQUAL(dataPtr[3], (uint64_t)0x3c3c3c3c); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
395  BOOST_REQUIRE_EQUAL(dataPtr[4], (uint64_t)0x5a5a5a5a); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
396  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
397  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
398  BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
399  MetadataTypeOne mdOneC;
400  mdOneC.field1 = 505;
401  mdOneC.field2 = 510;
402  mdOneC.field3 = 515;
403  f3.setMetadata(mdOneC);
404  mdOnePtr = f3.metadata<MetadataTypeOne>();
405  BOOST_REQUIRE_EQUAL(mdOnePtr->field1, (uint64_t)505);
406  BOOST_REQUIRE_EQUAL(mdOnePtr->field2, (uint32_t)510);
407  BOOST_REQUIRE_EQUAL(mdOnePtr->field3, (uint32_t)515);
408  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
409  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
410  BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
411  dataPtr = f3.dataAddress();
412  dataPtr[0] = 0x12345678; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
413  dataPtr[1] = 0xabcd; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
414  dataPtr[2] = 0x456789ab; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
415  dataPtr[3] = 0x3c3c3c3c; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
416  dataPtr[4] = 0x5a5a5a5a; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
417  BOOST_REQUIRE_EQUAL(dataPtr[0], (uint64_t)0x12345678); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
418  BOOST_REQUIRE_EQUAL(dataPtr[1], (uint64_t)0xabcd); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
419  BOOST_REQUIRE_EQUAL(dataPtr[2], (uint64_t)0x456789ab); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
420  BOOST_REQUIRE_EQUAL(dataPtr[3], (uint64_t)0x3c3c3c3c); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
421  BOOST_REQUIRE_EQUAL(dataPtr[4], (uint64_t)0x5a5a5a5a); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
422 
423  MetadataTypeHuge mdHuge;
424  artdaq::Fragment f4(19);
425  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), false);
426 
427  BOOST_REQUIRE_THROW(f4.setMetadata(mdHuge), cet::exception);
428 
429  BOOST_REQUIRE_THROW(artdaq::Fragment f5(127, 1, 2, 3, mdHuge), cet::exception);
430 }
431 
432 // JCF, 4/15/14 -- perform a set of tests concerning the new
433 // byte-by-byte interface functions added to artdaq::Fragment
434 
435 BOOST_AUTO_TEST_CASE(Bytes)
436 {
437  std::size_t payload_size = 5;
438 
439  // seqID, fragID, type are all random
442  artdaq::Fragment::type_t type = 3;
443 
444  // No explicit constructor necessary for Metadata -- all we care
445  // about is its size in the artdaq::Fragment, not its values
446 
447  struct Metadata
448  {
449  uint8_t byteOne;
450  uint8_t byteTwo;
451  uint8_t byteThree;
452  };
453 
454  Metadata theMetadata;
455 
456  BOOST_REQUIRE(sizeof(artdaq::Fragment::byte_t) == 1);
457 
458  // Assumption in some of the arithmetic below is that RawDataType is 8 bytes
459  BOOST_REQUIRE(sizeof(artdaq::RawDataType) == 8);
460 
461  // Check that the factory function and the explicit constructor
462  // methods of creating a fragment yield identical results IF the
463  // number of bytes passed to FragmentBytes() is a multiple of the
464  // size of the RawDataType
465 
466  std::unique_ptr<artdaq::Fragment> f1(new artdaq::Fragment(payload_size));
467  std::unique_ptr<artdaq::Fragment> f1_factory(artdaq::Fragment::FragmentBytes(
468  payload_size * sizeof(artdaq::RawDataType)));
469 
470  BOOST_REQUIRE(f1->size() == f1_factory->size());
471  BOOST_REQUIRE(f1->sizeBytes() == f1_factory->sizeBytes());
472 
473  std::unique_ptr<artdaq::Fragment> f2(new artdaq::Fragment(payload_size, seqID, fragID, type, theMetadata));
474  std::unique_ptr<artdaq::Fragment> f2_factory(artdaq::Fragment::FragmentBytes(
475  payload_size * sizeof(artdaq::RawDataType),
476  seqID, fragID,
477  type, theMetadata));
478 
479  BOOST_REQUIRE(f2->size() == f2_factory->size());
480  BOOST_REQUIRE(f2->sizeBytes() == f2_factory->sizeBytes());
481 
482  // Now let's make sure that data gets aligned as expected (i.e.,
483  // along boundaries separated by sizeof(RawDataType) bytes)
484 
485  std::size_t offset = 3;
486  std::unique_ptr<artdaq::Fragment> f3_factory(artdaq::Fragment::FragmentBytes(
487  payload_size * sizeof(artdaq::RawDataType) - offset,
488  seqID, fragID,
489  type, theMetadata));
490 
491  BOOST_REQUIRE(f3_factory->size() == f2->size());
492  BOOST_REQUIRE(f3_factory->sizeBytes() == f2->sizeBytes());
493 
494  // Make certain dataBegin(), dataBeginBytes() and the
495  // (now-deprecated, but still in legacy code) dataAddress() point to
496  // the same region in memory, i.e., the start of the payload
497 
498  auto* hdrptr = reinterpret_cast<artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
499  &*f3_factory->headerBegin());
500  BOOST_REQUIRE_EQUAL(&*f3_factory->headerBeginBytes(), hdrptr);
501 
502  auto* ptr1 = reinterpret_cast<artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
503  &*f3_factory->dataBegin());
504 
505  artdaq::Fragment::byte_t* ptr2 = f3_factory->dataBeginBytes();
506 
507  auto* ptr3 = reinterpret_cast<artdaq::Fragment::byte_t*>(f3_factory->dataAddress()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
508 
509  BOOST_REQUIRE_EQUAL(ptr1, ptr2);
510  BOOST_REQUIRE_EQUAL(ptr2, ptr3);
511 
512  auto* dataEndPtr = reinterpret_cast<artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
513  &*f3_factory->dataEnd());
514  BOOST_REQUIRE_EQUAL(&*f3_factory->dataEndBytes(), dataEndPtr);
515 
516  // Check const versions, too
517  const artdaq::Fragment f3_copy(*f3_factory);
518  auto chdrptr = reinterpret_cast<const artdaq::Fragment::byte_t*>(f3_copy.headerBegin()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
519  BOOST_REQUIRE_EQUAL(&*f3_copy.headerBeginBytes(), chdrptr);
520  auto* cptr1 = reinterpret_cast<const artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
521  &*f3_copy.dataBegin());
522 
523  const artdaq::Fragment::byte_t* cptr2 = f3_copy.dataBeginBytes();
524 
525  BOOST_REQUIRE_EQUAL(cptr1, cptr2);
526 
527  auto* cdataEndPtr = reinterpret_cast<const artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
528  &*f3_copy.dataEnd());
529  BOOST_REQUIRE_EQUAL(&*f3_copy.dataEndBytes(), cdataEndPtr);
530 
531  // Make sure metadata struct gets aligned
532  // header == 3 RawDataTypes, metadata is 3 bytes (rounds up to 1 RawDataType)
533  std::size_t const metadata_size =
534  f3_factory->dataBeginBytes() - reinterpret_cast<artdaq::Fragment::byte_t*>(&*f3_factory->headerBegin()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
535  BOOST_REQUIRE(metadata_size ==
537 
538  // Sanity check for the payload size
539  BOOST_REQUIRE(static_cast<std::size_t>(f3_factory->dataEndBytes() - f3_factory->dataBeginBytes()) == f3_factory->dataSizeBytes()); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
540 
541  // Check resizing
542  artdaq::Fragment f4(payload_size);
543  BOOST_REQUIRE_EQUAL(f4.dataSize(), payload_size);
544  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), (payload_size * sizeof(artdaq::RawDataType)));
545  f4.resize(payload_size + 1);
546  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 1));
547  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 1) * sizeof(artdaq::RawDataType)));
548  f4.resizeBytes(f4.dataSizeBytes() + 2);
549  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 2));
550  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 2) * sizeof(artdaq::RawDataType)));
551  f4.resizeBytes(f4.dataSizeBytes() + 1);
552  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 3));
553  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 3) * sizeof(artdaq::RawDataType)));
554  f4.resizeBytes(f4.dataSizeBytes() + 1);
555  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 4));
556  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 4) * sizeof(artdaq::RawDataType)));
557 
558  size_t targetSize = (payload_size + 4) * sizeof(artdaq::RawDataType);
559  ++targetSize;
560  f4.resizeBytes(targetSize);
561  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
562  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
563  ++targetSize;
564  f4.resizeBytes(targetSize);
565  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
566  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
567  ++targetSize;
568  f4.resizeBytes(targetSize);
569  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
570  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
571  ++targetSize;
572  f4.resizeBytes(targetSize);
573  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
574  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
575  ++targetSize;
576  f4.resizeBytes(targetSize);
577  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
578  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
579  ++targetSize;
580  f4.resizeBytes(targetSize);
581  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
582  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
583  ++targetSize;
584  f4.resizeBytes(targetSize);
585  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
586  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
587  ++targetSize;
588  f4.resizeBytes(targetSize);
589  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
590  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
591  ++targetSize;
592  f4.resizeBytes(targetSize);
593  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 6));
594  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 6) * sizeof(artdaq::RawDataType)));
595 
596  // Check adding metadata after construction
597  artdaq::Fragment f5(payload_size);
598  BOOST_REQUIRE_EQUAL(f5.size(), (payload_size + artdaq::detail::RawFragmentHeader::num_words()));
599  BOOST_REQUIRE_EQUAL(f5.sizeBytes(), ((payload_size + artdaq::detail::RawFragmentHeader::num_words()) * sizeof(artdaq::RawDataType)));
600  f5.setMetadata(theMetadata);
601  BOOST_REQUIRE_EQUAL(f5.dataSize(), payload_size);
602  BOOST_REQUIRE_EQUAL(f5.dataSizeBytes(), (payload_size * sizeof(artdaq::RawDataType)));
603  BOOST_REQUIRE_EQUAL(f5.size(), (payload_size + 1 + artdaq::detail::RawFragmentHeader::num_words()));
604  BOOST_REQUIRE_EQUAL(f5.sizeBytes(), ((payload_size + 1 + artdaq::detail::RawFragmentHeader::num_words()) * sizeof(artdaq::RawDataType)));
605 }
606 
607 BOOST_AUTO_TEST_CASE(Upgrade_V0)
608 {
609  artdaq::Fragment f(7);
611 
613  hdr0.version = 0;
614  hdr0.type = 0xFE;
615  hdr0.metadata_word_count = 0;
616 
617  hdr0.sequence_id = 0xFEEDDEADBEEF;
618  hdr0.fragment_id = 0xBEE7;
619  hdr0.timestamp = 0xCAFEFECA;
620 
621  hdr0.unused1 = 0xF0F0;
622  hdr0.unused2 = 0xC5C5;
623 
624  memcpy(f.headerBeginBytes(), &hdr0, sizeof(hdr0));
625 
628  {
629  memcpy(f.headerBegin() + ii, &(++counter), sizeof(counter));
630  }
631 
632  BOOST_REQUIRE_EQUAL(f.version(), 0);
633  BOOST_REQUIRE_EQUAL(f.type(), 0xFE);
634  BOOST_REQUIRE_EQUAL(f.hasMetadata(), false);
635 
636  BOOST_REQUIRE_EQUAL(f.sequenceID(), 0xFEEDDEADBEEF);
637  BOOST_REQUIRE_EQUAL(f.fragmentID(), 0xBEE7);
638  BOOST_REQUIRE_EQUAL(f.timestamp(), 0xCAFEFECA);
639 
640  for (size_t jj = 0; jj < f.dataSize(); ++jj)
641  {
642  BOOST_REQUIRE_EQUAL(*(f.dataBegin() + jj), jj + 1);
643  }
644 }
645 
646 BOOST_AUTO_TEST_CASE(Upgrade_V1)
647 {
648  artdaq::Fragment f(7);
650 
652  hdr1.version = 1;
653  hdr1.type = 0xFE;
654  hdr1.metadata_word_count = 0;
655 
656  hdr1.sequence_id = 0xFEEDDEADBEEF;
657  hdr1.fragment_id = 0xBEE7;
658  hdr1.timestamp = 0xCAFEFECAAAAABBBB;
659 
660  memcpy(f.headerBeginBytes(), &hdr1, sizeof(hdr1));
661 
664  {
665  memcpy(f.headerBegin() + ii, &(++counter), sizeof(counter));
666  }
667 
668  BOOST_REQUIRE_EQUAL(f.version(), 1);
669  BOOST_REQUIRE_EQUAL(f.type(), 0xFE);
670  BOOST_REQUIRE_EQUAL(f.hasMetadata(), false);
671 
672  BOOST_REQUIRE_EQUAL(f.sequenceID(), 0xFEEDDEADBEEF);
673  BOOST_REQUIRE_EQUAL(f.fragmentID(), 0xBEE7);
674  BOOST_REQUIRE_EQUAL(f.timestamp(), 0xCAFEFECAAAAABBBB);
675 
676  for (size_t jj = 0; jj < f.dataSize(); ++jj)
677  {
678  BOOST_REQUIRE_EQUAL(*(f.dataBegin() + jj), jj + 1); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
679  }
680 }
681 
682 BOOST_AUTO_TEST_SUITE_END()
RawDataType metadata_word_count
The number of RawDataType words in the user-defined metadata.
uint32_t field2
Definition: Fragment_t.cc:23
static constexpr type_t FIRST_SYSTEM_TYPE
The first system type.
static constexpr type_t InvalidFragmentType
Copy InvalidFragmentType from RawFragmentHeader.
Definition: Fragment.hh:147
uint32_t field2
Definition: Fragment_t.cc:13
void setSequenceID(sequence_id_t sequence_id)
Sets the Sequence ID of the Fragment.
Definition: Fragment.hh:895
uint16_t field5
Definition: Fragment_t.cc:26
Test Metadata with three fields in two long words.
Definition: Fragment_t.cc:10
The RawFragmentHeaderV0 class contains the basic fields used by artdaq for routing Fragment objects t...
RawDataType timestamp
The 64-bit timestamp field is the output of a user-defined clock used for building time-correlated ev...
static std::map< type_t, std::string > MakeSystemTypeMap()
Returns a map of the most-commonly used system types.
std::size_t size() const
Gets the size of the Fragment, from the Fragment header.
Definition: Fragment.hh:840
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
Test Metadata that is very large.
Definition: Fragment_t.cc:32
detail::RawFragmentHeader::fragment_id_t fragment_id_t
typedef for fragment_id_t from RawFragmentHeader
Definition: Fragment.hh:139
std::size_t sizeBytes() const
Size of vals_ vector ( header + (optional) metadata + payload) in bytes.
Definition: Fragment.hh:360
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
RawDataType type
The type of the fragment, either system or user-defined.
detail::RawFragmentHeader::type_t type_t
typedef for type_t from RawFragmentHeader
Definition: Fragment.hh:137
RawDataType timestamp
The 64-bit timestamp field is the output of a user-defined clock used for building time-correlated ev...
static FragmentPtr dataFrag(sequence_id_t sequenceID, fragment_id_t fragID, InputIterator i, InputIterator e)
Creates a Fragment, copying data from given location. 12-Apr-2013, KAB - this method is deprecated...
Definition: Fragment.hh:711
sequence_id_t sequenceID() const
Sequence ID of the Fragment, from the Fragment header.
Definition: Fragment.hh:865
static constexpr type_t DataFragmentType
Copy DataFragmentType from RawFragmentHeader.
Definition: Fragment.hh:149
uint8_t byte_t
For byte representation.
Definition: Fragment.hh:100
void resize(std::size_t sz)
Resize the data payload to hold sz RawDataType words.
Definition: Fragment.hh:1012
uint64_t field1
Definition: Fragment_t.cc:22
uint32_t field3
Definition: Fragment_t.cc:24
static constexpr fragment_id_t InvalidFragmentID
Copy InvalidFragmentID from RawFragmentHeader.
Definition: Fragment.hh:144
static constexpr type_t LAST_USER_TYPE
The last user-accessible type (types above this number are system types.
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
uint32_t field3
Definition: Fragment_t.cc:14
RawDataType fragment_id
The fragment_id uniquely identifies a particular piece of hardware within the artdaq system...
void setMetadata(const T &metadata)
Set the metadata in the Fragment to the contents of the specified structure. This throws an exception...
Definition: Fragment.hh:976
detail::RawFragmentHeader::version_t version_t
typedef for version_t from RawFragmentHeader
Definition: Fragment.hh:136
iterator headerBegin()
Return an iterator to the beginning of the header (should be used for serialization only: use setters...
Definition: Fragment.hh:1083
RawDataType sequence_id
The 48-bit sequence_id uniquely identifies events within the artdaq system.
iterator dataBegin()
Return an iterator to the beginning of the data payload (after header and metadata) ...
Definition: Fragment.hh:1070
bool empty()
Determines if the Fragment contains no data.
Definition: Fragment.hh:1115
static constexpr sequence_id_t InvalidSequenceID
Copy InvalidSequenceID from RawFragmentHeader.
Definition: Fragment.hh:143
uint64_t field1
Definition: Fragment_t.cc:12
void updateMetadata(const T &metadata)
Updates existing metadata with a new metadata object.
Definition: Fragment.hh:992
RawDataType type
The type of the fragment, either system or user-defined.
static constexpr type_t FIRST_USER_TYPE
The first user-accessible type.
type_t type() const
Type of the Fragment, from the Fragment header.
Definition: Fragment.hh:853
static std::map< type_t, std::string > MakeVerboseSystemTypeMap()
Returns a map of all system types.
RawDataType word_count
number of RawDataType words in this Fragment
RawDataType * dataAddress()
Returns a RawDataType pointer to the beginning of the payload.
Definition: Fragment.hh:1135
unsigned long long RawDataType
The RawDataType (currently an unsigned long long) is the basic unit of data representation within art...
T * metadata()
Return a pointer to the metadata. This throws an exception if the Fragment contains no metadata...
Definition: Fragment.hh:952
iterator dataEnd()
Return an iterator to the end of the data payload.
Definition: Fragment.hh:1077
static FragmentPtr FragmentBytes(std::size_t nbytes)
Create a Fragment using a static factory function rather than a constructor to allow for the function...
Definition: Fragment.hh:202
std::string typeString() const
Print the type of the Fragment.
Definition: Fragment.hh:859
RawDataType fragment_id
The fragment_id uniquely identifies a particular piece of hardware within the artdaq system...
detail::RawFragmentHeader::RawDataType RawDataType
The RawDataType (currently a 64-bit integer) is the basic unit of data representation within artdaq ...
Definition: Fragment.hh:40
RawDataType * metadataAddress()
Get the address of the metadata. For internal use only, use metadata() instead.
Definition: Fragment.hh:1142
void clear()
Removes all elements from the payload section of the Fragment.
Definition: Fragment.hh:1108
static const version_t CurrentVersion
The CurrentVersion field should be incremented whenever the RawFragmentHeader changes.
uint64_t field4
Definition: Fragment_t.cc:25
bool hasMetadata() const
Test whether this Fragment has metadata.
Definition: Fragment.hh:946
void setFragmentID(fragment_id_t fragment_id)
Sets the Fragment ID of the Fragment.
Definition: Fragment.hh:902
A Fragment contains the data from one piece of the DAQ system for one event The artdaq::Fragment is t...
Definition: Fragment.hh:85
static constexpr type_t LAST_SYSTEM_TYPE
The last system type.
RawDataType version
The version of the fragment. Currently always InvalidVersion.
Test Metadata with five fields, mixing field sizes.
Definition: Fragment_t.cc:20
RawDataType metadata_word_count
The number of RawDataType words in the user-defined metadata.
uint64_t fields[300]
300 long words
Definition: Fragment_t.cc:34
std::size_t dataSize() const
Return the number of RawDataType words in the data payload. This does not include the number of words...
Definition: Fragment.hh:939
The RawFragmentHeaderV1 class contains the basic fields used by artdaq for routing Fragment objects t...
RawDataType word_count
number of RawDataType words in this Fragment
detail::RawFragmentHeader::sequence_id_t sequence_id_t
typedef for sequence_id_t from RawFragmentHeader
Definition: Fragment.hh:138
RawDataType sequence_id
The 48-bit sequence_id uniquely identifies events within the artdaq system.
fragment_id_t fragmentID() const
Fragment ID of the Fragment, from the Fragment header.
Definition: Fragment.hh:871
RawDataType * headerAddress()
Gets the address of the header.
Definition: Fragment.hh:1153
version_t version() const
Version of the Fragment, from the Fragment header.
Definition: Fragment.hh:846
RawDataType version
The version of the fragment.