1 | // |
2 | // FIFOEventTest.cpp |
3 | // |
4 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "FIFOEventTest.h" |
12 | #include "DummyDelegate.h" |
13 | #include "Poco/CppUnit/TestCaller.h" |
14 | #include "Poco/CppUnit/TestSuite.h" |
15 | #include "Poco/Delegate.h" |
16 | #include "Poco/Expire.h" |
17 | #include "Poco/Thread.h" |
18 | #include "Poco/Exception.h" |
19 | |
20 | |
21 | using namespace Poco; |
22 | |
23 | |
24 | #define LARGEINC 100 |
25 | |
26 | |
27 | FIFOEventTest::FIFOEventTest(const std::string& rName): CppUnit::TestCase(rName) |
28 | { |
29 | } |
30 | |
31 | |
32 | FIFOEventTest::~FIFOEventTest() |
33 | { |
34 | } |
35 | |
36 | void FIFOEventTest::testNoDelegate() |
37 | { |
38 | int tmp = 0; |
39 | EventArgs args; |
40 | |
41 | assertTrue (_count == 0); |
42 | Void.notify(this); |
43 | assertTrue (_count == 0); |
44 | |
45 | Void += delegate(this, &FIFOEventTest::onVoid); |
46 | Void -= delegate(this, &FIFOEventTest::onVoid); |
47 | Void.notify(this); |
48 | assertTrue (_count == 0); |
49 | |
50 | Simple.notify(this, tmp); |
51 | assertTrue (_count == 0); |
52 | |
53 | Simple += delegate(this, &FIFOEventTest::onSimple); |
54 | Simple -= delegate(this, &FIFOEventTest::onSimple); |
55 | Simple.notify(this, tmp); |
56 | assertTrue (_count == 0); |
57 | |
58 | ConstSimple += delegate(this, &FIFOEventTest::onConstSimple); |
59 | ConstSimple -= delegate(this, &FIFOEventTest::onConstSimple); |
60 | ConstSimple.notify(this, tmp); |
61 | assertTrue (_count == 0); |
62 | |
63 | //Note: passing &args will not work due to & |
64 | EventArgs* pArgs = &args; |
65 | Complex += delegate(this, &FIFOEventTest::onComplex); |
66 | Complex -= delegate(this, &FIFOEventTest::onComplex); |
67 | Complex.notify(this, pArgs); |
68 | assertTrue (_count == 0); |
69 | |
70 | Complex2 += delegate(this, &FIFOEventTest::onComplex2); |
71 | Complex2 -= delegate(this, &FIFOEventTest::onComplex2); |
72 | Complex2.notify(this, args); |
73 | assertTrue (_count == 0); |
74 | |
75 | const EventArgs* pCArgs = &args; |
76 | ConstComplex += delegate(this, &FIFOEventTest::onConstComplex); |
77 | ConstComplex -= delegate(this, &FIFOEventTest::onConstComplex); |
78 | ConstComplex.notify(this, pCArgs); |
79 | assertTrue (_count == 0); |
80 | |
81 | Const2Complex += delegate(this, &FIFOEventTest::onConst2Complex); |
82 | Const2Complex -= delegate(this, &FIFOEventTest::onConst2Complex); |
83 | Const2Complex.notify(this, pArgs); |
84 | assertTrue (_count == 0); |
85 | } |
86 | |
87 | void FIFOEventTest::testSingleDelegate() |
88 | { |
89 | int tmp = 0; |
90 | EventArgs args; |
91 | |
92 | assertTrue (_count == 0); |
93 | |
94 | Void += delegate(this, &FIFOEventTest::onVoid); |
95 | Void.notify(this); |
96 | assertTrue (_count == 1); |
97 | |
98 | Simple += delegate(this, &FIFOEventTest::onSimple); |
99 | Simple.notify(this, tmp); |
100 | assertTrue (_count == 2); |
101 | |
102 | ConstSimple += delegate(this, &FIFOEventTest::onConstSimple); |
103 | ConstSimple.notify(this, tmp); |
104 | assertTrue (_count == 3); |
105 | |
106 | EventArgs* pArgs = &args; |
107 | Complex += delegate(this, &FIFOEventTest::onComplex); |
108 | Complex.notify(this, pArgs); |
109 | assertTrue (_count == 4); |
110 | |
111 | Complex2 += delegate(this, &FIFOEventTest::onComplex2); |
112 | Complex2.notify(this, args); |
113 | assertTrue (_count == 5); |
114 | |
115 | const EventArgs* pCArgs = &args; |
116 | ConstComplex += delegate(this, &FIFOEventTest::onConstComplex); |
117 | ConstComplex.notify(this, pCArgs); |
118 | assertTrue (_count == 6); |
119 | |
120 | Const2Complex += delegate(this, &FIFOEventTest::onConst2Complex); |
121 | Const2Complex.notify(this, pArgs); |
122 | assertTrue (_count == 7); |
123 | // check if 2nd notify also works |
124 | Const2Complex.notify(this, pArgs); |
125 | assertTrue (_count == 8); |
126 | |
127 | } |
128 | |
129 | void FIFOEventTest::testDuplicateRegister() |
130 | { |
131 | int tmp = 0; |
132 | |
133 | assertTrue (_count == 0); |
134 | |
135 | Simple += delegate(this, &FIFOEventTest::onSimple); |
136 | Simple += delegate(this, &FIFOEventTest::onSimple); |
137 | Simple.notify(this, tmp); |
138 | assertTrue (_count == 2); |
139 | Simple -= delegate(this, &FIFOEventTest::onSimple); |
140 | Simple.notify(this, tmp); |
141 | assertTrue (_count == 3); |
142 | } |
143 | |
144 | void FIFOEventTest::testDuplicateUnregister() |
145 | { |
146 | // duplicate unregister shouldn't give an error, |
147 | int tmp = 0; |
148 | |
149 | assertTrue (_count == 0); |
150 | |
151 | Simple -= delegate(this, &FIFOEventTest::onSimple); // should work |
152 | Simple.notify(this, tmp); |
153 | assertTrue (_count == 0); |
154 | |
155 | Simple += delegate(this, &FIFOEventTest::onSimple); |
156 | Simple.notify(this, tmp); |
157 | assertTrue (_count == 1); |
158 | |
159 | Simple -= delegate(this, &FIFOEventTest::onSimple); |
160 | Simple.notify(this, tmp); |
161 | assertTrue (_count == 1); |
162 | |
163 | Simple -= delegate(this, &FIFOEventTest::onSimple); |
164 | Simple.notify(this, tmp); |
165 | assertTrue (_count == 1); |
166 | } |
167 | |
168 | |
169 | void FIFOEventTest::testDisabling() |
170 | { |
171 | int tmp = 0; |
172 | |
173 | assertTrue (_count == 0); |
174 | |
175 | Simple += delegate(this, &FIFOEventTest::onSimple); |
176 | Simple.disable(); |
177 | Simple.notify(this, tmp); |
178 | assertTrue (_count == 0); |
179 | Simple.enable(); |
180 | Simple.notify(this, tmp); |
181 | assertTrue (_count == 1); |
182 | |
183 | // unregister should also work with disabled event |
184 | Simple.disable(); |
185 | Simple -= delegate(this, &FIFOEventTest::onSimple); |
186 | Simple.enable(); |
187 | Simple.notify(this, tmp); |
188 | assertTrue (_count == 1); |
189 | } |
190 | |
191 | void FIFOEventTest::testFIFOOrder() |
192 | { |
193 | DummyDelegate o1; |
194 | DummyDelegate o2; |
195 | |
196 | assertTrue (_count == 0); |
197 | |
198 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
199 | Simple += delegate(&o2, &DummyDelegate::onSimple2); |
200 | int tmp = 0; |
201 | Simple.notify(this, tmp); |
202 | assertTrue (tmp == 2); |
203 | |
204 | Simple -= delegate(&o1, &DummyDelegate::onSimple); |
205 | Simple -= delegate(&o2, &DummyDelegate::onSimple2); |
206 | |
207 | // now try with the wrong order |
208 | Simple += delegate(&o2, &DummyDelegate::onSimple2); |
209 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
210 | |
211 | try |
212 | { |
213 | tmp = 0; |
214 | Simple.notify(this, tmp); |
215 | failmsg ("Notify should not work" ); |
216 | } |
217 | catch (Poco::InvalidArgumentException&) |
218 | { |
219 | } |
220 | } |
221 | |
222 | void FIFOEventTest::testFIFOOrderExpire() |
223 | { |
224 | // expire must not break order! |
225 | DummyDelegate o1; |
226 | DummyDelegate o2; |
227 | |
228 | assertTrue (_count == 0); |
229 | |
230 | Simple += delegate(&o1, &DummyDelegate::onSimple, 5000); |
231 | Simple += delegate(&o2, &DummyDelegate::onSimple2, 5000); |
232 | int tmp = 0; |
233 | Simple.notify(this, tmp); |
234 | assertTrue (tmp == 2); |
235 | |
236 | // both ways of unregistering should work |
237 | Simple -= delegate(&o1, &DummyDelegate::onSimple, 6000); |
238 | Simple -= delegate(&o2, &DummyDelegate::onSimple2); |
239 | Simple.notify(this, tmp); |
240 | assertTrue (tmp == 2); |
241 | |
242 | // now start mixing of expire and non expire |
243 | tmp = 0; |
244 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
245 | Simple += delegate(&o2, &DummyDelegate::onSimple2, 5000); |
246 | Simple.notify(this, tmp); |
247 | assertTrue (tmp == 2); |
248 | |
249 | Simple -= delegate(&o2, &DummyDelegate::onSimple2); |
250 | // it is not forbidden to unregister a non expiring event with an expire decorator (it is just stupid ;-)) |
251 | Simple -= delegate(&o1, &DummyDelegate::onSimple, 6000); |
252 | Simple.notify(this, tmp); |
253 | assertTrue (tmp == 2); |
254 | |
255 | // now try with the wrong order |
256 | Simple += delegate(&o2, &DummyDelegate::onSimple2, 5000); |
257 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
258 | |
259 | try |
260 | { |
261 | tmp = 0; |
262 | Simple.notify(this, tmp); |
263 | failmsg ("Notify should not work" ); |
264 | } |
265 | catch (Poco::InvalidArgumentException&) |
266 | { |
267 | |
268 | } |
269 | |
270 | } |
271 | |
272 | void FIFOEventTest::testExpire() |
273 | { |
274 | int tmp = 0; |
275 | |
276 | assertTrue (_count == 0); |
277 | |
278 | Simple += delegate(this, &FIFOEventTest::onSimple, 500); |
279 | Simple.notify(this, tmp); |
280 | assertTrue (_count == 1); |
281 | Poco::Thread::sleep(700); |
282 | Simple.notify(this, tmp); |
283 | assertTrue (_count == 1); |
284 | } |
285 | |
286 | |
287 | void FIFOEventTest::testExpireReRegister() |
288 | { |
289 | int tmp = 0; |
290 | |
291 | assertTrue (_count == 0); |
292 | |
293 | Simple += delegate(this, &FIFOEventTest::onSimple, 500); |
294 | Simple.notify(this, tmp); |
295 | assertTrue (_count == 1); |
296 | Poco::Thread::sleep(200); |
297 | Simple.notify(this, tmp); |
298 | assertTrue (_count == 2); |
299 | // renew registration |
300 | Simple += delegate(this, &FIFOEventTest::onSimple, 600); |
301 | Poco::Thread::sleep(400); |
302 | Simple.notify(this, tmp); |
303 | assertTrue (_count == 3); |
304 | Poco::Thread::sleep(300); |
305 | Simple.notify(this, tmp); |
306 | assertTrue (_count == 3); |
307 | } |
308 | |
309 | |
310 | void FIFOEventTest::testReturnParams() |
311 | { |
312 | DummyDelegate o1; |
313 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
314 | |
315 | int tmp = 0; |
316 | Simple.notify(this, tmp); |
317 | assertTrue (tmp == 1); |
318 | } |
319 | |
320 | void FIFOEventTest::testOverwriteDelegate() |
321 | { |
322 | DummyDelegate o1; |
323 | Simple += delegate(&o1, &DummyDelegate::onSimple); |
324 | Simple += delegate(&o1, &DummyDelegate::onSimple2); |
325 | |
326 | int tmp = 0; // onsimple requires 0 as input |
327 | Simple.notify(this, tmp); |
328 | assertTrue (tmp == 2); |
329 | } |
330 | |
331 | void FIFOEventTest::testAsyncNotify() |
332 | { |
333 | Poco::FIFOEvent<int >* pSimple= new Poco::FIFOEvent<int>(); |
334 | (*pSimple) += delegate(this, &FIFOEventTest::onAsync); |
335 | assertTrue (_count == 0); |
336 | int tmp = 0; |
337 | Poco::ActiveResult<int>retArg = pSimple->notifyAsync(this, tmp); |
338 | delete pSimple; // must work even when the event got deleted! |
339 | pSimple = NULL; |
340 | assertTrue (_count == 0); |
341 | retArg.wait(); |
342 | assertTrue (retArg.data() == tmp); |
343 | assertTrue (_count == LARGEINC); |
344 | } |
345 | |
346 | void FIFOEventTest::onVoid(const void* pSender) |
347 | { |
348 | _count++; |
349 | } |
350 | |
351 | void FIFOEventTest::onSimple(const void* pSender, int& i) |
352 | { |
353 | _count++; |
354 | } |
355 | |
356 | void FIFOEventTest::onSimpleOther(const void* pSender, int& i) |
357 | { |
358 | _count+=100; |
359 | } |
360 | |
361 | void FIFOEventTest::onConstSimple(const void* pSender, const int& i) |
362 | { |
363 | _count++; |
364 | } |
365 | |
366 | void FIFOEventTest::onComplex(const void* pSender, Poco::EventArgs* & i) |
367 | { |
368 | _count++; |
369 | } |
370 | |
371 | void FIFOEventTest::onComplex2(const void* pSender, Poco::EventArgs & i) |
372 | { |
373 | _count++; |
374 | } |
375 | |
376 | void FIFOEventTest::onConstComplex(const void* pSender, const Poco::EventArgs*& i) |
377 | { |
378 | _count++; |
379 | } |
380 | |
381 | void FIFOEventTest::onConst2Complex(const void* pSender, const Poco::EventArgs * const & i) |
382 | { |
383 | _count++; |
384 | } |
385 | |
386 | void FIFOEventTest::onAsync(const void* pSender, int& i) |
387 | { |
388 | Poco::Thread::sleep(700); |
389 | _count += LARGEINC ; |
390 | } |
391 | |
392 | int FIFOEventTest::getCount() const |
393 | { |
394 | return _count; |
395 | } |
396 | |
397 | void FIFOEventTest::setUp() |
398 | { |
399 | _count = 0; |
400 | // must clear events, otherwise repeating test executions will fail |
401 | // because tests are only created once, only setup is called before |
402 | // each test run |
403 | Void.clear(); |
404 | Simple.clear(); |
405 | ConstSimple.clear(); |
406 | Complex.clear(); |
407 | Complex2.clear(); |
408 | ConstComplex.clear(); |
409 | Const2Complex.clear(); |
410 | } |
411 | |
412 | |
413 | void FIFOEventTest::tearDown() |
414 | { |
415 | } |
416 | |
417 | |
418 | CppUnit::Test* FIFOEventTest::suite() |
419 | { |
420 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("FIFOEventTest" ); |
421 | |
422 | CppUnit_addTest(pSuite, FIFOEventTest, testNoDelegate); |
423 | CppUnit_addTest(pSuite, FIFOEventTest, testSingleDelegate); |
424 | CppUnit_addTest(pSuite, FIFOEventTest, testReturnParams); |
425 | CppUnit_addTest(pSuite, FIFOEventTest, testDuplicateRegister); |
426 | CppUnit_addTest(pSuite, FIFOEventTest, testDuplicateUnregister); |
427 | CppUnit_addTest(pSuite, FIFOEventTest, testDisabling); |
428 | CppUnit_addTest(pSuite, FIFOEventTest, testFIFOOrder); |
429 | CppUnit_addTest(pSuite, FIFOEventTest, testFIFOOrderExpire); |
430 | CppUnit_addTest(pSuite, FIFOEventTest, testExpire); |
431 | CppUnit_addTest(pSuite, FIFOEventTest, testExpireReRegister); |
432 | CppUnit_addTest(pSuite, FIFOEventTest, testOverwriteDelegate); |
433 | CppUnit_addTest(pSuite, FIFOEventTest, testAsyncNotify); |
434 | return pSuite; |
435 | } |
436 | |