artdaq_core  v3_06_07
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  // Verify that only "user" fragment types may be specified
72  // in the constructor
73  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 0), cet::exception);
74  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 225), cet::exception);
75  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 255), cet::exception);
76  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::Fragment::InvalidFragmentType), cet::exception);
77  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::detail::RawFragmentHeader::FIRST_SYSTEM_TYPE), cet::exception);
78  BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::detail::RawFragmentHeader::LAST_SYSTEM_TYPE), cet::exception);
79 
84  artdaq::Fragment fragC(101, 202, 1);
85  artdaq::Fragment fragD(101, 202, 2);
86  artdaq::Fragment fragE(101, 202, 3);
87  artdaq::Fragment fragF(101, 202, 100);
88  artdaq::Fragment fragG(101, 202, 200);
89  artdaq::Fragment fragH(101, 202, 224);
90 }
91 
92 BOOST_AUTO_TEST_CASE(FragmentType)
93 {
94  artdaq::Fragment frag(15);
95 
96  // test "user" fragment types
97  BOOST_REQUIRE_THROW(frag.setUserType(0), cet::exception);
98  BOOST_REQUIRE_THROW(frag.setUserType(225), cet::exception);
99  BOOST_REQUIRE_THROW(frag.setUserType(255), cet::exception);
100  BOOST_REQUIRE_THROW(frag.setUserType(artdaq::Fragment::InvalidFragmentType), cet::exception);
101  BOOST_REQUIRE_THROW(frag.setUserType(artdaq::detail::RawFragmentHeader::FIRST_SYSTEM_TYPE), cet::exception);
102  BOOST_REQUIRE_THROW(frag.setUserType(artdaq::detail::RawFragmentHeader::LAST_SYSTEM_TYPE), cet::exception);
103 
106  frag.setUserType(1);
107  frag.setUserType(2);
108  frag.setUserType(3);
109  frag.setUserType(100);
110  frag.setUserType(200);
111  frag.setUserType(224);
112 
113  // test "system" fragment types
114  BOOST_REQUIRE_THROW(frag.setSystemType(0), cet::exception);
115  BOOST_REQUIRE_THROW(frag.setSystemType(1), cet::exception);
116  BOOST_REQUIRE_THROW(frag.setSystemType(224), cet::exception);
117  BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::Fragment::InvalidFragmentType), cet::exception);
118  BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::detail::RawFragmentHeader::FIRST_USER_TYPE), cet::exception);
119  BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::detail::RawFragmentHeader::LAST_USER_TYPE), cet::exception);
120 
123  frag.setSystemType(225);
124  frag.setSystemType(230);
125  frag.setSystemType(240);
126  frag.setSystemType(250);
127  frag.setSystemType(255);
128 
130  BOOST_REQUIRE(map.size() > 0);
132  BOOST_REQUIRE(map.size() > 0);
133 }
134 
135 BOOST_AUTO_TEST_CASE(SequenceID)
136 {
137  artdaq::Fragment f1;
138  f1.setSequenceID(0);
139  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0);
140  f1.setSequenceID(1);
141  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)1);
142  f1.setSequenceID(0xffff);
143  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0xffff);
144  f1.setSequenceID(0x0000ffffffffffff);
145  BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0x0000ffffffffffff);
146 
147  artdaq::Fragment f2(0x12345, 0xab);
148  BOOST_REQUIRE_EQUAL(f2.sequenceID(), (uint64_t)0x12345);
149 
150  artdaq::Fragment f3(0x0000567812345678, 0xab);
151  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint64_t)0x0000567812345678);
152 }
153 
154 BOOST_AUTO_TEST_CASE(FragmentID)
155 {
156  artdaq::Fragment f1;
157  f1.setFragmentID(0);
158  BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)0);
159  f1.setFragmentID(1);
160  BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)1);
161  f1.setFragmentID(0xffff);
162  BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)0xffff);
163 
164  artdaq::Fragment f2(0x12345, 0xab);
165  BOOST_REQUIRE_EQUAL(f2.fragmentID(), (uint16_t)0xab);
166 
167  artdaq::Fragment f3(0x0000567812345678, 0xffff);
168  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xffff);
169 }
170 
171 BOOST_AUTO_TEST_CASE(Resize)
172 {
173  // basic fragment
174  artdaq::Fragment f1;
175  f1.resize(1234);
176  BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)1234);
177  BOOST_REQUIRE_EQUAL(f1.size(), (size_t)1234 +
179 
180  // fragment with metadata
181  MetadataTypeOne mdOneA;
182  artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
183  f2.resize(129);
184  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)129);
185  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)129 + 2 +
187 }
188 
189 BOOST_AUTO_TEST_CASE(Empty)
190 {
191  artdaq::Fragment f1;
192  BOOST_REQUIRE_EQUAL(f1.empty(), true);
193  f1.resize(1234);
194  BOOST_REQUIRE_EQUAL(f1.empty(), false);
195 
196  MetadataTypeOne mdOneA;
197  artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
198  BOOST_REQUIRE_EQUAL(f2.empty(), false);
199  f2.resize(129);
200  BOOST_REQUIRE_EQUAL(f2.empty(), false);
201  f2.resize(0);
202  BOOST_REQUIRE_EQUAL(f2.empty(), true);
203  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)0);
204  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)2 +
206 
207  artdaq::Fragment f3;
208  BOOST_REQUIRE_EQUAL(f3.empty(), true);
209  f3.setMetadata(mdOneA);
210  BOOST_REQUIRE_EQUAL(f3.empty(), true);
211 
212  artdaq::Fragment f4(14);
213  BOOST_REQUIRE_EQUAL(f4.empty(), false);
214  f4.setMetadata(mdOneA);
215  BOOST_REQUIRE_EQUAL(f4.empty(), false);
216 }
217 
218 BOOST_AUTO_TEST_CASE(Clear)
219 {
220  artdaq::Fragment f1;
221  BOOST_REQUIRE_EQUAL(f1.empty(), true);
222  f1.resize(1234);
223  BOOST_REQUIRE_EQUAL(f1.empty(), false);
224  f1.clear();
225  BOOST_REQUIRE_EQUAL(f1.empty(), true);
226 
227  MetadataTypeOne mdOneA;
228  artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
229  BOOST_REQUIRE_EQUAL(f2.empty(), false);
230  f2.resize(129);
231  BOOST_REQUIRE_EQUAL(f2.empty(), false);
232  f2.clear();
233  BOOST_REQUIRE_EQUAL(f2.empty(), true);
234  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)0);
235  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)2 +
237 
238  artdaq::Fragment f3;
239  BOOST_REQUIRE_EQUAL(f3.empty(), true);
240  BOOST_REQUIRE_EQUAL(f3.hasMetadata(), false);
241  f3.setMetadata(mdOneA);
242  BOOST_REQUIRE_EQUAL(f3.empty(), true);
243  BOOST_REQUIRE_EQUAL(f3.hasMetadata(), true);
244  f3.clear();
245  BOOST_REQUIRE_EQUAL(f3.empty(), true);
246  BOOST_REQUIRE_EQUAL(f3.hasMetadata(), true);
247 
248  artdaq::Fragment f4(14);
249  BOOST_REQUIRE_EQUAL(f4.empty(), false);
250  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), false);
251  f4.setMetadata(mdOneA);
252  BOOST_REQUIRE_EQUAL(f4.empty(), false);
253  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), true);
254  f4.clear();
255  BOOST_REQUIRE_EQUAL(f4.empty(), true);
256  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), true);
257 }
258 
259 BOOST_AUTO_TEST_CASE(Addresses)
260 {
261  // no metadata
262  artdaq::Fragment f1(200);
263  BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)200);
264  BOOST_REQUIRE_EQUAL(f1.size(), (size_t)200 +
266  artdaq::RawDataType* haddr = f1.headerAddress();
267  artdaq::RawDataType* daddr = f1.dataAddress();
268  BOOST_REQUIRE_EQUAL(daddr,
269  (haddr + artdaq::detail::RawFragmentHeader::num_words())); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
270 
271  BOOST_REQUIRE_THROW(f1.metadataAddress(), cet::exception);
272 
273  BOOST_REQUIRE_EQUAL(haddr, &(*(f1.headerBegin())));
274  BOOST_REQUIRE_EQUAL(daddr, &(*(f1.dataBegin())));
275  BOOST_REQUIRE_EQUAL(daddr + 200, &(*(f1.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
276 
277  // metadata with integer number of longwords
278  MetadataTypeOne mdOneA;
279  artdaq::Fragment f2(135, 101, 0, 3, mdOneA);
280  BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)135);
281  BOOST_REQUIRE_EQUAL(f2.size(), (size_t)135 + 2 +
283  haddr = f2.headerAddress();
284  daddr = f2.dataAddress();
285  artdaq::RawDataType* maddr = f2.metadataAddress();
286  BOOST_REQUIRE_EQUAL(maddr, haddr + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
288  BOOST_REQUIRE_EQUAL(daddr, maddr + 2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
289  BOOST_REQUIRE_EQUAL(haddr, &(*(f2.headerBegin())));
290  BOOST_REQUIRE_EQUAL(daddr, &(*(f2.dataBegin())));
291  BOOST_REQUIRE_EQUAL(daddr + 135, &(*(f2.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
292 
293  // metadata with fractional number of longwords
294  MetadataTypeTwo mdTwoA;
295  artdaq::Fragment f3(77, 101, 0, 3, mdTwoA);
296  BOOST_REQUIRE_EQUAL(f3.dataSize(), (size_t)77);
297  BOOST_REQUIRE_EQUAL(f3.size(), (size_t)77 + 4 + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
299  haddr = f3.headerAddress();
300  daddr = f3.dataAddress();
301  maddr = f3.metadataAddress();
302  BOOST_REQUIRE_EQUAL(maddr, haddr + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
304  BOOST_REQUIRE_EQUAL(daddr, maddr + 4); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
305  BOOST_REQUIRE_EQUAL(haddr, &(*(f3.headerBegin())));
306  BOOST_REQUIRE_EQUAL(daddr, &(*(f3.dataBegin())));
307  BOOST_REQUIRE_EQUAL(daddr + 77, &(*(f3.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
308 }
309 
310 BOOST_AUTO_TEST_CASE(Metadata)
311 {
312  artdaq::Fragment f1(42);
313  BOOST_REQUIRE_EQUAL(f1.hasMetadata(), false);
314 
315  BOOST_REQUIRE_THROW(f1.metadata<MetadataTypeOne>(), cet::exception);
316 
317  MetadataTypeOne mdOneA;
318  mdOneA.field1 = 5;
319  mdOneA.field2 = 10;
320  mdOneA.field3 = 15;
321 
322  BOOST_REQUIRE_THROW(f1.updateMetadata(mdOneA), cet::exception);
323 
324  f1.setMetadata(mdOneA);
325  auto* mdOnePtr = f1.metadata<MetadataTypeOne>();
326  BOOST_REQUIRE_EQUAL(mdOnePtr->field1, (uint64_t)5);
327  BOOST_REQUIRE_EQUAL(mdOnePtr->field2, (uint32_t)10);
328  BOOST_REQUIRE_EQUAL(mdOnePtr->field3, (uint32_t)15);
329 
330  MetadataTypeOne mdOneB;
331  BOOST_REQUIRE_THROW(f1.setMetadata(mdOneB), cet::exception);
332 
333  f1.updateMetadata(*mdOnePtr);
334 
335  MetadataTypeTwo mdTwoA;
336  mdTwoA.field1 = 10;
337  mdTwoA.field2 = 20;
338  mdTwoA.field3 = 30;
339  mdTwoA.field4 = 40;
340  mdTwoA.field5 = 50;
341 
342  BOOST_REQUIRE_THROW(f1.updateMetadata(mdTwoA), cet::exception);
343 
344  artdaq::Fragment f2(10, 1, 2, 3, mdTwoA);
345  auto* mdTwoPtr = f2.metadata<MetadataTypeTwo>();
346  BOOST_REQUIRE_EQUAL(mdTwoPtr->field1, (uint64_t)10);
347  BOOST_REQUIRE_EQUAL(mdTwoPtr->field2, (uint32_t)20);
348  BOOST_REQUIRE_EQUAL(mdTwoPtr->field3, (uint32_t)30);
349  BOOST_REQUIRE_EQUAL(mdTwoPtr->field4, (uint32_t)40);
350  BOOST_REQUIRE_EQUAL(mdTwoPtr->field5, (uint32_t)50);
351 
352  artdaq::Fragment f3(0xabcdef, 0xc3a5, 123);
353  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
354  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
355  BOOST_REQUIRE_EQUAL(f3.type(), (uint16_t)123);
356  f3.resize(5);
357  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
358  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
359  BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
360  artdaq::RawDataType* dataPtr = f3.dataAddress();
361  dataPtr[0] = 0x12345678; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
362  dataPtr[1] = 0xabcd; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
363  dataPtr[2] = 0x456789ab; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
364  dataPtr[3] = 0x3c3c3c3c; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
365  dataPtr[4] = 0x5a5a5a5a; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
366  BOOST_REQUIRE_EQUAL(dataPtr[0], (uint64_t)0x12345678); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
367  BOOST_REQUIRE_EQUAL(dataPtr[1], (uint64_t)0xabcd); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
368  BOOST_REQUIRE_EQUAL(dataPtr[2], (uint64_t)0x456789ab); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
369  BOOST_REQUIRE_EQUAL(dataPtr[3], (uint64_t)0x3c3c3c3c); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
370  BOOST_REQUIRE_EQUAL(dataPtr[4], (uint64_t)0x5a5a5a5a); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
371  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
372  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
373  BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
374  MetadataTypeOne mdOneC;
375  mdOneC.field1 = 505;
376  mdOneC.field2 = 510;
377  mdOneC.field3 = 515;
378  f3.setMetadata(mdOneC);
379  mdOnePtr = f3.metadata<MetadataTypeOne>();
380  BOOST_REQUIRE_EQUAL(mdOnePtr->field1, (uint64_t)505);
381  BOOST_REQUIRE_EQUAL(mdOnePtr->field2, (uint32_t)510);
382  BOOST_REQUIRE_EQUAL(mdOnePtr->field3, (uint32_t)515);
383  BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
384  BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
385  BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
386  dataPtr = f3.dataAddress();
387  dataPtr[0] = 0x12345678; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
388  dataPtr[1] = 0xabcd; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
389  dataPtr[2] = 0x456789ab; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
390  dataPtr[3] = 0x3c3c3c3c; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
391  dataPtr[4] = 0x5a5a5a5a; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
392  BOOST_REQUIRE_EQUAL(dataPtr[0], (uint64_t)0x12345678); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
393  BOOST_REQUIRE_EQUAL(dataPtr[1], (uint64_t)0xabcd); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
394  BOOST_REQUIRE_EQUAL(dataPtr[2], (uint64_t)0x456789ab); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
395  BOOST_REQUIRE_EQUAL(dataPtr[3], (uint64_t)0x3c3c3c3c); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
396  BOOST_REQUIRE_EQUAL(dataPtr[4], (uint64_t)0x5a5a5a5a); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
397 
398  MetadataTypeHuge mdHuge;
399  artdaq::Fragment f4(19);
400  BOOST_REQUIRE_EQUAL(f4.hasMetadata(), false);
401 
402  BOOST_REQUIRE_THROW(f4.setMetadata(mdHuge), cet::exception);
403 
404  BOOST_REQUIRE_THROW(artdaq::Fragment f5(127, 1, 2, 3, mdHuge), cet::exception);
405 }
406 
407 // JCF, 4/15/14 -- perform a set of tests concerning the new
408 // byte-by-byte interface functions added to artdaq::Fragment
409 
410 BOOST_AUTO_TEST_CASE(Bytes)
411 {
412  std::size_t payload_size = 5;
413 
414  // seqID, fragID, type are all random
417  artdaq::Fragment::type_t type = 3;
418 
419  // No explicit constructor necessary for Metadata -- all we care
420  // about is its size in the artdaq::Fragment, not its values
421 
422  struct Metadata
423  {
424  uint8_t byteOne;
425  uint8_t byteTwo;
426  uint8_t byteThree;
427  };
428 
429  Metadata theMetadata;
430 
431  BOOST_REQUIRE(sizeof(artdaq::Fragment::byte_t) == 1);
432 
433  // Assumption in some of the arithmetic below is that RawDataType is 8 bytes
434  BOOST_REQUIRE(sizeof(artdaq::RawDataType) == 8);
435 
436  // Check that the factory function and the explicit constructor
437  // methods of creating a fragment yield identical results IF the
438  // number of bytes passed to FragmentBytes() is a multiple of the
439  // size of the RawDataType
440 
441  std::unique_ptr<artdaq::Fragment> f1(new artdaq::Fragment(payload_size));
442  std::unique_ptr<artdaq::Fragment> f1_factory(artdaq::Fragment::FragmentBytes(
443  payload_size * sizeof(artdaq::RawDataType)));
444 
445  BOOST_REQUIRE(f1->size() == f1_factory->size());
446  BOOST_REQUIRE(f1->sizeBytes() == f1_factory->sizeBytes());
447 
448  std::unique_ptr<artdaq::Fragment> f2(new artdaq::Fragment(payload_size, seqID, fragID, type, theMetadata));
449  std::unique_ptr<artdaq::Fragment> f2_factory(artdaq::Fragment::FragmentBytes(
450  payload_size * sizeof(artdaq::RawDataType),
451  seqID, fragID,
452  type, theMetadata));
453 
454  BOOST_REQUIRE(f2->size() == f2_factory->size());
455  BOOST_REQUIRE(f2->sizeBytes() == f2_factory->sizeBytes());
456 
457  // Now let's make sure that data gets aligned as expected (i.e.,
458  // along boundaries separated by sizeof(RawDataType) bytes)
459 
460  std::size_t offset = 3;
461  std::unique_ptr<artdaq::Fragment> f3_factory(artdaq::Fragment::FragmentBytes(
462  payload_size * sizeof(artdaq::RawDataType) - offset,
463  seqID, fragID,
464  type, theMetadata));
465 
466  BOOST_REQUIRE(f3_factory->size() == f2->size());
467  BOOST_REQUIRE(f3_factory->sizeBytes() == f2->sizeBytes());
468 
469  // Make certain dataBegin(), dataBeginBytes() and the
470  // (now-deprecated, but still in legacy code) dataAddress() point to
471  // the same region in memory, i.e., the start of the payload
472 
473  auto* ptr1 = reinterpret_cast<artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
474  &*f3_factory->dataBegin());
475 
476  artdaq::Fragment::byte_t* ptr2 = f3_factory->dataBeginBytes();
477 
478  auto* ptr3 = reinterpret_cast<artdaq::Fragment::byte_t*>(f3_factory->dataAddress()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
479 
480  BOOST_REQUIRE_EQUAL(ptr1, ptr2);
481  BOOST_REQUIRE_EQUAL(ptr2, ptr3);
482 
483  // Make sure metadata struct gets aligned
484  // header == 3 RawDataTypes, metadata is 3 bytes (rounds up to 1 RawDataType)
485  std::size_t const metadata_size =
486  f3_factory->dataBeginBytes() - reinterpret_cast<artdaq::Fragment::byte_t*>(&*f3_factory->headerBegin()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
487  BOOST_REQUIRE(metadata_size ==
489 
490  // Sanity check for the payload size
491  BOOST_REQUIRE(static_cast<std::size_t>(f3_factory->dataEndBytes() - f3_factory->dataBeginBytes()) == f3_factory->dataSizeBytes()); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
492 
493  // Check resizing
494  artdaq::Fragment f4(payload_size);
495  BOOST_REQUIRE_EQUAL(f4.dataSize(), payload_size);
496  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), (payload_size * sizeof(artdaq::RawDataType)));
497  f4.resize(payload_size + 1);
498  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 1));
499  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 1) * sizeof(artdaq::RawDataType)));
500  f4.resizeBytes(f4.dataSizeBytes() + 2);
501  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 2));
502  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 2) * sizeof(artdaq::RawDataType)));
503  f4.resizeBytes(f4.dataSizeBytes() + 1);
504  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 3));
505  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 3) * sizeof(artdaq::RawDataType)));
506  f4.resizeBytes(f4.dataSizeBytes() + 1);
507  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 4));
508  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 4) * sizeof(artdaq::RawDataType)));
509 
510  size_t targetSize = (payload_size + 4) * sizeof(artdaq::RawDataType);
511  ++targetSize;
512  f4.resizeBytes(targetSize);
513  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
514  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
515  ++targetSize;
516  f4.resizeBytes(targetSize);
517  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
518  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
519  ++targetSize;
520  f4.resizeBytes(targetSize);
521  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
522  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
523  ++targetSize;
524  f4.resizeBytes(targetSize);
525  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
526  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
527  ++targetSize;
528  f4.resizeBytes(targetSize);
529  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
530  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
531  ++targetSize;
532  f4.resizeBytes(targetSize);
533  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
534  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
535  ++targetSize;
536  f4.resizeBytes(targetSize);
537  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
538  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
539  ++targetSize;
540  f4.resizeBytes(targetSize);
541  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
542  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
543  ++targetSize;
544  f4.resizeBytes(targetSize);
545  BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 6));
546  BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 6) * sizeof(artdaq::RawDataType)));
547 
548  // Check adding metadata after construction
549  artdaq::Fragment f5(payload_size);
550  BOOST_REQUIRE_EQUAL(f5.size(), (payload_size + artdaq::detail::RawFragmentHeader::num_words()));
551  BOOST_REQUIRE_EQUAL(f5.sizeBytes(), ((payload_size + artdaq::detail::RawFragmentHeader::num_words()) * sizeof(artdaq::RawDataType)));
552  f5.setMetadata(theMetadata);
553  BOOST_REQUIRE_EQUAL(f5.dataSize(), payload_size);
554  BOOST_REQUIRE_EQUAL(f5.dataSizeBytes(), (payload_size * sizeof(artdaq::RawDataType)));
555  BOOST_REQUIRE_EQUAL(f5.size(), (payload_size + 1 + artdaq::detail::RawFragmentHeader::num_words()));
556  BOOST_REQUIRE_EQUAL(f5.sizeBytes(), ((payload_size + 1 + artdaq::detail::RawFragmentHeader::num_words()) * sizeof(artdaq::RawDataType)));
557 }
558 
559 BOOST_AUTO_TEST_CASE(Upgrade_V0)
560 {
561  artdaq::Fragment f(7);
563 
565  hdr0.version = 0;
566  hdr0.type = 0xFE;
567  hdr0.metadata_word_count = 0;
568 
569  hdr0.sequence_id = 0xFEEDDEADBEEF;
570  hdr0.fragment_id = 0xBEE7;
571  hdr0.timestamp = 0xCAFEFECA;
572 
573  hdr0.unused1 = 0xF0F0;
574  hdr0.unused2 = 0xC5C5;
575 
576  memcpy(f.headerBeginBytes(), &hdr0, sizeof(hdr0));
577 
580  {
581  memcpy(f.headerBegin() + ii, &(++counter), sizeof(counter));
582  }
583 
584  BOOST_REQUIRE_EQUAL(f.version(), 0);
585  BOOST_REQUIRE_EQUAL(f.type(), 0xFE);
586  BOOST_REQUIRE_EQUAL(f.hasMetadata(), false);
587 
588  BOOST_REQUIRE_EQUAL(f.sequenceID(), 0xFEEDDEADBEEF);
589  BOOST_REQUIRE_EQUAL(f.fragmentID(), 0xBEE7);
590  BOOST_REQUIRE_EQUAL(f.timestamp(), 0xCAFEFECA);
591 
592  for (size_t jj = 0; jj < f.dataSize(); ++jj)
593  {
594  BOOST_REQUIRE_EQUAL(*(f.dataBegin() + jj), jj + 1);
595  }
596 }
597 
598 BOOST_AUTO_TEST_CASE(Upgrade_V1)
599 {
600  artdaq::Fragment f(7);
602 
604  hdr1.version = 1;
605  hdr1.type = 0xFE;
606  hdr1.metadata_word_count = 0;
607 
608  hdr1.sequence_id = 0xFEEDDEADBEEF;
609  hdr1.fragment_id = 0xBEE7;
610  hdr1.timestamp = 0xCAFEFECAAAAABBBB;
611 
612  memcpy(f.headerBeginBytes(), &hdr1, sizeof(hdr1));
613 
616  {
617  memcpy(f.headerBegin() + ii, &(++counter), sizeof(counter));
618  }
619 
620  BOOST_REQUIRE_EQUAL(f.version(), 1);
621  BOOST_REQUIRE_EQUAL(f.type(), 0xFE);
622  BOOST_REQUIRE_EQUAL(f.hasMetadata(), false);
623 
624  BOOST_REQUIRE_EQUAL(f.sequenceID(), 0xFEEDDEADBEEF);
625  BOOST_REQUIRE_EQUAL(f.fragmentID(), 0xBEE7);
626  BOOST_REQUIRE_EQUAL(f.timestamp(), 0xCAFEFECAAAAABBBB);
627 
628  for (size_t jj = 0; jj < f.dataSize(); ++jj)
629  {
630  BOOST_REQUIRE_EQUAL(*(f.dataBegin() + jj), jj + 1); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
631  }
632 }
633 
634 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...
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
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.