1 | // |
2 | // NotificationQueueTest.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 "NotificationQueueTest.h" |
12 | #include "Poco/CppUnit/TestCaller.h" |
13 | #include "Poco/CppUnit/TestSuite.h" |
14 | #include "Poco/NotificationQueue.h" |
15 | #include "Poco/Notification.h" |
16 | #include "Poco/Thread.h" |
17 | #include "Poco/Runnable.h" |
18 | #include "Poco/RunnableAdapter.h" |
19 | #include "Poco/Random.h" |
20 | |
21 | |
22 | using Poco::NotificationQueue; |
23 | using Poco::Notification; |
24 | using Poco::Thread; |
25 | using Poco::RunnableAdapter; |
26 | |
27 | |
28 | namespace |
29 | { |
30 | class QTestNotification: public Notification |
31 | { |
32 | public: |
33 | QTestNotification(const std::string& data): _data(data) |
34 | { |
35 | } |
36 | ~QTestNotification() |
37 | { |
38 | } |
39 | const std::string& data() const |
40 | { |
41 | return _data; |
42 | } |
43 | |
44 | private: |
45 | std::string _data; |
46 | }; |
47 | } |
48 | |
49 | |
50 | NotificationQueueTest::NotificationQueueTest(const std::string& rName): CppUnit::TestCase(rName) |
51 | { |
52 | } |
53 | |
54 | |
55 | NotificationQueueTest::~NotificationQueueTest() |
56 | { |
57 | } |
58 | |
59 | |
60 | void NotificationQueueTest::testQueueDequeue() |
61 | { |
62 | NotificationQueue queue; |
63 | assertTrue (queue.empty()); |
64 | assertTrue (queue.size() == 0); |
65 | Notification* pNf = queue.dequeueNotification(); |
66 | assertNullPtr(pNf); |
67 | queue.enqueueNotification(new Notification); |
68 | assertTrue (!queue.empty()); |
69 | assertTrue (queue.size() == 1); |
70 | pNf = queue.dequeueNotification(); |
71 | assertNotNullPtr(pNf); |
72 | assertTrue (queue.empty()); |
73 | assertTrue (queue.size() == 0); |
74 | pNf->release(); |
75 | |
76 | queue.enqueueNotification(new QTestNotification("first" )); |
77 | queue.enqueueNotification(new QTestNotification("second" )); |
78 | assertTrue (!queue.empty()); |
79 | assertTrue (queue.size() == 2); |
80 | QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
81 | assertNotNullPtr(pTNf); |
82 | assertTrue (pTNf->data() == "first" ); |
83 | pTNf->release(); |
84 | assertTrue (!queue.empty()); |
85 | assertTrue (queue.size() == 1); |
86 | pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
87 | assertNotNullPtr(pTNf); |
88 | assertTrue (pTNf->data() == "second" ); |
89 | pTNf->release(); |
90 | assertTrue (queue.empty()); |
91 | assertTrue (queue.size() == 0); |
92 | |
93 | pNf = queue.dequeueNotification(); |
94 | assertNullPtr(pNf); |
95 | } |
96 | |
97 | |
98 | void NotificationQueueTest::testQueueDequeueUrgent() |
99 | { |
100 | NotificationQueue queue; |
101 | queue.enqueueNotification(new QTestNotification("first" )); |
102 | queue.enqueueNotification(new QTestNotification("second" )); |
103 | queue.enqueueUrgentNotification(new QTestNotification("third" )); |
104 | assertTrue (!queue.empty()); |
105 | assertTrue (queue.size() == 3); |
106 | QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
107 | assertNotNullPtr(pTNf); |
108 | assertTrue (pTNf->data() == "third" ); |
109 | pTNf->release(); |
110 | assertTrue (!queue.empty()); |
111 | assertTrue (queue.size() == 2); |
112 | pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
113 | assertTrue (pTNf->data() == "first" ); |
114 | pTNf->release(); |
115 | assertTrue (!queue.empty()); |
116 | assertTrue (queue.size() == 1); |
117 | pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
118 | assertNotNullPtr(pTNf); |
119 | assertTrue (pTNf->data() == "second" ); |
120 | pTNf->release(); |
121 | assertTrue (queue.empty()); |
122 | assertTrue (queue.size() == 0); |
123 | |
124 | Notification* pNf = queue.dequeueNotification(); |
125 | assertNullPtr(pNf); |
126 | } |
127 | |
128 | |
129 | void NotificationQueueTest::testWaitDequeue() |
130 | { |
131 | NotificationQueue queue; |
132 | queue.enqueueNotification(new QTestNotification("third" )); |
133 | queue.enqueueNotification(new QTestNotification("fourth" )); |
134 | assertTrue (!queue.empty()); |
135 | assertTrue (queue.size() == 2); |
136 | QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.waitDequeueNotification(10)); |
137 | assertNotNullPtr(pTNf); |
138 | assertTrue (pTNf->data() == "third" ); |
139 | pTNf->release(); |
140 | assertTrue (!queue.empty()); |
141 | assertTrue (queue.size() == 1); |
142 | pTNf = dynamic_cast<QTestNotification*>(queue.waitDequeueNotification(10)); |
143 | assertNotNullPtr(pTNf); |
144 | assertTrue (pTNf->data() == "fourth" ); |
145 | pTNf->release(); |
146 | assertTrue (queue.empty()); |
147 | assertTrue (queue.size() == 0); |
148 | |
149 | Notification* pNf = queue.waitDequeueNotification(10); |
150 | assertNullPtr(pNf); |
151 | } |
152 | |
153 | |
154 | void NotificationQueueTest::testThreads() |
155 | { |
156 | const int NOTIFICATION_COUNT = 5000; |
157 | |
158 | Thread t1("thread1" ); |
159 | Thread t2("thread2" ); |
160 | Thread t3("thread3" ); |
161 | |
162 | RunnableAdapter<NotificationQueueTest> ra(*this, &NotificationQueueTest::work); |
163 | t1.start(ra); |
164 | t2.start(ra); |
165 | t3.start(ra); |
166 | for (int i = 0; i < NOTIFICATION_COUNT; ++i) |
167 | { |
168 | _queue.enqueueNotification(new Notification); |
169 | } |
170 | while (!_queue.empty()) Thread::sleep(50); |
171 | Thread::sleep(20); |
172 | _queue.wakeUpAll(); |
173 | t1.join(); |
174 | t2.join(); |
175 | t3.join(); |
176 | assertTrue (_handled.size() == NOTIFICATION_COUNT); |
177 | assertTrue (_handled.count("thread1" ) > 0); |
178 | assertTrue (_handled.count("thread2" ) > 0); |
179 | assertTrue (_handled.count("thread3" ) > 0); |
180 | } |
181 | |
182 | |
183 | void NotificationQueueTest::testDefaultQueue() |
184 | { |
185 | NotificationQueue& queue = NotificationQueue::defaultQueue(); |
186 | assertTrue (queue.empty()); |
187 | assertTrue (queue.size() == 0); |
188 | } |
189 | |
190 | |
191 | void NotificationQueueTest::testQueueRemove() |
192 | { |
193 | NotificationQueue queue; |
194 | Notification::Ptr frontNotification = new QTestNotification("front" ); |
195 | Notification::Ptr middleNotification = new QTestNotification("middle" ); |
196 | Notification::Ptr backNotification = new QTestNotification("back" ); |
197 | queue.enqueueNotification(frontNotification); |
198 | queue.enqueueNotification(new QTestNotification("dummy" )); |
199 | queue.enqueueNotification(middleNotification); |
200 | queue.enqueueNotification(new QTestNotification("dummy" )); |
201 | queue.enqueueNotification(backNotification); |
202 | assertTrue (queue.size() == 5); |
203 | assertTrue (queue.remove(frontNotification)); |
204 | assertTrue (queue.size() == 4); |
205 | assertTrue (queue.remove(middleNotification)); |
206 | assertTrue (queue.size() == 3); |
207 | assertTrue (queue.remove(backNotification)); |
208 | assertTrue (queue.size() == 2); |
209 | assertTrue (!queue.remove(backNotification)); |
210 | assertTrue (queue.size() == 2); |
211 | } |
212 | |
213 | |
214 | void NotificationQueueTest::setUp() |
215 | { |
216 | _handled.clear(); |
217 | } |
218 | |
219 | |
220 | void NotificationQueueTest::tearDown() |
221 | { |
222 | } |
223 | |
224 | |
225 | void NotificationQueueTest::work() |
226 | { |
227 | Poco::Random rnd; |
228 | Thread::sleep(50); |
229 | Notification* pNf = _queue.waitDequeueNotification(); |
230 | while (pNf) |
231 | { |
232 | pNf->release(); |
233 | _mutex.lock(); |
234 | _handled.insert(Thread::current()->name()); |
235 | _mutex.unlock(); |
236 | Thread::sleep(rnd.next(5)); |
237 | pNf = _queue.waitDequeueNotification(); |
238 | } |
239 | } |
240 | |
241 | |
242 | CppUnit::Test* NotificationQueueTest::suite() |
243 | { |
244 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NotificationQueueTest" ); |
245 | |
246 | CppUnit_addTest(pSuite, NotificationQueueTest, testQueueDequeue); |
247 | CppUnit_addTest(pSuite, NotificationQueueTest, testQueueDequeueUrgent); |
248 | CppUnit_addTest(pSuite, NotificationQueueTest, testWaitDequeue); |
249 | CppUnit_addTest(pSuite, NotificationQueueTest, testThreads); |
250 | CppUnit_addTest(pSuite, NotificationQueueTest, testDefaultQueue); |
251 | CppUnit_addTest(pSuite, NotificationQueueTest, testQueueRemove); |
252 | |
253 | return pSuite; |
254 | } |
255 | |