Line data Source code
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 :
7 : /**
8 : * \brief Test Metadata with three fields in two long words
9 : */
10 : struct MetadataTypeOne
11 : {
12 : uint64_t field1; ///< 1. A 64-bit field
13 : uint32_t field2; ///< 2. A 32-bit field
14 : uint32_t field3; ///< 3. A 32-bit field
15 : };
16 :
17 : /**
18 : * \brief Test Metadata with five fields, mixing field sizes
19 : */
20 : struct MetadataTypeTwo
21 : {
22 : uint64_t field1; ///< 1. A 64-bit field
23 : uint32_t field2; ///< 2. A 32-bit field
24 : uint32_t field3; ///< 3. A 32-bit field
25 : uint64_t field4; ///< 4. A 64-bit field
26 : uint16_t field5; ///< 5. A 16-bit field
27 : };
28 :
29 : /**
30 : * \brief Test Metadata that is very large
31 : */
32 : struct MetadataTypeHuge
33 : {
34 : uint64_t fields[300]; ///< 300 long words
35 : };
36 :
37 : BOOST_AUTO_TEST_SUITE(Fragment_test)
38 :
39 2 : 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.
44 1 : artdaq::Fragment f1;
45 1 : BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)0);
46 1 : BOOST_REQUIRE_EQUAL(f1.size(), (size_t)artdaq::detail::RawFragmentHeader::num_words());
47 1 : BOOST_REQUIRE_EQUAL(f1.version(), (artdaq::Fragment::version_t)artdaq::detail::RawFragmentHeader::CurrentVersion);
48 1 : BOOST_REQUIRE_EQUAL(f1.type(), (artdaq::Fragment::type_t)artdaq::Fragment::InvalidFragmentType);
49 1 : BOOST_REQUIRE_EQUAL(f1.sequenceID(), (artdaq::Fragment::sequence_id_t)artdaq::Fragment::InvalidSequenceID);
50 1 : BOOST_REQUIRE_EQUAL(f1.fragmentID(), (artdaq::Fragment::fragment_id_t)artdaq::Fragment::InvalidFragmentID);
51 1 : BOOST_REQUIRE_EQUAL(f1.hasMetadata(), false);
52 :
53 1 : artdaq::Fragment f2(7);
54 1 : BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)7);
55 1 : BOOST_REQUIRE_EQUAL(f2.size(), (size_t)artdaq::detail::RawFragmentHeader::num_words() + 7);
56 1 : BOOST_REQUIRE_EQUAL(f2.version(), (artdaq::Fragment::version_t)artdaq::detail::RawFragmentHeader::CurrentVersion);
57 1 : BOOST_REQUIRE(f2.type() == artdaq::Fragment::InvalidFragmentType);
58 1 : BOOST_REQUIRE(f2.sequenceID() == artdaq::Fragment::InvalidSequenceID);
59 1 : BOOST_REQUIRE(f2.fragmentID() == artdaq::Fragment::InvalidFragmentID);
60 1 : BOOST_REQUIRE_EQUAL(f2.hasMetadata(), false);
61 :
62 1 : artdaq::Fragment f3(101, 202);
63 1 : BOOST_REQUIRE_EQUAL(f3.dataSize(), (size_t)0);
64 1 : BOOST_REQUIRE_EQUAL(f3.size(), (size_t)artdaq::detail::RawFragmentHeader::num_words());
65 1 : BOOST_REQUIRE_EQUAL(f3.version(), (artdaq::Fragment::version_t)artdaq::detail::RawFragmentHeader::CurrentVersion);
66 1 : BOOST_REQUIRE(f3.type() == artdaq::Fragment::DataFragmentType);
67 1 : BOOST_REQUIRE_EQUAL(f3.sequenceID(), (artdaq::Fragment::sequence_id_t)101);
68 1 : BOOST_REQUIRE_EQUAL(f3.fragmentID(), (artdaq::Fragment::fragment_id_t)202);
69 1 : BOOST_REQUIRE_EQUAL(f3.hasMetadata(), false);
70 :
71 2 : std::vector<artdaq::RawDataType> d{1, 2, 3};
72 1 : auto f4 = artdaq::Fragment::dataFrag(101, 202, &d[0], 3);
73 1 : BOOST_REQUIRE_EQUAL(f4->dataSize(), (size_t)3);
74 1 : BOOST_REQUIRE_EQUAL(f4->size(), (size_t)artdaq::detail::RawFragmentHeader::num_words() + 3);
75 1 : BOOST_REQUIRE_EQUAL(f4->version(), (artdaq::Fragment::version_t)artdaq::detail::RawFragmentHeader::CurrentVersion);
76 1 : BOOST_REQUIRE(f4->type() == artdaq::Fragment::DataFragmentType);
77 1 : BOOST_REQUIRE_EQUAL(f4->sequenceID(), (artdaq::Fragment::sequence_id_t)101);
78 1 : BOOST_REQUIRE_EQUAL(f4->fragmentID(), (artdaq::Fragment::fragment_id_t)202);
79 1 : BOOST_REQUIRE_EQUAL(f4->hasMetadata(), false);
80 :
81 : // Verify that only "user" fragment types may be specified
82 : // in the constructor
83 2 : BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 0), cet::exception);
84 2 : BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 225), cet::exception);
85 2 : BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, 255), cet::exception);
86 2 : BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::Fragment::InvalidFragmentType), cet::exception);
87 2 : BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::detail::RawFragmentHeader::FIRST_SYSTEM_TYPE), cet::exception);
88 2 : BOOST_REQUIRE_THROW(artdaq::Fragment frag(101, 202, artdaq::detail::RawFragmentHeader::LAST_SYSTEM_TYPE), cet::exception);
89 :
90 : artdaq::Fragment
91 1 : fragA(101, 202, artdaq::detail::RawFragmentHeader::FIRST_USER_TYPE);
92 : artdaq::Fragment
93 1 : fragB(101, 202, artdaq::detail::RawFragmentHeader::LAST_USER_TYPE);
94 1 : artdaq::Fragment fragC(101, 202, 1);
95 1 : artdaq::Fragment fragD(101, 202, 2);
96 1 : artdaq::Fragment fragE(101, 202, 3);
97 1 : artdaq::Fragment fragF(101, 202, 100);
98 1 : artdaq::Fragment fragG(101, 202, 200);
99 1 : artdaq::Fragment fragH(101, 202, 224);
100 :
101 3 : TLOG(TLVL_INFO) << "Example Fragment: " << f1;
102 1 : BOOST_REQUIRE_EQUAL(f1.typeString(), "0");
103 1 : }
104 :
105 2 : BOOST_AUTO_TEST_CASE(FragmentType)
106 : {
107 1 : artdaq::Fragment frag(15);
108 :
109 : // test "user" fragment types
110 1 : BOOST_REQUIRE_THROW(frag.setUserType(0), cet::exception);
111 1 : BOOST_REQUIRE_THROW(frag.setUserType(225), cet::exception);
112 1 : BOOST_REQUIRE_THROW(frag.setUserType(255), cet::exception);
113 1 : BOOST_REQUIRE_THROW(frag.setUserType(artdaq::Fragment::InvalidFragmentType), cet::exception);
114 1 : BOOST_REQUIRE_THROW(frag.setUserType(artdaq::detail::RawFragmentHeader::FIRST_SYSTEM_TYPE), cet::exception);
115 1 : BOOST_REQUIRE_THROW(frag.setUserType(artdaq::detail::RawFragmentHeader::LAST_SYSTEM_TYPE), cet::exception);
116 :
117 1 : frag.setUserType(artdaq::detail::RawFragmentHeader::FIRST_USER_TYPE);
118 1 : frag.setUserType(artdaq::detail::RawFragmentHeader::LAST_USER_TYPE);
119 1 : frag.setUserType(1);
120 1 : frag.setUserType(2);
121 1 : frag.setUserType(3);
122 1 : frag.setUserType(100);
123 1 : frag.setUserType(200);
124 1 : frag.setUserType(224);
125 :
126 : // test "system" fragment types
127 1 : BOOST_REQUIRE_THROW(frag.setSystemType(0), cet::exception);
128 1 : BOOST_REQUIRE_THROW(frag.setSystemType(1), cet::exception);
129 1 : BOOST_REQUIRE_THROW(frag.setSystemType(224), cet::exception);
130 1 : BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::Fragment::InvalidFragmentType), cet::exception);
131 1 : BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::detail::RawFragmentHeader::FIRST_USER_TYPE), cet::exception);
132 1 : BOOST_REQUIRE_THROW(frag.setSystemType(artdaq::detail::RawFragmentHeader::LAST_USER_TYPE), cet::exception);
133 :
134 1 : frag.setSystemType(artdaq::detail::RawFragmentHeader::FIRST_SYSTEM_TYPE);
135 1 : frag.setSystemType(artdaq::detail::RawFragmentHeader::LAST_SYSTEM_TYPE);
136 1 : frag.setSystemType(225);
137 1 : frag.setSystemType(230);
138 1 : frag.setSystemType(240);
139 1 : frag.setSystemType(250);
140 1 : frag.setSystemType(255);
141 :
142 1 : auto map = artdaq::detail::RawFragmentHeader::MakeVerboseSystemTypeMap();
143 1 : BOOST_REQUIRE(map.size() > 0);
144 1 : map = artdaq::detail::RawFragmentHeader::MakeSystemTypeMap();
145 1 : BOOST_REQUIRE(map.size() > 0);
146 1 : }
147 :
148 2 : BOOST_AUTO_TEST_CASE(SequenceID)
149 : {
150 1 : artdaq::Fragment f1;
151 1 : f1.setSequenceID(0);
152 1 : BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0);
153 1 : f1.setSequenceID(1);
154 1 : BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)1);
155 1 : f1.setSequenceID(0xffff);
156 1 : BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0xffff);
157 1 : f1.setSequenceID(0x0000ffffffffffff);
158 1 : BOOST_REQUIRE_EQUAL(f1.sequenceID(), (uint64_t)0x0000ffffffffffff);
159 :
160 1 : artdaq::Fragment f2(0x12345, 0xab);
161 1 : BOOST_REQUIRE_EQUAL(f2.sequenceID(), (uint64_t)0x12345);
162 :
163 1 : artdaq::Fragment f3(0x0000567812345678, 0xab);
164 1 : BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint64_t)0x0000567812345678);
165 1 : }
166 :
167 2 : BOOST_AUTO_TEST_CASE(FragmentID)
168 : {
169 1 : artdaq::Fragment f1;
170 1 : f1.setFragmentID(0);
171 1 : BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)0);
172 1 : f1.setFragmentID(1);
173 1 : BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)1);
174 1 : f1.setFragmentID(0xffff);
175 1 : BOOST_REQUIRE_EQUAL(f1.fragmentID(), (uint16_t)0xffff);
176 :
177 1 : artdaq::Fragment f2(0x12345, 0xab);
178 1 : BOOST_REQUIRE_EQUAL(f2.fragmentID(), (uint16_t)0xab);
179 :
180 1 : artdaq::Fragment f3(0x0000567812345678, 0xffff);
181 1 : BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xffff);
182 1 : }
183 :
184 2 : BOOST_AUTO_TEST_CASE(Resize)
185 : {
186 : // basic fragment
187 1 : artdaq::Fragment f1;
188 1 : f1.resize(1234);
189 1 : BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)1234);
190 1 : BOOST_REQUIRE_EQUAL(f1.size(), (size_t)1234 +
191 : artdaq::detail::RawFragmentHeader::num_words());
192 :
193 : // fragment with metadata
194 1 : MetadataTypeOne mdOneA{};
195 1 : artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
196 1 : f2.resize(129);
197 1 : BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)129);
198 1 : BOOST_REQUIRE_EQUAL(f2.size(), (size_t)129 + 2 +
199 : artdaq::detail::RawFragmentHeader::num_words());
200 1 : }
201 :
202 2 : BOOST_AUTO_TEST_CASE(Empty)
203 : {
204 1 : artdaq::Fragment f1;
205 1 : BOOST_REQUIRE_EQUAL(f1.empty(), true);
206 1 : f1.resize(1234);
207 1 : BOOST_REQUIRE_EQUAL(f1.empty(), false);
208 :
209 1 : MetadataTypeOne mdOneA{};
210 1 : artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
211 1 : BOOST_REQUIRE_EQUAL(f2.empty(), false);
212 1 : f2.resize(129);
213 1 : BOOST_REQUIRE_EQUAL(f2.empty(), false);
214 1 : f2.resize(0);
215 1 : BOOST_REQUIRE_EQUAL(f2.empty(), true);
216 1 : BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)0);
217 1 : BOOST_REQUIRE_EQUAL(f2.size(), (size_t)2 +
218 : artdaq::detail::RawFragmentHeader::num_words());
219 :
220 1 : artdaq::Fragment f3;
221 1 : BOOST_REQUIRE_EQUAL(f3.empty(), true);
222 1 : f3.setMetadata(mdOneA);
223 1 : BOOST_REQUIRE_EQUAL(f3.empty(), true);
224 :
225 1 : artdaq::Fragment f4(14);
226 1 : BOOST_REQUIRE_EQUAL(f4.empty(), false);
227 1 : f4.setMetadata(mdOneA);
228 1 : BOOST_REQUIRE_EQUAL(f4.empty(), false);
229 1 : }
230 :
231 2 : BOOST_AUTO_TEST_CASE(Clear)
232 : {
233 1 : artdaq::Fragment f1;
234 1 : BOOST_REQUIRE_EQUAL(f1.empty(), true);
235 1 : f1.resize(1234);
236 1 : BOOST_REQUIRE_EQUAL(f1.empty(), false);
237 1 : f1.clear();
238 1 : BOOST_REQUIRE_EQUAL(f1.empty(), true);
239 :
240 : MetadataTypeOne mdOneA;
241 1 : artdaq::Fragment f2(1, 123, 3, 5, mdOneA);
242 1 : BOOST_REQUIRE_EQUAL(f2.empty(), false);
243 1 : f2.resize(129);
244 1 : BOOST_REQUIRE_EQUAL(f2.empty(), false);
245 1 : f2.clear();
246 1 : BOOST_REQUIRE_EQUAL(f2.empty(), true);
247 1 : BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)0);
248 1 : BOOST_REQUIRE_EQUAL(f2.size(), (size_t)2 +
249 : artdaq::detail::RawFragmentHeader::num_words());
250 :
251 1 : artdaq::Fragment f3;
252 1 : BOOST_REQUIRE_EQUAL(f3.empty(), true);
253 1 : BOOST_REQUIRE_EQUAL(f3.hasMetadata(), false);
254 1 : f3.setMetadata(mdOneA);
255 1 : BOOST_REQUIRE_EQUAL(f3.empty(), true);
256 1 : BOOST_REQUIRE_EQUAL(f3.hasMetadata(), true);
257 1 : f3.clear();
258 1 : BOOST_REQUIRE_EQUAL(f3.empty(), true);
259 1 : BOOST_REQUIRE_EQUAL(f3.hasMetadata(), true);
260 :
261 1 : artdaq::Fragment f4(14);
262 1 : BOOST_REQUIRE_EQUAL(f4.empty(), false);
263 1 : BOOST_REQUIRE_EQUAL(f4.hasMetadata(), false);
264 1 : f4.setMetadata(mdOneA);
265 1 : BOOST_REQUIRE_EQUAL(f4.empty(), false);
266 1 : BOOST_REQUIRE_EQUAL(f4.hasMetadata(), true);
267 1 : f4.clear();
268 1 : BOOST_REQUIRE_EQUAL(f4.empty(), true);
269 1 : BOOST_REQUIRE_EQUAL(f4.hasMetadata(), true);
270 1 : }
271 :
272 2 : BOOST_AUTO_TEST_CASE(Addresses)
273 : {
274 : // no metadata
275 1 : artdaq::Fragment f1(200);
276 1 : BOOST_REQUIRE_EQUAL(f1.dataSize(), (size_t)200);
277 1 : BOOST_REQUIRE_EQUAL(f1.size(), (size_t)200 +
278 : artdaq::detail::RawFragmentHeader::num_words());
279 1 : artdaq::RawDataType* haddr = f1.headerAddress();
280 1 : artdaq::RawDataType* daddr = f1.dataAddress();
281 1 : BOOST_REQUIRE_EQUAL(daddr,
282 : (haddr + artdaq::detail::RawFragmentHeader::num_words())); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
283 :
284 1 : BOOST_REQUIRE_THROW(f1.metadataAddress(), cet::exception);
285 :
286 1 : BOOST_REQUIRE_EQUAL(haddr, &(*(f1.headerBegin())));
287 1 : BOOST_REQUIRE_EQUAL(daddr, &(*(f1.dataBegin())));
288 1 : BOOST_REQUIRE_EQUAL(daddr + 200, &(*(f1.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
289 :
290 : // Const versions
291 1 : const artdaq::Fragment cf1(f1);
292 1 : BOOST_REQUIRE_EQUAL(cf1.dataSize(), (size_t)200);
293 1 : BOOST_REQUIRE_EQUAL(cf1.size(), (size_t)200 +
294 : artdaq::detail::RawFragmentHeader::num_words());
295 1 : const artdaq::RawDataType* chaddr = cf1.headerBegin();
296 1 : const artdaq::RawDataType* cdaddr = cf1.dataBegin();
297 1 : BOOST_REQUIRE_EQUAL(cdaddr,
298 : (chaddr + artdaq::detail::RawFragmentHeader::num_words())); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
299 :
300 1 : BOOST_REQUIRE_EQUAL(cdaddr + 200, &(*(cf1.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
301 :
302 : // metadata with integer number of longwords
303 1 : MetadataTypeOne mdOneA{};
304 1 : artdaq::Fragment f2(135, 101, 0, 3, mdOneA);
305 1 : BOOST_REQUIRE_EQUAL(f2.dataSize(), (size_t)135);
306 1 : BOOST_REQUIRE_EQUAL(f2.size(), (size_t)135 + 2 +
307 : artdaq::detail::RawFragmentHeader::num_words());
308 1 : haddr = f2.headerAddress();
309 1 : daddr = f2.dataAddress();
310 1 : artdaq::RawDataType* maddr = f2.metadataAddress();
311 1 : BOOST_REQUIRE_EQUAL(maddr, haddr + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
312 : artdaq::detail::RawFragmentHeader::num_words());
313 1 : BOOST_REQUIRE_EQUAL(daddr, maddr + 2); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
314 1 : BOOST_REQUIRE_EQUAL(haddr, &(*(f2.headerBegin())));
315 1 : BOOST_REQUIRE_EQUAL(daddr, &(*(f2.dataBegin())));
316 1 : 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 1 : artdaq::Fragment f3(77, 101, 0, 3, mdTwoA);
321 1 : BOOST_REQUIRE_EQUAL(f3.dataSize(), (size_t)77);
322 1 : BOOST_REQUIRE_EQUAL(f3.size(), (size_t)77 + 4 + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
323 : artdaq::detail::RawFragmentHeader::num_words());
324 1 : haddr = f3.headerAddress();
325 1 : daddr = f3.dataAddress();
326 1 : maddr = f3.metadataAddress();
327 1 : BOOST_REQUIRE_EQUAL(maddr, haddr + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
328 : artdaq::detail::RawFragmentHeader::num_words());
329 1 : BOOST_REQUIRE_EQUAL(daddr, maddr + 4); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
330 1 : BOOST_REQUIRE_EQUAL(haddr, &(*(f3.headerBegin())));
331 1 : BOOST_REQUIRE_EQUAL(daddr, &(*(f3.dataBegin())));
332 1 : BOOST_REQUIRE_EQUAL(daddr + 77, &(*(f3.dataEnd()))); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
333 1 : }
334 :
335 2 : BOOST_AUTO_TEST_CASE(Metadata)
336 : {
337 1 : artdaq::Fragment f1(42);
338 1 : BOOST_REQUIRE_EQUAL(f1.hasMetadata(), false);
339 :
340 1 : BOOST_REQUIRE_THROW(f1.metadata<MetadataTypeOne>(), cet::exception);
341 :
342 : MetadataTypeOne mdOneA;
343 1 : mdOneA.field1 = 5;
344 1 : mdOneA.field2 = 10;
345 1 : mdOneA.field3 = 15;
346 :
347 1 : BOOST_REQUIRE_THROW(f1.updateMetadata(mdOneA), cet::exception);
348 :
349 1 : f1.setMetadata(mdOneA);
350 1 : auto* mdOnePtr = f1.metadata<MetadataTypeOne>();
351 1 : BOOST_REQUIRE_EQUAL(mdOnePtr->field1, (uint64_t)5);
352 1 : BOOST_REQUIRE_EQUAL(mdOnePtr->field2, (uint32_t)10);
353 1 : BOOST_REQUIRE_EQUAL(mdOnePtr->field3, (uint32_t)15);
354 :
355 1 : MetadataTypeOne mdOneB{};
356 1 : BOOST_REQUIRE_THROW(f1.setMetadata(mdOneB), cet::exception);
357 :
358 1 : f1.updateMetadata(*mdOnePtr);
359 :
360 : MetadataTypeTwo mdTwoA;
361 1 : mdTwoA.field1 = 10;
362 1 : mdTwoA.field2 = 20;
363 1 : mdTwoA.field3 = 30;
364 1 : mdTwoA.field4 = 40;
365 1 : mdTwoA.field5 = 50;
366 :
367 1 : BOOST_REQUIRE_THROW(f1.updateMetadata(mdTwoA), cet::exception);
368 :
369 1 : artdaq::Fragment f2(10, 1, 2, 3, mdTwoA);
370 1 : auto* mdTwoPtr = f2.metadata<MetadataTypeTwo>();
371 1 : BOOST_REQUIRE_EQUAL(mdTwoPtr->field1, (uint64_t)10);
372 1 : BOOST_REQUIRE_EQUAL(mdTwoPtr->field2, (uint32_t)20);
373 1 : BOOST_REQUIRE_EQUAL(mdTwoPtr->field3, (uint32_t)30);
374 1 : BOOST_REQUIRE_EQUAL(mdTwoPtr->field4, (uint32_t)40);
375 1 : BOOST_REQUIRE_EQUAL(mdTwoPtr->field5, (uint32_t)50);
376 :
377 1 : artdaq::Fragment f3(0xabcdef, 0xc3a5, 123);
378 1 : BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
379 1 : BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
380 1 : BOOST_REQUIRE_EQUAL(f3.type(), (uint16_t)123);
381 1 : f3.resize(5);
382 1 : BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
383 1 : BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
384 1 : BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
385 1 : artdaq::RawDataType* dataPtr = f3.dataAddress();
386 1 : dataPtr[0] = 0x12345678; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
387 1 : dataPtr[1] = 0xabcd; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
388 1 : dataPtr[2] = 0x456789ab; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
389 1 : dataPtr[3] = 0x3c3c3c3c; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
390 1 : dataPtr[4] = 0x5a5a5a5a; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
391 1 : BOOST_REQUIRE_EQUAL(dataPtr[0], (uint64_t)0x12345678); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
392 1 : BOOST_REQUIRE_EQUAL(dataPtr[1], (uint64_t)0xabcd); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
393 1 : BOOST_REQUIRE_EQUAL(dataPtr[2], (uint64_t)0x456789ab); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
394 1 : BOOST_REQUIRE_EQUAL(dataPtr[3], (uint64_t)0x3c3c3c3c); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
395 1 : BOOST_REQUIRE_EQUAL(dataPtr[4], (uint64_t)0x5a5a5a5a); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
396 1 : BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
397 1 : BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
398 1 : BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
399 : MetadataTypeOne mdOneC;
400 1 : mdOneC.field1 = 505;
401 1 : mdOneC.field2 = 510;
402 1 : mdOneC.field3 = 515;
403 1 : f3.setMetadata(mdOneC);
404 1 : mdOnePtr = f3.metadata<MetadataTypeOne>();
405 1 : BOOST_REQUIRE_EQUAL(mdOnePtr->field1, (uint64_t)505);
406 1 : BOOST_REQUIRE_EQUAL(mdOnePtr->field2, (uint32_t)510);
407 1 : BOOST_REQUIRE_EQUAL(mdOnePtr->field3, (uint32_t)515);
408 1 : BOOST_REQUIRE_EQUAL(f3.sequenceID(), (uint32_t)0xabcdef);
409 1 : BOOST_REQUIRE_EQUAL(f3.fragmentID(), (uint16_t)0xc3a5);
410 1 : BOOST_REQUIRE_EQUAL(f3.type(), (uint8_t)123);
411 1 : dataPtr = f3.dataAddress();
412 1 : dataPtr[0] = 0x12345678; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
413 1 : dataPtr[1] = 0xabcd; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
414 1 : dataPtr[2] = 0x456789ab; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
415 1 : dataPtr[3] = 0x3c3c3c3c; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
416 1 : dataPtr[4] = 0x5a5a5a5a; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
417 1 : BOOST_REQUIRE_EQUAL(dataPtr[0], (uint64_t)0x12345678); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
418 1 : BOOST_REQUIRE_EQUAL(dataPtr[1], (uint64_t)0xabcd); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
419 1 : BOOST_REQUIRE_EQUAL(dataPtr[2], (uint64_t)0x456789ab); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
420 1 : BOOST_REQUIRE_EQUAL(dataPtr[3], (uint64_t)0x3c3c3c3c); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
421 1 : BOOST_REQUIRE_EQUAL(dataPtr[4], (uint64_t)0x5a5a5a5a); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
422 :
423 : MetadataTypeHuge mdHuge;
424 1 : artdaq::Fragment f4(19);
425 1 : BOOST_REQUIRE_EQUAL(f4.hasMetadata(), false);
426 :
427 1 : BOOST_REQUIRE_THROW(f4.setMetadata(mdHuge), cet::exception);
428 :
429 2 : BOOST_REQUIRE_THROW(artdaq::Fragment f5(127, 1, 2, 3, mdHuge), cet::exception);
430 1 : }
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 2 : BOOST_AUTO_TEST_CASE(Bytes)
436 : {
437 1 : std::size_t payload_size = 5;
438 :
439 : // seqID, fragID, type are all random
440 1 : artdaq::Fragment::sequence_id_t seqID = 1;
441 1 : artdaq::Fragment::fragment_id_t fragID = 1;
442 1 : 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 1 : BOOST_REQUIRE(sizeof(artdaq::Fragment::byte_t) == 1);
457 :
458 : // Assumption in some of the arithmetic below is that RawDataType is 8 bytes
459 1 : 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 1 : std::unique_ptr<artdaq::Fragment> f1(new artdaq::Fragment(payload_size));
467 : std::unique_ptr<artdaq::Fragment> f1_factory(artdaq::Fragment::FragmentBytes(
468 1 : payload_size * sizeof(artdaq::RawDataType)));
469 :
470 1 : BOOST_REQUIRE(f1->size() == f1_factory->size());
471 1 : BOOST_REQUIRE(f1->sizeBytes() == f1_factory->sizeBytes());
472 :
473 1 : 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 1 : type, theMetadata));
478 :
479 1 : BOOST_REQUIRE(f2->size() == f2_factory->size());
480 1 : 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 1 : std::size_t offset = 3;
486 : std::unique_ptr<artdaq::Fragment> f3_factory(artdaq::Fragment::FragmentBytes(
487 1 : payload_size * sizeof(artdaq::RawDataType) - offset,
488 : seqID, fragID,
489 1 : type, theMetadata));
490 :
491 1 : BOOST_REQUIRE(f3_factory->size() == f2->size());
492 1 : 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 1 : &*f3_factory->headerBegin());
500 1 : BOOST_REQUIRE_EQUAL(&*f3_factory->headerBeginBytes(), hdrptr);
501 :
502 : auto* ptr1 = reinterpret_cast<artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
503 1 : &*f3_factory->dataBegin());
504 :
505 1 : artdaq::Fragment::byte_t* ptr2 = f3_factory->dataBeginBytes();
506 :
507 1 : auto* ptr3 = reinterpret_cast<artdaq::Fragment::byte_t*>(f3_factory->dataAddress()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
508 :
509 1 : BOOST_REQUIRE_EQUAL(ptr1, ptr2);
510 1 : BOOST_REQUIRE_EQUAL(ptr2, ptr3);
511 :
512 : auto* dataEndPtr = reinterpret_cast<artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
513 1 : &*f3_factory->dataEnd());
514 1 : BOOST_REQUIRE_EQUAL(&*f3_factory->dataEndBytes(), dataEndPtr);
515 :
516 : // Check const versions, too
517 1 : const artdaq::Fragment f3_copy(*f3_factory);
518 1 : auto chdrptr = reinterpret_cast<const artdaq::Fragment::byte_t*>(f3_copy.headerBegin()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
519 1 : BOOST_REQUIRE_EQUAL(&*f3_copy.headerBeginBytes(), chdrptr);
520 : auto* cptr1 = reinterpret_cast<const artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
521 1 : &*f3_copy.dataBegin());
522 :
523 1 : const artdaq::Fragment::byte_t* cptr2 = f3_copy.dataBeginBytes();
524 :
525 1 : BOOST_REQUIRE_EQUAL(cptr1, cptr2);
526 :
527 : auto* cdataEndPtr = reinterpret_cast<const artdaq::Fragment::byte_t*>( // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
528 1 : &*f3_copy.dataEnd());
529 1 : 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 1 : f3_factory->dataBeginBytes() - reinterpret_cast<artdaq::Fragment::byte_t*>(&*f3_factory->headerBegin()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
535 1 : BOOST_REQUIRE(metadata_size ==
536 : (1 + artdaq::detail::RawFragmentHeader::num_words()) * sizeof(artdaq::RawDataType));
537 :
538 : // Sanity check for the payload size
539 1 : 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 1 : artdaq::Fragment f4(payload_size);
543 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), payload_size);
544 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), (payload_size * sizeof(artdaq::RawDataType)));
545 1 : f4.resize(payload_size + 1);
546 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 1));
547 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 1) * sizeof(artdaq::RawDataType)));
548 1 : f4.resizeBytes(f4.dataSizeBytes() + 2);
549 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 2));
550 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 2) * sizeof(artdaq::RawDataType)));
551 1 : f4.resizeBytes(f4.dataSizeBytes() + 1);
552 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 3));
553 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 3) * sizeof(artdaq::RawDataType)));
554 1 : f4.resizeBytes(f4.dataSizeBytes() + 1);
555 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 4));
556 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 4) * sizeof(artdaq::RawDataType)));
557 :
558 1 : size_t targetSize = (payload_size + 4) * sizeof(artdaq::RawDataType);
559 1 : ++targetSize;
560 1 : f4.resizeBytes(targetSize);
561 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
562 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
563 1 : ++targetSize;
564 1 : f4.resizeBytes(targetSize);
565 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
566 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
567 1 : ++targetSize;
568 1 : f4.resizeBytes(targetSize);
569 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
570 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
571 1 : ++targetSize;
572 1 : f4.resizeBytes(targetSize);
573 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
574 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
575 1 : ++targetSize;
576 1 : f4.resizeBytes(targetSize);
577 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
578 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
579 1 : ++targetSize;
580 1 : f4.resizeBytes(targetSize);
581 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
582 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
583 1 : ++targetSize;
584 1 : f4.resizeBytes(targetSize);
585 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
586 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
587 1 : ++targetSize;
588 1 : f4.resizeBytes(targetSize);
589 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 5));
590 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 5) * sizeof(artdaq::RawDataType)));
591 1 : ++targetSize;
592 1 : f4.resizeBytes(targetSize);
593 1 : BOOST_REQUIRE_EQUAL(f4.dataSize(), (payload_size + 6));
594 1 : BOOST_REQUIRE_EQUAL(f4.dataSizeBytes(), ((payload_size + 6) * sizeof(artdaq::RawDataType)));
595 :
596 : // Check adding metadata after construction
597 1 : artdaq::Fragment f5(payload_size);
598 1 : BOOST_REQUIRE_EQUAL(f5.size(), (payload_size + artdaq::detail::RawFragmentHeader::num_words()));
599 1 : BOOST_REQUIRE_EQUAL(f5.sizeBytes(), ((payload_size + artdaq::detail::RawFragmentHeader::num_words()) * sizeof(artdaq::RawDataType)));
600 1 : f5.setMetadata(theMetadata);
601 1 : BOOST_REQUIRE_EQUAL(f5.dataSize(), payload_size);
602 1 : BOOST_REQUIRE_EQUAL(f5.dataSizeBytes(), (payload_size * sizeof(artdaq::RawDataType)));
603 1 : BOOST_REQUIRE_EQUAL(f5.size(), (payload_size + 1 + artdaq::detail::RawFragmentHeader::num_words()));
604 1 : BOOST_REQUIRE_EQUAL(f5.sizeBytes(), ((payload_size + 1 + artdaq::detail::RawFragmentHeader::num_words()) * sizeof(artdaq::RawDataType)));
605 1 : }
606 :
607 2 : BOOST_AUTO_TEST_CASE(Upgrade_V0)
608 : {
609 1 : artdaq::Fragment f(7);
610 : artdaq::detail::RawFragmentHeaderV0 hdr0;
611 :
612 1 : hdr0.word_count = artdaq::detail::RawFragmentHeader::num_words() + 7;
613 1 : hdr0.version = 0;
614 1 : hdr0.type = 0xFE;
615 1 : hdr0.metadata_word_count = 0;
616 :
617 1 : hdr0.sequence_id = 0xFEEDDEADBEEF;
618 1 : hdr0.fragment_id = 0xBEE7;
619 1 : hdr0.timestamp = 0xCAFEFECA;
620 :
621 1 : hdr0.unused1 = 0xF0F0;
622 1 : hdr0.unused2 = 0xC5C5;
623 :
624 1 : memcpy(f.headerBeginBytes(), &hdr0, sizeof(hdr0));
625 :
626 1 : artdaq::detail::RawFragmentHeader::RawDataType counter = 0;
627 9 : for (size_t ii = artdaq::detail::RawFragmentHeaderV0::num_words(); ii < artdaq::detail::RawFragmentHeader::num_words() + 7; ++ii)
628 : {
629 8 : memcpy(f.headerBegin() + ii, &(++counter), sizeof(counter));
630 : }
631 :
632 1 : BOOST_REQUIRE_EQUAL(f.version(), 0);
633 1 : BOOST_REQUIRE_EQUAL(f.type(), 0xFE);
634 1 : BOOST_REQUIRE_EQUAL(f.hasMetadata(), false);
635 :
636 1 : BOOST_REQUIRE_EQUAL(f.sequenceID(), 0xFEEDDEADBEEF);
637 1 : BOOST_REQUIRE_EQUAL(f.fragmentID(), 0xBEE7);
638 1 : BOOST_REQUIRE_EQUAL(f.timestamp(), 0xCAFEFECA);
639 :
640 9 : for (size_t jj = 0; jj < f.dataSize(); ++jj)
641 : {
642 8 : BOOST_REQUIRE_EQUAL(*(f.dataBegin() + jj), jj + 1);
643 : }
644 1 : }
645 :
646 2 : BOOST_AUTO_TEST_CASE(Upgrade_V1)
647 : {
648 1 : artdaq::Fragment f(7);
649 : artdaq::detail::RawFragmentHeaderV1 hdr1;
650 :
651 1 : hdr1.word_count = artdaq::detail::RawFragmentHeader::num_words() + 7;
652 1 : hdr1.version = 1;
653 1 : hdr1.type = 0xFE;
654 1 : hdr1.metadata_word_count = 0;
655 :
656 1 : hdr1.sequence_id = 0xFEEDDEADBEEF;
657 1 : hdr1.fragment_id = 0xBEE7;
658 1 : hdr1.timestamp = 0xCAFEFECAAAAABBBB;
659 :
660 1 : memcpy(f.headerBeginBytes(), &hdr1, sizeof(hdr1));
661 :
662 1 : artdaq::detail::RawFragmentHeader::RawDataType counter = 0;
663 9 : for (size_t ii = artdaq::detail::RawFragmentHeaderV1::num_words(); ii < artdaq::detail::RawFragmentHeader::num_words() + 7; ++ii)
664 : {
665 8 : memcpy(f.headerBegin() + ii, &(++counter), sizeof(counter));
666 : }
667 :
668 1 : BOOST_REQUIRE_EQUAL(f.version(), 1);
669 1 : BOOST_REQUIRE_EQUAL(f.type(), 0xFE);
670 1 : BOOST_REQUIRE_EQUAL(f.hasMetadata(), false);
671 :
672 1 : BOOST_REQUIRE_EQUAL(f.sequenceID(), 0xFEEDDEADBEEF);
673 1 : BOOST_REQUIRE_EQUAL(f.fragmentID(), 0xBEE7);
674 1 : BOOST_REQUIRE_EQUAL(f.timestamp(), 0xCAFEFECAAAAABBBB);
675 :
676 9 : for (size_t jj = 0; jj < f.dataSize(); ++jj)
677 : {
678 8 : BOOST_REQUIRE_EQUAL(*(f.dataBegin() + jj), jj + 1); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
679 : }
680 1 : }
681 :
682 : BOOST_AUTO_TEST_SUITE_END()
|