1 #include "artdaq-core/Core/SharedMemoryManager.hh"
2 #include "artdaq-core/Utilities/TimeUtils.hh"
3 #include "artdaq-core/Utilities/configureMessageFacility.hh"
5 #define BOOST_TEST_MODULE SharedMemoryManager_t
6 #include "cetlib/quiet_unit_test.hpp"
7 #include "cetlib_except/exception.h"
9 #define TRACE_NAME "SharedMemoryManager_t"
10 #include "SharedMemoryTestShims.hh"
13 BOOST_AUTO_TEST_SUITE(SharedMemoryManager_test)
15 BOOST_AUTO_TEST_CASE(Construct)
18 TLOG(TLVL_DEBUG) <<
"BEGIN TEST Construct";
19 uint32_t key = GetRandomKey(0x7357);
21 BOOST_REQUIRE_EQUAL(man.IsValid(),
true);
22 BOOST_REQUIRE_EQUAL(man.GetMyId(), 0);
23 BOOST_REQUIRE_EQUAL(man.size(), 10);
24 BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 1);
25 BOOST_REQUIRE_EQUAL(man.GetKey(), key);
26 TLOG(TLVL_DEBUG) <<
"END TEST Construct";
29 BOOST_AUTO_TEST_CASE(Attach)
31 TLOG(TLVL_DEBUG) <<
"BEGIN TEST Attach";
32 uint32_t key = GetRandomKey(0x7357);
36 BOOST_REQUIRE_EQUAL(man.IsValid(),
true);
37 BOOST_REQUIRE_EQUAL(man.GetMyId(), 0);
38 BOOST_REQUIRE_EQUAL(man.size(), 10);
39 BOOST_REQUIRE_EQUAL(man.GetAttachedCount(), 2);
40 BOOST_REQUIRE_EQUAL(man.GetKey(), key);
42 BOOST_REQUIRE_EQUAL(man2.IsValid(),
true);
43 BOOST_REQUIRE_EQUAL(man2.GetMyId(), 1);
44 BOOST_REQUIRE_EQUAL(man2.size(), 10);
45 BOOST_REQUIRE_EQUAL(man2.GetAttachedCount(), 2);
46 BOOST_REQUIRE_EQUAL(man2.GetKey(), key);
48 TLOG(TLVL_DEBUG) <<
"END TEST Attach";
51 BOOST_AUTO_TEST_CASE(DataFlow)
53 TLOG(TLVL_DEBUG) <<
"BEGIN TEST DataFlow";
54 uint32_t key = GetRandomKey(0x7357);
58 BOOST_REQUIRE_EQUAL(man.ReadyForWrite(
false),
true);
59 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(
false), 10);
60 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
61 BOOST_REQUIRE_EQUAL(man.ReadReadyCount(), 0);
63 int buf = man.GetBufferForWriting(
false);
65 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1);
66 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf);
67 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0);
68 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0);
72 std::generate_n(data, 0x1000, [&]() {
return ++n; });
73 man.Write(buf, data, 0x1000);
74 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000);
75 BOOST_REQUIRE_EQUAL(man2.BufferDataSize(buf), 0x1000);
76 man.MarkBufferFull(buf, 1);
78 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0);
79 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 1);
81 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
82 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(),
true);
83 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1);
85 auto readbuf = man2.GetBufferForReading();
87 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
89 auto sts = man2.Read(readbuf, &byte, 1);
90 BOOST_REQUIRE_EQUAL(sts,
true);
91 BOOST_REQUIRE_EQUAL(byte, 1);
92 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
93 sts = man2.Read(readbuf, &byte, 1);
94 BOOST_REQUIRE_EQUAL(sts,
true);
95 BOOST_REQUIRE_EQUAL(byte, 2);
96 man2.IncrementReadPos(readbuf, 0x10);
97 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
98 sts = man2.Read(readbuf, &byte, 1);
99 BOOST_REQUIRE_EQUAL(sts,
true);
100 BOOST_REQUIRE_EQUAL(byte, 0x13);
101 man2.ResetReadPos(readbuf);
102 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
103 sts = man2.Read(readbuf, &byte, 1);
104 BOOST_REQUIRE_EQUAL(sts,
true);
105 BOOST_REQUIRE_EQUAL(byte, 1);
106 man2.IncrementReadPos(readbuf, 0xFFF);
107 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
false);
108 man2.MarkBufferEmpty(readbuf);
110 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0);
111 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0);
112 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(
false), 10);
113 TLOG(TLVL_DEBUG) <<
"END TEST DataFlow";
116 BOOST_AUTO_TEST_CASE(Exceptions)
119 TLOG(TLVL_DEBUG) <<
"BEGIN TEST Exceptions";
120 uint32_t key = GetRandomKey(0x7357);
123 BOOST_REQUIRE_EQUAL(man.ReadyForWrite(
false),
true);
124 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(
false), 10);
125 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
126 BOOST_REQUIRE_EQUAL(man.ReadReadyCount(), 0);
129 BOOST_REQUIRE_EXCEPTION(man.ResetReadPos(11), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
130 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
132 BOOST_REQUIRE_EXCEPTION(man.BufferDataSize(11), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
133 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
135 BOOST_REQUIRE_EXCEPTION(man.ResetWritePos(11), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
136 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
138 BOOST_REQUIRE_EXCEPTION(man.IncrementReadPos(11, 1), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
139 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
141 BOOST_REQUIRE_EXCEPTION(man.IncrementWritePos(11, 1), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
142 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
144 BOOST_REQUIRE_EXCEPTION(man.MoreDataInBuffer(11), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
145 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
148 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
150 BOOST_REQUIRE_EXCEPTION(man.MarkBufferFull(11), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
151 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
153 BOOST_REQUIRE_EXCEPTION(man.MarkBufferEmpty(11), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
154 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
156 BOOST_REQUIRE_EXCEPTION(man.ResetBuffer(11), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
157 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
160 BOOST_REQUIRE_EXCEPTION(man.Write(11, &dummy,
sizeof(dummy)), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
161 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
163 BOOST_REQUIRE_EXCEPTION(man.Read(11, &dummy,
sizeof(dummy)), cet::exception, [&](cet::exception e) {
return e.category() ==
"ArgumentOutOfRange"; });
164 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
168 BOOST_REQUIRE_EXCEPTION(man.MarkBufferEmpty(0), cet::exception, [&](cet::exception e) {
return e.category() ==
"StateAccessViolation"; });
169 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
174 int buf = man.GetBufferForWriting(
false);
176 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1);
177 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf);
178 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0);
181 uint8_t data[0x2000];
182 std::generate_n(data, 0x2000, [&]() {
return ++n; });
183 BOOST_REQUIRE_EXCEPTION(man.Write(buf, data, 0x2000), cet::exception, [&](cet::exception e) {
return e.category() ==
"SharedMemoryWrite"; });
184 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
188 buf = man.GetBufferForWriting(
false);
190 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1);
191 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf);
192 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0);
193 man.Write(buf, data, 0x1000);
194 man.MarkBufferFull(buf);
197 BOOST_REQUIRE_EQUAL(man2.IsValid(),
true);
198 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(),
true);
199 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1);
201 int readbuf = man2.GetBufferForReading();
202 BOOST_REQUIRE_EQUAL(readbuf, buf);
203 BOOST_REQUIRE_EXCEPTION(man2.Read(readbuf, data, 0x1001), cet::exception, [&](cet::exception e) {
return e.category() ==
"SharedMemoryRead"; });
204 BOOST_REQUIRE_EQUAL(man2.IsValid(),
false);
209 man.MarkBufferEmpty(readbuf,
true);
210 buf = man.GetBufferForWriting(
false);
212 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1);
213 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf);
214 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0);
215 man.Write(buf, data, 0x1000);
216 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1);
217 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf);
218 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000);
219 man.MarkBufferFull(buf);
220 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0);
221 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000);
223 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(),
true);
224 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1);
225 readbuf = man2.GetBufferForReading();
226 BOOST_REQUIRE_EQUAL(readbuf, buf);
227 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 1);
228 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager()[0], readbuf);
229 BOOST_REQUIRE_EQUAL(man2.BufferDataSize(readbuf), 0x1000);
231 BOOST_REQUIRE_EXCEPTION(man.MarkBufferEmpty(readbuf), cet::exception, [&](cet::exception e) {
return e.category() ==
"OwnerAccessViolation"; });
232 BOOST_REQUIRE_EQUAL(man.IsValid(),
false);
234 TLOG(TLVL_DEBUG) <<
"END TEST Exceptions";
237 BOOST_AUTO_TEST_CASE(Broadcast)
239 TLOG(TLVL_DEBUG) <<
"BEGIN TEST Broadcast";
240 uint32_t key = GetRandomKey(0x7357);
245 BOOST_REQUIRE_EQUAL(man.ReadyForWrite(
false),
true);
246 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(
false), 10);
247 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
248 BOOST_REQUIRE_EQUAL(man.ReadReadyCount(), 0);
250 int buf = man.GetBufferForWriting(
false);
252 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 1);
253 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager()[0], buf);
254 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0);
255 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0);
258 uint8_t data[0x1000];
259 std::generate_n(data, 0x1000, [&]() {
return ++n; });
260 man.Write(buf, data, 0x1000);
261 BOOST_REQUIRE_EQUAL(man.BufferDataSize(buf), 0x1000);
262 BOOST_REQUIRE_EQUAL(man2.BufferDataSize(buf), 0x1000);
263 man.MarkBufferFull(buf, -1);
265 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0);
267 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
268 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(),
true);
269 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 1);
271 auto readbuf = man2.GetBufferForReading();
272 BOOST_REQUIRE_EQUAL(readbuf, buf);
273 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 1);
274 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
275 BOOST_REQUIRE_EQUAL(man3.ReadyForRead(),
false);
277 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
279 auto sts = man2.Read(readbuf, &byte, 1);
280 BOOST_REQUIRE_EQUAL(sts,
true);
281 BOOST_REQUIRE_EQUAL(byte, 1);
282 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
283 sts = man2.Read(readbuf, &byte, 1);
284 BOOST_REQUIRE_EQUAL(sts,
true);
285 BOOST_REQUIRE_EQUAL(byte, 2);
286 man2.IncrementReadPos(readbuf, 0x10);
287 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
288 sts = man2.Read(readbuf, &byte, 1);
289 BOOST_REQUIRE_EQUAL(sts,
true);
290 BOOST_REQUIRE_EQUAL(byte, 0x13);
291 man2.ResetReadPos(readbuf);
292 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
true);
293 sts = man2.Read(readbuf, &byte, 1);
294 BOOST_REQUIRE_EQUAL(sts,
true);
295 BOOST_REQUIRE_EQUAL(byte, 1);
296 man2.IncrementReadPos(readbuf, 0xFFF);
297 BOOST_REQUIRE_EQUAL(man2.MoreDataInBuffer(readbuf),
false);
298 man2.MarkBufferEmpty(readbuf);
299 BOOST_REQUIRE_EQUAL(man3.ReadyForRead(),
true);
300 BOOST_REQUIRE_EQUAL(man3.ReadReadyCount(), 1);
301 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(),
false);
302 BOOST_REQUIRE_EQUAL(man2.ReadReadyCount(), 0);
303 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
305 readbuf = man3.GetBufferForReading();
306 BOOST_REQUIRE_EQUAL(readbuf, buf);
307 BOOST_REQUIRE_EQUAL(man3.GetBuffersOwnedByManager().size(), 1);
308 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
310 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf),
true);
311 sts = man3.Read(readbuf, &byte, 1);
312 BOOST_REQUIRE_EQUAL(sts,
true);
313 BOOST_REQUIRE_EQUAL(byte, 1);
314 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf),
true);
315 sts = man3.Read(readbuf, &byte, 1);
316 BOOST_REQUIRE_EQUAL(sts,
true);
317 BOOST_REQUIRE_EQUAL(byte, 2);
318 man3.IncrementReadPos(readbuf, 0x10);
319 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf),
true);
320 sts = man3.Read(readbuf, &byte, 1);
321 BOOST_REQUIRE_EQUAL(sts,
true);
322 BOOST_REQUIRE_EQUAL(byte, 0x13);
323 man3.ResetReadPos(readbuf);
324 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf),
true);
325 sts = man3.Read(readbuf, &byte, 1);
326 BOOST_REQUIRE_EQUAL(sts,
true);
327 BOOST_REQUIRE_EQUAL(byte, 1);
328 man3.IncrementReadPos(readbuf, 0xFFF);
329 BOOST_REQUIRE_EQUAL(man3.MoreDataInBuffer(readbuf),
false);
330 man3.MarkBufferEmpty(readbuf);
331 BOOST_REQUIRE_EQUAL(man3.ReadyForRead(),
false);
332 BOOST_REQUIRE_EQUAL(man2.ReadyForRead(),
false);
333 BOOST_REQUIRE_EQUAL(man.ReadyForRead(),
false);
335 BOOST_REQUIRE_EQUAL(man2.GetBuffersOwnedByManager().size(), 0);
336 BOOST_REQUIRE_EQUAL(man.GetBuffersOwnedByManager().size(), 0);
337 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(
false), 9);
338 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(
true), 10);
340 BOOST_REQUIRE_EQUAL(man.WriteReadyCount(
false), 10);
341 TLOG(TLVL_DEBUG) <<
"END TEST Broadcast";
344 BOOST_AUTO_TEST_SUITE_END()
The buffer is full, and waiting for a reader.
The buffer is currently being read from.
The buffer is currently being written to.
The SharedMemoryManager creates a Shared Memory area which is divided into a number of fixed-size buf...
void configureMessageFacility(char const *progname, bool useConsole=true, bool printDebug=false)
Configure and start the message facility. Provide the program name so that messages will be appropria...