Commit | Line | Data |
---|---|---|
6cda58a6 GE |
1 | /*************************************************************************** |
2 | * Copyright (C) 2004 by Intra2net AG * | |
3 | * info@intra2net.com * | |
4 | * * | |
5 | ***************************************************************************/ | |
6 | ||
7 | #include <sys/types.h> | |
8 | #include <unistd.h> | |
9 | #include <errno.h> | |
10 | #include <signal.h> | |
11 | #include <stdio.h> | |
12 | ||
13 | #include <iostream> | |
14 | #include <string> | |
15 | #include <sstream> | |
16 | #include <stdexcept> | |
17 | #include <vector> | |
18 | ||
19 | #include <boost/bind.hpp> | |
20 | ||
21 | #include <cppunit/extensions/TestFactoryRegistry.h> | |
22 | #include <cppunit/ui/text/TestRunner.h> | |
23 | #include <cppunit/extensions/HelperMacros.h> | |
24 | ||
25 | #include <socket_client.hxx> | |
26 | #include <socket_server.hxx> | |
27 | ||
28 | using namespace std; | |
29 | using namespace libt2n; | |
30 | using namespace CppUnit; | |
31 | ||
32 | class test_callback : public TestFixture | |
33 | { | |
34 | CPPUNIT_TEST_SUITE(test_callback); | |
35 | ||
91730468 GE |
36 | CPPUNIT_TEST(ServerNewConnCallback); |
37 | CPPUNIT_TEST(ServerConnClosedCallback); | |
38 | CPPUNIT_TEST(ServerConnDeletedCallback); | |
39 | CPPUNIT_TEST(ServerCallbackOrder); | |
40 | CPPUNIT_TEST(ClientConnClosedCallback); | |
41 | CPPUNIT_TEST(ClientConnDeletedCallback); | |
6cda58a6 GE |
42 | |
43 | CPPUNIT_TEST_SUITE_END(); | |
44 | ||
45 | std::vector<bool> callback_done; | |
46 | ||
b5922184 GE |
47 | pid_t child_pid; |
48 | ||
6cda58a6 GE |
49 | public: |
50 | ||
51 | void setUp() | |
52 | { | |
53 | callback_done.resize(__events_end); | |
54 | } | |
55 | ||
56 | void tearDown() | |
57 | { | |
58 | callback_done.clear(); | |
b5922184 GE |
59 | |
60 | // make sure the server-child is dead before the next test runs | |
61 | kill(child_pid,SIGKILL); | |
62 | sleep(1); | |
6cda58a6 GE |
63 | } |
64 | ||
65 | void callback_func(callback_event_type ev, int conn_id) | |
66 | { | |
67 | // we don't care for the conn_id, we just mark the callback as done | |
68 | if (callback_done[ev]) | |
69 | throw runtime_error("callback already done for this event"); | |
70 | ||
71 | callback_done[ev]=true; | |
72 | } | |
73 | ||
91730468 | 74 | void ServerNewConnCallback() |
6cda58a6 | 75 | { |
b5922184 | 76 | switch(child_pid=fork()) |
6cda58a6 GE |
77 | { |
78 | case -1: | |
79 | { | |
80 | CPPUNIT_FAIL("fork error"); | |
81 | break; | |
82 | } | |
83 | case 0: | |
84 | // child | |
85 | { | |
86 | string data; | |
87 | // wait till server is up | |
88 | sleep(1); | |
89 | ||
90 | { | |
91 | socket_client_connection sc("./socket"); | |
92 | ||
93 | sc.write("ABC"); | |
94 | ||
95 | // wait half a sec | |
96 | sc.fill_buffer(500000); | |
97 | sc.get_packet(data); | |
98 | ||
99 | // close the connection | |
100 | } | |
101 | ||
102 | // don't call atexit and stuff | |
103 | _exit(0); | |
104 | } | |
105 | ||
106 | default: | |
107 | // parent | |
108 | { | |
109 | socket_server ss("./socket"); | |
110 | ||
111 | ss.add_callback(new_connection,bind(&test_callback::callback_func, boost::ref(*this), new_connection, _1)); | |
112 | ||
113 | // max 3 sec | |
114 | for (int i=0; i < 3; i++) | |
115 | { | |
116 | ss.fill_buffer(1000000); | |
117 | ||
118 | string data; | |
119 | unsigned int cid; | |
120 | if(ss.get_packet(data,cid)) | |
121 | { | |
122 | server_connection* con=ss.get_connection(cid); | |
123 | con->write("XYZ"); | |
124 | } | |
125 | } | |
126 | CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[new_connection])); | |
127 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed])); | |
128 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted])); | |
129 | } | |
130 | } | |
131 | } | |
132 | ||
91730468 | 133 | void ServerConnClosedCallback() |
6cda58a6 | 134 | { |
b5922184 | 135 | switch(child_pid=fork()) |
6cda58a6 GE |
136 | { |
137 | case -1: | |
138 | { | |
139 | CPPUNIT_FAIL("fork error"); | |
140 | break; | |
141 | } | |
142 | case 0: | |
143 | // child | |
144 | { | |
145 | string data; | |
146 | // wait till server is up | |
147 | sleep(1); | |
148 | ||
149 | { | |
150 | socket_client_connection sc("./socket"); | |
151 | ||
152 | sc.write("ABC"); | |
153 | ||
154 | // wait half a sec | |
155 | sc.fill_buffer(500000); | |
156 | sc.get_packet(data); | |
157 | ||
158 | // close the connection | |
159 | } | |
160 | ||
161 | // don't call atexit and stuff | |
162 | _exit(0); | |
163 | } | |
164 | ||
165 | default: | |
166 | // parent | |
167 | { | |
168 | socket_server ss("./socket"); | |
169 | ||
170 | ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1)); | |
171 | ||
172 | // max 3 sec | |
173 | for (int i=0; i < 3; i++) | |
174 | { | |
175 | ss.fill_buffer(1000000); | |
176 | ||
177 | string data; | |
178 | unsigned int cid; | |
179 | if(ss.get_packet(data,cid)) | |
180 | { | |
181 | server_connection* con=ss.get_connection(cid); | |
182 | con->write("XYZ"); | |
183 | } | |
184 | } | |
185 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection])); | |
186 | CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed])); | |
187 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted])); | |
188 | } | |
189 | } | |
190 | } | |
191 | ||
91730468 | 192 | void ServerConnDeletedCallback() |
6cda58a6 | 193 | { |
b5922184 | 194 | switch(child_pid=fork()) |
6cda58a6 GE |
195 | { |
196 | case -1: | |
197 | { | |
198 | CPPUNIT_FAIL("fork error"); | |
199 | break; | |
200 | } | |
201 | case 0: | |
202 | // child | |
203 | { | |
204 | string data; | |
205 | // wait till server is up | |
206 | sleep(1); | |
207 | ||
208 | { | |
209 | socket_client_connection sc("./socket"); | |
210 | ||
211 | sc.write("ABC"); | |
212 | ||
213 | // wait half a sec | |
214 | sc.fill_buffer(500000); | |
215 | sc.get_packet(data); | |
216 | ||
217 | // close the connection | |
218 | } | |
219 | ||
220 | // don't call atexit and stuff | |
221 | _exit(0); | |
222 | } | |
223 | ||
224 | default: | |
225 | // parent | |
226 | { | |
227 | socket_server ss("./socket"); | |
228 | ||
229 | ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1)); | |
230 | ||
231 | // max 3 sec | |
232 | for (int i=0; i < 3; i++) | |
233 | { | |
234 | ss.fill_buffer(1000000); | |
235 | ||
236 | string data; | |
237 | unsigned int cid; | |
238 | if(ss.get_packet(data,cid)) | |
239 | { | |
240 | server_connection* con=ss.get_connection(cid); | |
241 | con->write("XYZ"); | |
242 | } | |
243 | ss.cleanup(); | |
244 | } | |
245 | ss.cleanup(); | |
246 | ||
247 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection])); | |
248 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed])); | |
249 | CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted])); | |
250 | } | |
251 | } | |
252 | } | |
253 | ||
91730468 | 254 | void ServerCallbackOrder() |
6cda58a6 | 255 | { |
b5922184 | 256 | switch(child_pid=fork()) |
6cda58a6 GE |
257 | { |
258 | case -1: | |
259 | { | |
260 | CPPUNIT_FAIL("fork error"); | |
261 | break; | |
262 | } | |
263 | case 0: | |
264 | // child | |
265 | { | |
266 | string data; | |
267 | // wait till server is up | |
268 | sleep(1); | |
269 | ||
270 | { | |
271 | socket_client_connection sc("./socket"); | |
272 | ||
273 | sc.write("1"); | |
274 | ||
275 | // wait half a sec | |
276 | sc.fill_buffer(500000); | |
277 | sc.get_packet(data); | |
278 | ||
279 | sc.write("2"); | |
280 | ||
281 | // close the connection | |
282 | } | |
283 | ||
284 | // don't call atexit and stuff | |
285 | _exit(0); | |
286 | } | |
287 | ||
288 | default: | |
289 | // parent | |
290 | { | |
291 | socket_server ss("./socket"); | |
292 | ||
293 | ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1)); | |
294 | ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1)); | |
295 | ||
296 | bool got_1=false; | |
297 | ||
af84dfb5 | 298 | for (int i=0; i < 5; i++) |
6cda58a6 GE |
299 | { |
300 | ss.fill_buffer(500000); | |
301 | ||
302 | string data; | |
303 | unsigned int cid; | |
304 | if(!got_1 && ss.get_packet(data,cid)) | |
305 | { | |
306 | server_connection* con=ss.get_connection(cid); | |
307 | con->write("XYZ"); | |
308 | got_1=true; | |
309 | // don't call get_packet anymore | |
310 | } | |
311 | ss.cleanup(); | |
312 | } | |
313 | ss.cleanup(); | |
314 | ||
af84dfb5 GE |
315 | CPPUNIT_ASSERT_EQUAL_MESSAGE("closed done",true,static_cast<bool>(callback_done[connection_closed])); |
316 | CPPUNIT_ASSERT_EQUAL_MESSAGE("not deleted yet",false,static_cast<bool>(callback_done[connection_deleted])); | |
6cda58a6 GE |
317 | |
318 | for (int i=0; i < 4; i++) | |
319 | { | |
320 | ss.fill_buffer(500000); | |
321 | ||
322 | string data; | |
323 | unsigned int cid; | |
324 | ss.get_packet(data,cid); | |
325 | ss.cleanup(); | |
326 | } | |
327 | ss.cleanup(); | |
328 | ||
af84dfb5 GE |
329 | CPPUNIT_ASSERT_EQUAL_MESSAGE("closed done (2)",true,static_cast<bool>(callback_done[connection_closed])); |
330 | CPPUNIT_ASSERT_EQUAL_MESSAGE("deleted done",true,static_cast<bool>(callback_done[connection_deleted])); | |
6cda58a6 GE |
331 | } |
332 | } | |
333 | } | |
334 | ||
91730468 GE |
335 | void ClientConnClosedCallback() |
336 | { | |
b5922184 | 337 | switch(child_pid=fork()) |
91730468 GE |
338 | { |
339 | case -1: | |
340 | { | |
341 | CPPUNIT_FAIL("fork error"); | |
342 | break; | |
343 | } | |
344 | case 0: | |
345 | // child | |
346 | { | |
347 | socket_server ss("./socket"); | |
348 | ||
349 | // max 3 sec | |
350 | for (int i=0; i < 3; i++) | |
351 | { | |
352 | ss.fill_buffer(1000000); | |
353 | ||
354 | string data; | |
355 | unsigned int cid; | |
356 | if(ss.get_packet(data,cid)) | |
357 | break; | |
358 | } | |
359 | // don't call atexit and stuff | |
360 | _exit(0); | |
361 | } | |
362 | ||
363 | default: | |
364 | // parent | |
365 | { | |
366 | string data; | |
367 | // wait till server is up | |
368 | sleep(1); | |
369 | ||
370 | socket_client_connection sc("./socket"); | |
371 | ||
372 | sc.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, 0)); | |
373 | ||
374 | sc.write("ABC"); | |
375 | ||
376 | // wait half a sec | |
377 | sc.fill_buffer(500000); | |
378 | sc.get_packet(data); | |
379 | ||
380 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection])); | |
381 | CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed])); | |
382 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted])); | |
383 | } | |
384 | } | |
385 | } | |
386 | ||
387 | void ClientConnDeletedCallback() | |
388 | { | |
b5922184 | 389 | switch(child_pid=fork()) |
91730468 GE |
390 | { |
391 | case -1: | |
392 | { | |
393 | CPPUNIT_FAIL("fork error"); | |
394 | break; | |
395 | } | |
396 | case 0: | |
397 | // child | |
398 | { | |
399 | socket_server ss("./socket"); | |
400 | ||
401 | // max 3 sec | |
402 | for (int i=0; i < 3; i++) | |
403 | { | |
404 | ss.fill_buffer(1000000); | |
405 | ||
406 | string data; | |
407 | unsigned int cid; | |
408 | if(ss.get_packet(data,cid)) | |
409 | break; | |
410 | } | |
411 | // don't call atexit and stuff | |
412 | _exit(0); | |
413 | } | |
414 | ||
415 | default: | |
416 | // parent | |
417 | { | |
418 | string data; | |
419 | // wait till server is up | |
420 | sleep(1); | |
421 | ||
422 | { | |
423 | socket_client_connection sc("./socket"); | |
424 | ||
425 | sc.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, 0)); | |
426 | ||
427 | sc.write("ABC"); | |
428 | ||
429 | // wait half a sec | |
430 | sc.fill_buffer(500000); | |
431 | sc.get_packet(data); | |
432 | } | |
433 | ||
434 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection])); | |
435 | CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed])); | |
436 | CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted])); | |
437 | } | |
438 | } | |
439 | } | |
6cda58a6 GE |
440 | }; |
441 | ||
442 | CPPUNIT_TEST_SUITE_REGISTRATION(test_callback); |