1 | // |
2 | // PriorityNotificationQueueTest.cpp |
3 | // |
4 | // Copyright (c) 2009, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "PriorityNotificationQueueTest.h" |
12 | #include "Poco/CppUnit/TestCaller.h" |
13 | #include "Poco/CppUnit/TestSuite.h" |
14 | #include "Poco/PriorityNotificationQueue.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::PriorityNotificationQueue; |
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 | PriorityNotificationQueueTest::PriorityNotificationQueueTest(const std::string& rName): CppUnit::TestCase(rName) |
51 | { |
52 | } |
53 | |
54 | |
55 | PriorityNotificationQueueTest::~PriorityNotificationQueueTest() |
56 | { |
57 | } |
58 | |
59 | |
60 | void PriorityNotificationQueueTest::testQueueDequeue() |
61 | { |
62 | PriorityNotificationQueue queue; |
63 | assertTrue (queue.empty()); |
64 | assertTrue (queue.size() == 0); |
65 | Notification* pNf = queue.dequeueNotification(); |
66 | assertNullPtr(pNf); |
67 | queue.enqueueNotification(new Notification, 1); |
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" ), 1); |
77 | queue.enqueueNotification(new QTestNotification("fourth" ), 4); |
78 | queue.enqueueNotification(new QTestNotification("third" ), 3); |
79 | queue.enqueueNotification(new QTestNotification("second" ), 2); |
80 | assertTrue (!queue.empty()); |
81 | assertTrue (queue.size() == 4); |
82 | QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
83 | assertNotNullPtr(pTNf); |
84 | assertTrue (pTNf->data() == "first" ); |
85 | pTNf->release(); |
86 | assertTrue (!queue.empty()); |
87 | assertTrue (queue.size() == 3); |
88 | pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
89 | assertNotNullPtr(pTNf); |
90 | assertTrue (pTNf->data() == "second" ); |
91 | pTNf->release(); |
92 | assertTrue (!queue.empty()); |
93 | assertTrue (queue.size() == 2); |
94 | pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
95 | assertNotNullPtr(pTNf); |
96 | assertTrue (pTNf->data() == "third" ); |
97 | pTNf->release(); |
98 | assertTrue (!queue.empty()); |
99 | assertTrue (queue.size() == 1); |
100 | pTNf = dynamic_cast<QTestNotification*>(queue.dequeueNotification()); |
101 | assertNotNullPtr(pTNf); |
102 | assertTrue (pTNf->data() == "fourth" ); |
103 | pTNf->release(); |
104 | assertTrue (queue.empty()); |
105 | assertTrue (queue.size() == 0); |
106 | |
107 | pNf = queue.dequeueNotification(); |
108 | assertNullPtr(pNf); |
109 | } |
110 | |
111 | |
112 | void PriorityNotificationQueueTest::testWaitDequeue() |
113 | { |
114 | PriorityNotificationQueue queue; |
115 | queue.enqueueNotification(new QTestNotification("third" ), 3); |
116 | queue.enqueueNotification(new QTestNotification("fourth" ), 4); |
117 | assertTrue (!queue.empty()); |
118 | assertTrue (queue.size() == 2); |
119 | QTestNotification* pTNf = dynamic_cast<QTestNotification*>(queue.waitDequeueNotification(10)); |
120 | assertNotNullPtr(pTNf); |
121 | assertTrue (pTNf->data() == "third" ); |
122 | pTNf->release(); |
123 | assertTrue (!queue.empty()); |
124 | assertTrue (queue.size() == 1); |
125 | pTNf = dynamic_cast<QTestNotification*>(queue.waitDequeueNotification(10)); |
126 | assertNotNullPtr(pTNf); |
127 | assertTrue (pTNf->data() == "fourth" ); |
128 | pTNf->release(); |
129 | assertTrue (queue.empty()); |
130 | assertTrue (queue.size() == 0); |
131 | |
132 | Notification* pNf = queue.waitDequeueNotification(10); |
133 | assertNullPtr(pNf); |
134 | } |
135 | |
136 | |
137 | void PriorityNotificationQueueTest::testThreads() |
138 | { |
139 | const int NOTIFICATION_COUNT = 5000; |
140 | |
141 | Thread t1("thread1" ); |
142 | Thread t2("thread2" ); |
143 | Thread t3("thread3" ); |
144 | |
145 | RunnableAdapter<PriorityNotificationQueueTest> ra(*this, &PriorityNotificationQueueTest::work); |
146 | t1.start(ra); |
147 | t2.start(ra); |
148 | t3.start(ra); |
149 | for (int i = 0; i < NOTIFICATION_COUNT; ++i) |
150 | { |
151 | _queue.enqueueNotification(new Notification, 1); |
152 | } |
153 | while (!_queue.empty()) Thread::sleep(50); |
154 | Thread::sleep(20); |
155 | _queue.wakeUpAll(); |
156 | t1.join(); |
157 | t2.join(); |
158 | t3.join(); |
159 | assertTrue (_handled.size() == NOTIFICATION_COUNT); |
160 | assertTrue (_handled.count("thread1" ) > 0); |
161 | assertTrue (_handled.count("thread2" ) > 0); |
162 | assertTrue (_handled.count("thread3" ) > 0); |
163 | } |
164 | |
165 | |
166 | void PriorityNotificationQueueTest::testDefaultQueue() |
167 | { |
168 | PriorityNotificationQueue& queue = PriorityNotificationQueue::defaultQueue(); |
169 | assertTrue (queue.empty()); |
170 | assertTrue (queue.size() == 0); |
171 | } |
172 | |
173 | |
174 | void PriorityNotificationQueueTest::setUp() |
175 | { |
176 | _handled.clear(); |
177 | } |
178 | |
179 | |
180 | void PriorityNotificationQueueTest::tearDown() |
181 | { |
182 | } |
183 | |
184 | |
185 | void PriorityNotificationQueueTest::work() |
186 | { |
187 | Poco::Random rnd; |
188 | Thread::sleep(50); |
189 | Notification* pNf = _queue.waitDequeueNotification(); |
190 | while (pNf) |
191 | { |
192 | pNf->release(); |
193 | _mutex.lock(); |
194 | _handled.insert(Thread::current()->name()); |
195 | _mutex.unlock(); |
196 | Thread::sleep(rnd.next(5)); |
197 | pNf = _queue.waitDequeueNotification(); |
198 | } |
199 | } |
200 | |
201 | |
202 | CppUnit::Test* PriorityNotificationQueueTest::suite() |
203 | { |
204 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("PriorityNotificationQueueTest" ); |
205 | |
206 | CppUnit_addTest(pSuite, PriorityNotificationQueueTest, testQueueDequeue); |
207 | CppUnit_addTest(pSuite, PriorityNotificationQueueTest, testWaitDequeue); |
208 | CppUnit_addTest(pSuite, PriorityNotificationQueueTest, testThreads); |
209 | CppUnit_addTest(pSuite, PriorityNotificationQueueTest, testDefaultQueue); |
210 | |
211 | return pSuite; |
212 | } |
213 | |