1 | // |
2 | // TCPServerTest.cpp |
3 | // |
4 | // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "TCPServerTest.h" |
12 | #include "Poco/CppUnit/TestCaller.h" |
13 | #include "Poco/CppUnit/TestSuite.h" |
14 | #include "Poco/Net/TCPServer.h" |
15 | #include "Poco/Net/TCPServerConnection.h" |
16 | #include "Poco/Net/TCPServerConnectionFactory.h" |
17 | #include "Poco/Net/TCPServerParams.h" |
18 | #include "Poco/Net/StreamSocket.h" |
19 | #include "Poco/Net/ServerSocket.h" |
20 | #include "Poco/Thread.h" |
21 | #include <iostream> |
22 | |
23 | |
24 | using Poco::Net::TCPServer; |
25 | using Poco::Net::TCPServerConnectionFilter; |
26 | using Poco::Net::TCPServerConnection; |
27 | using Poco::Net::TCPServerConnectionFactory; |
28 | using Poco::Net::TCPServerConnectionFactoryImpl; |
29 | using Poco::Net::TCPServerParams; |
30 | using Poco::Net::StreamSocket; |
31 | using Poco::Net::ServerSocket; |
32 | using Poco::Net::SocketAddress; |
33 | using Poco::Thread; |
34 | |
35 | |
36 | namespace |
37 | { |
38 | class EchoConnection: public TCPServerConnection |
39 | { |
40 | public: |
41 | EchoConnection(const StreamSocket& s): TCPServerConnection(s) |
42 | { |
43 | } |
44 | |
45 | void run() |
46 | { |
47 | StreamSocket& ss = socket(); |
48 | try |
49 | { |
50 | char buffer[256]; |
51 | int n = ss.receiveBytes(buffer, sizeof(buffer)); |
52 | while (n > 0) |
53 | { |
54 | ss.sendBytes(buffer, n); |
55 | n = ss.receiveBytes(buffer, sizeof(buffer)); |
56 | } |
57 | } |
58 | catch (Poco::Exception& exc) |
59 | { |
60 | std::cerr << "EchoConnection: " << exc.displayText() << std::endl; |
61 | } |
62 | } |
63 | }; |
64 | |
65 | class RejectFilter: public TCPServerConnectionFilter |
66 | { |
67 | public: |
68 | bool accept(const StreamSocket&) |
69 | { |
70 | return false; |
71 | } |
72 | }; |
73 | } |
74 | |
75 | |
76 | TCPServerTest::TCPServerTest(const std::string& name): CppUnit::TestCase(name) |
77 | { |
78 | } |
79 | |
80 | |
81 | TCPServerTest::~TCPServerTest() |
82 | { |
83 | } |
84 | |
85 | |
86 | void TCPServerTest::testOneConnection() |
87 | { |
88 | TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>()); |
89 | srv.start(); |
90 | assertTrue (srv.currentConnections() == 0); |
91 | assertTrue (srv.currentThreads() == 0); |
92 | assertTrue (srv.queuedConnections() == 0); |
93 | assertTrue (srv.totalConnections() == 0); |
94 | |
95 | SocketAddress sa("127.0.0.1" , srv.socket().address().port()); |
96 | StreamSocket ss1(sa); |
97 | std::string data("hello, world" ); |
98 | ss1.sendBytes(data.data(), (int) data.size()); |
99 | char buffer[256]; |
100 | int n = ss1.receiveBytes(buffer, sizeof(buffer)); |
101 | assertTrue (n > 0); |
102 | assertTrue (std::string(buffer, n) == data); |
103 | assertTrue (srv.currentConnections() == 1); |
104 | assertTrue (srv.currentThreads() == 1); |
105 | assertTrue (srv.queuedConnections() == 0); |
106 | assertTrue (srv.totalConnections() == 1); |
107 | ss1.close(); |
108 | Thread::sleep(1000); |
109 | assertTrue (srv.currentConnections() == 0); |
110 | } |
111 | |
112 | |
113 | void TCPServerTest::testTwoConnections() |
114 | { |
115 | TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>()); |
116 | srv.start(); |
117 | assertTrue (srv.currentConnections() == 0); |
118 | assertTrue (srv.currentThreads() == 0); |
119 | assertTrue (srv.queuedConnections() == 0); |
120 | assertTrue (srv.totalConnections() == 0); |
121 | |
122 | SocketAddress sa("127.0.0.1" , srv.socket().address().port()); |
123 | StreamSocket ss1(sa); |
124 | StreamSocket ss2(sa); |
125 | std::string data("hello, world" ); |
126 | ss1.sendBytes(data.data(), (int) data.size()); |
127 | ss2.sendBytes(data.data(), (int) data.size()); |
128 | |
129 | char buffer[256]; |
130 | int n = ss1.receiveBytes(buffer, sizeof(buffer)); |
131 | assertTrue (n > 0); |
132 | assertTrue (std::string(buffer, n) == data); |
133 | |
134 | n = ss2.receiveBytes(buffer, sizeof(buffer)); |
135 | assertTrue (n > 0); |
136 | assertTrue (std::string(buffer, n) == data); |
137 | |
138 | assertTrue (srv.currentConnections() == 2); |
139 | assertTrue (srv.currentThreads() == 2); |
140 | assertTrue (srv.queuedConnections() == 0); |
141 | assertTrue (srv.totalConnections() == 2); |
142 | ss1.close(); |
143 | Thread::sleep(1000); |
144 | assertTrue (srv.currentConnections() == 1); |
145 | assertTrue (srv.currentThreads() == 1); |
146 | assertTrue (srv.queuedConnections() == 0); |
147 | assertTrue (srv.totalConnections() == 2); |
148 | ss2.close(); |
149 | |
150 | Thread::sleep(1000); |
151 | assertTrue (srv.currentConnections() == 0); |
152 | } |
153 | |
154 | |
155 | void TCPServerTest::testMultiConnections() |
156 | { |
157 | ServerSocket svs(0); |
158 | TCPServerParams* pParams = new TCPServerParams; |
159 | pParams->setMaxThreads(4); |
160 | pParams->setMaxQueued(4); |
161 | pParams->setThreadIdleTime(100); |
162 | TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs, pParams); |
163 | srv.start(); |
164 | assertTrue (srv.currentConnections() == 0); |
165 | assertTrue (srv.currentThreads() == 0); |
166 | assertTrue (srv.maxThreads() >= 4); |
167 | assertTrue (srv.queuedConnections() == 0); |
168 | assertTrue (srv.totalConnections() == 0); |
169 | |
170 | SocketAddress sa("127.0.0.1" , svs.address().port()); |
171 | StreamSocket ss1(sa); |
172 | StreamSocket ss2(sa); |
173 | StreamSocket ss3(sa); |
174 | StreamSocket ss4(sa); |
175 | std::string data("hello, world" ); |
176 | ss1.sendBytes(data.data(), (int) data.size()); |
177 | ss2.sendBytes(data.data(), (int) data.size()); |
178 | ss3.sendBytes(data.data(), (int) data.size()); |
179 | ss4.sendBytes(data.data(), (int) data.size()); |
180 | |
181 | char buffer[256]; |
182 | int n = ss1.receiveBytes(buffer, sizeof(buffer)); |
183 | assertTrue (n > 0); |
184 | assertTrue (std::string(buffer, n) == data); |
185 | |
186 | n = ss2.receiveBytes(buffer, sizeof(buffer)); |
187 | assertTrue (n > 0); |
188 | assertTrue (std::string(buffer, n) == data); |
189 | |
190 | n = ss3.receiveBytes(buffer, sizeof(buffer)); |
191 | assertTrue (n > 0); |
192 | assertTrue (std::string(buffer, n) == data); |
193 | |
194 | n = ss4.receiveBytes(buffer, sizeof(buffer)); |
195 | assertTrue (n > 0); |
196 | assertTrue (std::string(buffer, n) == data); |
197 | |
198 | assertTrue (srv.currentConnections() == 4); |
199 | assertTrue (srv.currentThreads() == 4); |
200 | assertTrue (srv.queuedConnections() == 0); |
201 | assertTrue (srv.totalConnections() == 4); |
202 | |
203 | StreamSocket ss5(sa); |
204 | Thread::sleep(200); |
205 | assertTrue (srv.queuedConnections() == 1); |
206 | StreamSocket ss6(sa); |
207 | Thread::sleep(200); |
208 | assertTrue (srv.queuedConnections() == 2); |
209 | |
210 | ss1.close(); |
211 | Thread::sleep(2000); |
212 | assertTrue (srv.currentConnections() == 4); |
213 | assertTrue (srv.currentThreads() == 4); |
214 | assertTrue (srv.queuedConnections() == 1); |
215 | assertTrue (srv.totalConnections() == 5); |
216 | |
217 | ss2.close(); |
218 | Thread::sleep(2000); |
219 | assertTrue (srv.currentConnections() == 4); |
220 | assertTrue (srv.currentThreads() == 4); |
221 | assertTrue (srv.queuedConnections() == 0); |
222 | assertTrue (srv.totalConnections() == 6); |
223 | |
224 | ss3.close(); |
225 | Thread::sleep(2000); |
226 | assertTrue (srv.currentConnections() == 3); |
227 | assertTrue (srv.currentThreads() == 3); |
228 | assertTrue (srv.queuedConnections() == 0); |
229 | assertTrue (srv.totalConnections() == 6); |
230 | |
231 | ss4.close(); |
232 | Thread::sleep(2000); |
233 | assertTrue (srv.currentConnections() == 2); |
234 | assertTrue (srv.currentThreads() == 2); |
235 | assertTrue (srv.queuedConnections() == 0); |
236 | assertTrue (srv.totalConnections() == 6); |
237 | |
238 | ss5.close(); |
239 | ss6.close(); |
240 | Thread::sleep(1000); |
241 | assertTrue (srv.currentConnections() == 0); |
242 | } |
243 | |
244 | |
245 | void TCPServerTest::testThreadCapacity() |
246 | { |
247 | ServerSocket svs(0); |
248 | TCPServerParams* pParams = new TCPServerParams; |
249 | pParams->setMaxThreads(64); |
250 | TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs, pParams); |
251 | srv.start(); |
252 | assertTrue (srv.maxThreads() >= 64); |
253 | } |
254 | |
255 | |
256 | void TCPServerTest::testFilter() |
257 | { |
258 | TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>()); |
259 | srv.setConnectionFilter(new RejectFilter); |
260 | srv.start(); |
261 | assertTrue (srv.currentConnections() == 0); |
262 | assertTrue (srv.currentThreads() == 0); |
263 | assertTrue (srv.queuedConnections() == 0); |
264 | assertTrue (srv.totalConnections() == 0); |
265 | |
266 | SocketAddress sa("127.0.0.1" , srv.socket().address().port()); |
267 | StreamSocket ss(sa); |
268 | |
269 | char buffer[256]; |
270 | int n = ss.receiveBytes(buffer, sizeof(buffer)); |
271 | |
272 | assertTrue (n == 0); |
273 | assertTrue (srv.currentConnections() == 0); |
274 | assertTrue (srv.currentThreads() == 0); |
275 | assertTrue (srv.queuedConnections() == 0); |
276 | assertTrue (srv.totalConnections() == 0); |
277 | } |
278 | |
279 | |
280 | void TCPServerTest::setUp() |
281 | { |
282 | } |
283 | |
284 | |
285 | void TCPServerTest::tearDown() |
286 | { |
287 | } |
288 | |
289 | |
290 | CppUnit::Test* TCPServerTest::suite() |
291 | { |
292 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("TCPServerTest" ); |
293 | |
294 | CppUnit_addTest(pSuite, TCPServerTest, testOneConnection); |
295 | CppUnit_addTest(pSuite, TCPServerTest, testTwoConnections); |
296 | CppUnit_addTest(pSuite, TCPServerTest, testMultiConnections); |
297 | CppUnit_addTest(pSuite, TCPServerTest, testThreadCapacity); |
298 | CppUnit_addTest(pSuite, TCPServerTest, testFilter); |
299 | |
300 | return pSuite; |
301 | } |
302 | |