Commit | Line | Data |
---|---|---|
19facd85 TJ |
1 | /* |
2 | Copyright (C) 2004 by Intra2net AG | |
04d86ba4 | 3 | |
19facd85 TJ |
4 | The software in this package is distributed under the GNU General |
5 | Public License version 2 (with a special exception described below). | |
6 | ||
7 | A copy of GNU General Public License (GPL) is included in this distribution, | |
8 | in the file COPYING.GPL. | |
9 | ||
10 | As a special exception, if other files instantiate templates or use macros | |
11 | or inline functions from this file, or you compile this file and link it | |
12 | with other works to produce a work based on this file, this file | |
13 | does not by itself cause the resulting work to be covered | |
14 | by the GNU General Public License. | |
15 | ||
16 | However the source code for this file must still be made available | |
17 | in accordance with section (3) of the GNU General Public License. | |
18 | ||
19 | This exception does not invalidate any other reasons why a work based | |
20 | on this file might be covered by the GNU General Public License. | |
21 | */ | |
04d86ba4 GE |
22 | #include <sys/types.h> |
23 | #include <unistd.h> | |
24 | #include <errno.h> | |
25 | #include <signal.h> | |
26 | #include <stdio.h> | |
27 | ||
28 | #include <iostream> | |
29 | #include <string> | |
30 | #include <sstream> | |
31 | #include <stdexcept> | |
32 | ||
33 | #include <boost/bind.hpp> | |
34 | ||
307b5e74 TJ |
35 | #define BOOST_TEST_DYN_LINK |
36 | #include <boost/test/unit_test.hpp> | |
04d86ba4 GE |
37 | |
38 | #include <t2n_exception.hxx> | |
39 | #include <socket_client.hxx> | |
40 | #include <socket_server.hxx> | |
41 | #include <command_client.hxx> | |
42 | ||
307b5e74 TJ |
43 | #include "test_fixtures.hxx" |
44 | ||
04d86ba4 GE |
45 | #ifdef HAVE_CONFIG_H |
46 | #include <config.h> | |
47 | #endif | |
48 | ||
49 | using namespace std; | |
50 | using namespace libt2n; | |
04d86ba4 GE |
51 | |
52 | // this is an evil hack to get access to real_write, don't ever do this in an app!!! | |
53 | class real_write_connection: public socket_server_connection | |
54 | { | |
55 | public: | |
56 | void real_write(const std::string& data) | |
57 | { socket_write(data); } | |
58 | }; | |
59 | ||
307b5e74 | 60 | class test_helloFixture : public KillChildOnShutdownFixture |
04d86ba4 | 61 | { |
307b5e74 | 62 | protected: |
04d86ba4 GE |
63 | void send_hello(string hello_string, socket_server* ss, int conn_id) |
64 | { | |
65 | server_connection *sc=ss->get_connection(conn_id); | |
66 | sc->write(hello_string); | |
67 | } | |
68 | ||
69 | void send_raw_socket(string hello_string, socket_server* ss, int conn_id) | |
70 | { | |
71 | socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id)); | |
72 | ||
73 | // this is an evil hack to get access to real_write, don't ever do this in an app!!! | |
74 | real_write_connection *rwc=(real_write_connection*)ssc; | |
75 | rwc->real_write(hello_string); | |
76 | } | |
77 | ||
307b5e74 TJ |
78 | public: |
79 | test_helloFixture() | |
80 | { | |
81 | } | |
82 | ||
83 | ~test_helloFixture() | |
04d86ba4 | 84 | { |
307b5e74 TJ |
85 | } |
86 | }; | |
87 | ||
88 | BOOST_FIXTURE_TEST_SUITE(test_hello, test_helloFixture) | |
89 | ||
90 | BOOST_AUTO_TEST_CASE(HelloOk) | |
91 | { | |
92 | switch(child_pid=fork()) | |
93 | { | |
94 | case -1: | |
04d86ba4 | 95 | { |
307b5e74 TJ |
96 | BOOST_FAIL("fork error"); |
97 | break; | |
98 | } | |
99 | case 0: | |
100 | // child | |
101 | { | |
102 | try | |
04d86ba4 | 103 | { |
307b5e74 TJ |
104 | socket_server ss("./socket"); |
105 | ||
106 | ostringstream hello; | |
107 | hello << "T2Nv" << PROTOCOL_VERSION << ';'; | |
108 | int byteordercheck=1; | |
109 | hello.write((char*)&byteordercheck,sizeof(byteordercheck)); | |
110 | hello << ';'; | |
111 | ||
112 | ss.add_callback(new_connection,bind(&test_hello::HelloOk::send_hello, boost::ref(*this), hello.str(),&ss, _1)); | |
113 | ||
114 | // max 10 sec | |
115 | for (int i=0; i < 10; i++) | |
116 | ss.fill_buffer(1000000); | |
117 | } catch(...) | |
04d86ba4 | 118 | { |
307b5e74 | 119 | std::cerr << "exception in child. ignoring\n"; |
04d86ba4 GE |
120 | } |
121 | ||
307b5e74 TJ |
122 | // don't call atexit and stuff |
123 | _exit(0); | |
124 | } | |
04d86ba4 | 125 | |
307b5e74 TJ |
126 | default: |
127 | // parent | |
128 | { | |
129 | string data; | |
130 | ||
131 | // wait till server is up | |
132 | sleep(1); | |
133 | socket_client_connection sc("./socket"); | |
134 | command_client cc(&sc); | |
135 | ||
136 | // All fine we reached this point | |
137 | BOOST_CHECK(true); | |
04d86ba4 GE |
138 | } |
139 | } | |
307b5e74 | 140 | } |
04d86ba4 | 141 | |
307b5e74 TJ |
142 | BOOST_AUTO_TEST_CASE(BadTag) |
143 | { | |
144 | switch(child_pid=fork()) | |
04d86ba4 | 145 | { |
307b5e74 | 146 | case -1: |
04d86ba4 | 147 | { |
307b5e74 TJ |
148 | BOOST_FAIL("fork error"); |
149 | break; | |
150 | } | |
151 | case 0: | |
152 | // child | |
153 | { | |
154 | try | |
04d86ba4 | 155 | { |
307b5e74 | 156 | socket_server ss("./socket"); |
04d86ba4 | 157 | |
307b5e74 TJ |
158 | ostringstream hello; |
159 | hello << "XYZ 123"; | |
441d41fe | 160 | |
307b5e74 | 161 | ss.add_callback(new_connection,bind(&test_hello::BadTag::send_hello, boost::ref(*this), hello.str(),&ss, _1)); |
04d86ba4 | 162 | |
307b5e74 TJ |
163 | // max 10 sec |
164 | for (int i=0; i < 10; i++) | |
165 | ss.fill_buffer(1000000); | |
166 | } catch(...) | |
167 | { | |
168 | std::cerr << "exception in child. ignoring\n"; | |
04d86ba4 GE |
169 | } |
170 | ||
307b5e74 TJ |
171 | // don't call atexit and stuff |
172 | _exit(0); | |
173 | } | |
04d86ba4 | 174 | |
307b5e74 TJ |
175 | default: |
176 | // parent | |
177 | { | |
178 | string data; | |
04d86ba4 | 179 | |
307b5e74 TJ |
180 | // wait till server is up |
181 | sleep(1); | |
182 | socket_client_connection sc("./socket"); | |
b5922184 | 183 | |
307b5e74 | 184 | command_client cc(&sc); |
04d86ba4 | 185 | |
307b5e74 | 186 | t2n_exception* ep=cc.get_constuctor_exception(); |
04d86ba4 | 187 | |
307b5e74 TJ |
188 | string errormsg; |
189 | if (ep) | |
190 | errormsg=ep->what(); | |
191 | ||
192 | BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg); | |
04d86ba4 GE |
193 | } |
194 | } | |
307b5e74 | 195 | } |
04d86ba4 | 196 | |
307b5e74 TJ |
197 | BOOST_AUTO_TEST_CASE(BadVersion) |
198 | { | |
199 | switch(child_pid=fork()) | |
04d86ba4 | 200 | { |
307b5e74 | 201 | case -1: |
04d86ba4 | 202 | { |
307b5e74 TJ |
203 | BOOST_FAIL("fork error"); |
204 | break; | |
205 | } | |
206 | case 0: | |
207 | // child | |
208 | { | |
209 | try | |
04d86ba4 | 210 | { |
307b5e74 TJ |
211 | socket_server ss("./socket"); |
212 | ||
213 | ostringstream hello; | |
214 | // lets hope we don't ever get near such a version number... | |
215 | hello << "T2Nv" << 4982271 << ';'; | |
216 | int byteordercheck=1; | |
217 | hello.write((char*)&byteordercheck,sizeof(byteordercheck)); | |
218 | hello << ';'; | |
219 | ||
220 | ss.add_callback(new_connection,bind(&test_hello::BadVersion::send_hello, boost::ref(*this), hello.str(),&ss, _1)); | |
221 | ||
222 | // max 10 sec | |
223 | for (int i=0; i < 10; i++) | |
224 | ss.fill_buffer(1000000); | |
225 | } catch(...) | |
04d86ba4 | 226 | { |
307b5e74 | 227 | std::cerr << "exception in child. ignoring\n"; |
04d86ba4 GE |
228 | } |
229 | ||
307b5e74 TJ |
230 | // don't call atexit and stuff |
231 | _exit(0); | |
232 | } | |
233 | ||
234 | default: | |
235 | // parent | |
236 | { | |
237 | string data; | |
04d86ba4 | 238 | |
307b5e74 TJ |
239 | // wait till server is up |
240 | sleep(1); | |
241 | socket_client_connection sc("./socket"); | |
04d86ba4 | 242 | |
307b5e74 | 243 | command_client cc(&sc); |
04d86ba4 | 244 | |
307b5e74 | 245 | t2n_exception* ep=cc.get_constuctor_exception(); |
b5922184 | 246 | |
307b5e74 TJ |
247 | string errormsg; |
248 | if (ep) | |
249 | errormsg=ep->what(); | |
04d86ba4 | 250 | |
307b5e74 | 251 | BOOST_CHECK_EQUAL(string("not compatible with the server protocol version"),errormsg); |
04d86ba4 GE |
252 | } |
253 | } | |
307b5e74 | 254 | } |
04d86ba4 | 255 | |
307b5e74 TJ |
256 | BOOST_AUTO_TEST_CASE(SeparatorMissing) |
257 | { | |
258 | switch(child_pid=fork()) | |
04d86ba4 | 259 | { |
307b5e74 | 260 | case -1: |
04d86ba4 | 261 | { |
307b5e74 TJ |
262 | BOOST_FAIL("fork error"); |
263 | break; | |
264 | } | |
265 | case 0: | |
266 | // child | |
267 | { | |
268 | try | |
04d86ba4 | 269 | { |
307b5e74 TJ |
270 | socket_server ss("./socket"); |
271 | ||
272 | ostringstream hello; | |
273 | hello << "T2Nv" << PROTOCOL_VERSION; | |
274 | int byteordercheck=1; | |
275 | hello.write((char*)&byteordercheck,sizeof(byteordercheck)); | |
276 | hello << ';'; | |
277 | ||
278 | ss.add_callback(new_connection,bind(&test_hello::SeparatorMissing::send_hello, boost::ref(*this), hello.str(),&ss, _1)); | |
279 | ||
280 | // max 10 sec | |
281 | for (int i=0; i < 10; i++) | |
282 | ss.fill_buffer(1000000); | |
283 | } catch(...) | |
04d86ba4 | 284 | { |
307b5e74 | 285 | std::cerr << "exception in child. ignoring\n"; |
04d86ba4 GE |
286 | } |
287 | ||
307b5e74 TJ |
288 | // don't call atexit and stuff |
289 | _exit(0); | |
290 | } | |
04d86ba4 | 291 | |
307b5e74 TJ |
292 | default: |
293 | // parent | |
294 | { | |
295 | string data; | |
04d86ba4 | 296 | |
307b5e74 TJ |
297 | // wait till server is up |
298 | sleep(1); | |
299 | socket_client_connection sc("./socket"); | |
04d86ba4 | 300 | |
307b5e74 | 301 | command_client cc(&sc); |
b5922184 | 302 | |
307b5e74 | 303 | t2n_exception* ep=cc.get_constuctor_exception(); |
04d86ba4 | 304 | |
307b5e74 TJ |
305 | string errormsg; |
306 | if (ep) | |
307 | errormsg=ep->what(); | |
308 | ||
309 | BOOST_CHECK_EQUAL(string("illegal hello received (1. ;)"),errormsg); | |
04d86ba4 GE |
310 | } |
311 | } | |
307b5e74 | 312 | } |
04d86ba4 | 313 | |
307b5e74 TJ |
314 | BOOST_AUTO_TEST_CASE(WrongByteOrder) |
315 | { | |
316 | switch(child_pid=fork()) | |
04d86ba4 | 317 | { |
307b5e74 TJ |
318 | case -1: |
319 | { | |
320 | BOOST_FAIL("fork error"); | |
321 | break; | |
322 | } | |
323 | case 0: | |
324 | // child | |
04d86ba4 | 325 | { |
307b5e74 | 326 | try |
04d86ba4 | 327 | { |
307b5e74 TJ |
328 | socket_server ss("./socket"); |
329 | ||
330 | ostringstream hello; | |
331 | hello << "T2Nv" << PROTOCOL_VERSION << ';'; | |
332 | int byteordercheck=1; | |
333 | int dst; | |
334 | char* si=(char*)&byteordercheck; | |
335 | char* di=(char*)&dst; | |
336 | ||
337 | di[0]=si[3]; | |
338 | di[1]=si[2]; | |
339 | di[2]=si[1]; | |
340 | di[3]=si[0]; | |
341 | ||
342 | hello.write((char*)&dst,sizeof(dst)); | |
343 | hello << ';'; | |
344 | ||
345 | ss.add_callback(new_connection,bind(&test_hello::WrongByteOrder::send_hello, boost::ref(*this), hello.str(),&ss, _1)); | |
346 | ||
347 | // max 10 sec | |
348 | for (int i=0; i < 10; i++) | |
349 | ss.fill_buffer(1000000); | |
350 | } catch(...) | |
04d86ba4 | 351 | { |
307b5e74 | 352 | std::cerr << "exception in child. ignoring\n"; |
04d86ba4 GE |
353 | } |
354 | ||
307b5e74 TJ |
355 | // don't call atexit and stuff |
356 | _exit(0); | |
357 | } | |
04d86ba4 | 358 | |
307b5e74 TJ |
359 | default: |
360 | // parent | |
361 | { | |
362 | string data; | |
04d86ba4 | 363 | |
307b5e74 TJ |
364 | // wait till server is up |
365 | sleep(1); | |
366 | socket_client_connection sc("./socket"); | |
04d86ba4 | 367 | |
307b5e74 | 368 | command_client cc(&sc); |
b5922184 | 369 | |
307b5e74 | 370 | t2n_exception* ep=cc.get_constuctor_exception(); |
04d86ba4 | 371 | |
307b5e74 TJ |
372 | string errormsg; |
373 | if (ep) | |
374 | errormsg=ep->what(); | |
375 | ||
376 | BOOST_CHECK_EQUAL(string("host byte order not matching"),errormsg); | |
04d86ba4 GE |
377 | } |
378 | } | |
307b5e74 | 379 | } |
04d86ba4 | 380 | |
307b5e74 TJ |
381 | BOOST_AUTO_TEST_CASE(OtherServerBig) |
382 | { | |
383 | switch(child_pid=fork()) | |
04d86ba4 | 384 | { |
307b5e74 TJ |
385 | case -1: |
386 | { | |
387 | BOOST_FAIL("fork error"); | |
388 | break; | |
389 | } | |
390 | case 0: | |
391 | // child | |
04d86ba4 | 392 | { |
307b5e74 | 393 | try |
04d86ba4 | 394 | { |
307b5e74 TJ |
395 | socket_server ss("./socket"); |
396 | ||
397 | ostringstream hello; | |
398 | // hmm, we got the wrong socket | |
399 | hello << "* OK intradev.net.lan Cyrus IMAP4 v2.2.13 server ready"; | |
400 | ||
401 | ss.add_callback(new_connection,bind(&test_hello::OtherServerBig::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1)); | |
402 | ||
403 | // max 3 sec | |
404 | for (int i=0; i < 3; i++) | |
405 | ss.fill_buffer(1000000); | |
406 | } catch(...) | |
04d86ba4 | 407 | { |
307b5e74 | 408 | std::cerr << "exception in child. ignoring\n"; |
04d86ba4 GE |
409 | } |
410 | ||
307b5e74 TJ |
411 | // don't call atexit and stuff |
412 | _exit(0); | |
413 | } | |
04d86ba4 | 414 | |
307b5e74 TJ |
415 | default: |
416 | // parent | |
417 | { | |
418 | string data; | |
04d86ba4 | 419 | |
307b5e74 TJ |
420 | // wait till server is up |
421 | sleep(1); | |
422 | socket_client_connection sc("./socket"); | |
b5922184 | 423 | |
307b5e74 | 424 | command_client cc(&sc); |
04d86ba4 | 425 | |
307b5e74 | 426 | t2n_exception* ep=cc.get_constuctor_exception(); |
04d86ba4 | 427 | |
307b5e74 TJ |
428 | string errormsg; |
429 | if (ep) | |
430 | errormsg=ep->what(); | |
431 | ||
432 | BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg); | |
04d86ba4 GE |
433 | } |
434 | } | |
307b5e74 | 435 | } |
04d86ba4 | 436 | |
307b5e74 TJ |
437 | BOOST_AUTO_TEST_CASE(OtherServerSmall) |
438 | { | |
439 | switch(child_pid=fork()) | |
b604df5f | 440 | { |
307b5e74 | 441 | case -1: |
b604df5f | 442 | { |
307b5e74 TJ |
443 | BOOST_FAIL("fork error"); |
444 | break; | |
445 | } | |
446 | case 0: | |
447 | // child | |
448 | { | |
449 | try | |
b604df5f | 450 | { |
307b5e74 TJ |
451 | socket_server ss("./socket"); |
452 | ||
453 | ostringstream hello; | |
454 | // hmm, we got the wrong socket | |
455 | hello << "READY"; | |
456 | ||
457 | ss.add_callback(new_connection,bind(&test_hello::OtherServerSmall::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1)); | |
458 | ||
459 | // max 3 sec | |
460 | for (int i=0; i < 3; i++) | |
461 | ss.fill_buffer(1000000); | |
462 | } catch(...) | |
b604df5f | 463 | { |
307b5e74 | 464 | std::cerr << "exception in child. ignoring\n"; |
b604df5f GE |
465 | } |
466 | ||
307b5e74 TJ |
467 | // don't call atexit and stuff |
468 | _exit(0); | |
469 | } | |
b604df5f | 470 | |
307b5e74 TJ |
471 | default: |
472 | // parent | |
473 | { | |
474 | string data; | |
b604df5f | 475 | |
307b5e74 TJ |
476 | // wait till server is up |
477 | sleep(1); | |
478 | socket_client_connection sc("./socket"); | |
b604df5f | 479 | |
307b5e74 | 480 | command_client cc(&sc); |
b5922184 | 481 | |
307b5e74 | 482 | t2n_exception* ep=cc.get_constuctor_exception(); |
b604df5f | 483 | |
307b5e74 TJ |
484 | string errormsg; |
485 | if (ep) | |
486 | errormsg=ep->what(); | |
487 | ||
488 | BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg); | |
b604df5f GE |
489 | } |
490 | } | |
307b5e74 | 491 | } |
b604df5f | 492 | |
307b5e74 | 493 | BOOST_AUTO_TEST_SUITE_END() |