libt2n: (gerd) add client timeouts & tests, hello peek missing
[libt2n] / test / hello.cpp
CommitLineData
04d86ba4
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
18#include <boost/bind.hpp>
19
20#include <cppunit/extensions/TestFactoryRegistry.h>
21#include <cppunit/ui/text/TestRunner.h>
22#include <cppunit/extensions/HelperMacros.h>
23
24#include <t2n_exception.hxx>
25#include <socket_client.hxx>
26#include <socket_server.hxx>
27#include <command_client.hxx>
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33using namespace std;
34using namespace libt2n;
35using namespace CppUnit;
36
37// this is an evil hack to get access to real_write, don't ever do this in an app!!!
38class real_write_connection: public socket_server_connection
39{
40 public:
41 void real_write(const std::string& data)
42 { socket_write(data); }
43};
44
45class test_hello : public TestFixture
46{
47 CPPUNIT_TEST_SUITE(test_hello);
48
49 CPPUNIT_TEST(HelloOk);
50 CPPUNIT_TEST(BadTag);
51 CPPUNIT_TEST(BadVersion);
52 CPPUNIT_TEST(SeparatorMissing);
53 CPPUNIT_TEST(WrongByteOrder);
54 CPPUNIT_TEST(OtherServer);
55
56 CPPUNIT_TEST_SUITE_END();
57
58 public:
59
60 void setUp()
61 { }
62
63 void tearDown()
64 { }
65
66 void send_hello(string hello_string, socket_server* ss, int conn_id)
67 {
68 server_connection *sc=ss->get_connection(conn_id);
69 sc->write(hello_string);
70 }
71
72 void send_raw_socket(string hello_string, socket_server* ss, int conn_id)
73 {
74 socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id));
75
76 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
77 real_write_connection *rwc=(real_write_connection*)ssc;
78 rwc->real_write(hello_string);
79 }
80
81 void HelloOk()
82 {
83 pid_t pid;
84
85 switch(pid=fork())
86 {
87 case -1:
88 {
89 CPPUNIT_FAIL("fork error");
90 break;
91 }
92 case 0:
93 // child
94 {
95 socket_server ss("./socket");
96
97 ostringstream hello;
98 hello << "T2Nv" << PROTOCOL_VERSION << ';';
99 int byteordercheck=1;
100 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
101 hello << ';';
102
103 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
104
105 // max 10 sec
106 for (int i=0; i < 10; i++)
107 ss.fill_buffer(1000000);
108 // don't call atexit and stuff
109 _exit(0);
110 }
111
112 default:
113 // parent
114 {
115 string data;
116
117 // wait till server is up
118 sleep(1);
119 socket_client_connection sc("./socket");
120 command_client cc(sc);
121 }
122 }
123 }
124
125 void BadTag()
126 {
127 pid_t pid;
128
129 switch(pid=fork())
130 {
131 case -1:
132 {
133 CPPUNIT_FAIL("fork error");
134 break;
135 }
136 case 0:
137 // child
138 {
139 socket_server ss("./socket");
140
141 ostringstream hello;
142 hello << "XYZ 123";
143
144 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
145
146 // max 10 sec
147 for (int i=0; i < 10; i++)
148 ss.fill_buffer(1000000);
149 // don't call atexit and stuff
150 _exit(0);
151 }
152
153 default:
154 // parent
155 {
156 string data;
157
158 // wait till server is up
159 sleep(1);
160 socket_client_connection sc("./socket");
161
162 string errormsg;
163
164 try
165 {
166 command_client cc(sc);
167 }
168 catch(t2n_version_mismatch &e)
169 { errormsg=e.what(); }
170 catch(...)
171 { throw; }
172
173 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
174 }
175 }
176 }
177
178 void BadVersion()
179 {
180 pid_t pid;
181
182 switch(pid=fork())
183 {
184 case -1:
185 {
186 CPPUNIT_FAIL("fork error");
187 break;
188 }
189 case 0:
190 // child
191 {
192 socket_server ss("./socket");
193
194 ostringstream hello;
195 // lets hope we don't ever get near such a version number...
196 hello << "T2Nv" << 4982271 << ';';
197 int byteordercheck=1;
198 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
199 hello << ';';
200
201 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
202
203 // max 10 sec
204 for (int i=0; i < 10; i++)
205 ss.fill_buffer(1000000);
206 // don't call atexit and stuff
207 _exit(0);
208 }
209
210 default:
211 // parent
212 {
213 string data;
214
215 // wait till server is up
216 sleep(1);
217 socket_client_connection sc("./socket");
218
219 string errormsg;
220
221 try
222 {
223 command_client cc(sc);
224 }
225 catch(t2n_version_mismatch &e)
226 { errormsg=e.what(); }
227 catch(...)
228 { throw; }
229
230 CPPUNIT_ASSERT_EQUAL(string("not compatible with the server protocol version"),errormsg);
231 }
232 }
233 }
234
235 void SeparatorMissing()
236 {
237 pid_t pid;
238
239 switch(pid=fork())
240 {
241 case -1:
242 {
243 CPPUNIT_FAIL("fork error");
244 break;
245 }
246 case 0:
247 // child
248 {
249 socket_server ss("./socket");
250
251 ostringstream hello;
252 hello << "T2Nv" << PROTOCOL_VERSION;
253 int byteordercheck=1;
254 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
255 hello << ';';
256
257 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
258
259 // max 10 sec
260 for (int i=0; i < 10; i++)
261 ss.fill_buffer(1000000);
262 // don't call atexit and stuff
263 _exit(0);
264 }
265
266 default:
267 // parent
268 {
269 string data;
270
271 // wait till server is up
272 sleep(1);
273 socket_client_connection sc("./socket");
274
275 string errormsg;
276
277 try
278 {
279 command_client cc(sc);
280 }
281 catch(t2n_version_mismatch &e)
282 { errormsg=e.what(); }
283 catch(...)
284 { throw; }
285
286 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (1. ;)"),errormsg);
287 }
288 }
289 }
290
291 void WrongByteOrder()
292 {
293 pid_t pid;
294
295 switch(pid=fork())
296 {
297 case -1:
298 {
299 CPPUNIT_FAIL("fork error");
300 break;
301 }
302 case 0:
303 // child
304 {
305 socket_server ss("./socket");
306
307 ostringstream hello;
308 hello << "T2Nv" << PROTOCOL_VERSION << ';';
309 int byteordercheck=1;
310 int dst;
311 char* si=(char*)&byteordercheck;
312 char* di=(char*)&dst;
313
314 di[0]=si[3];
315 di[1]=si[2];
316 di[2]=si[1];
317 di[3]=si[0];
318
319 hello.write((char*)&dst,sizeof(dst));
320 hello << ';';
321
322 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
323
324 // max 10 sec
325 for (int i=0; i < 10; i++)
326 ss.fill_buffer(1000000);
327 // don't call atexit and stuff
328 _exit(0);
329 }
330
331 default:
332 // parent
333 {
334 string data;
335
336 // wait till server is up
337 sleep(1);
338 socket_client_connection sc("./socket");
339
340 string errormsg;
341
342 try
343 {
344 command_client cc(sc);
345 }
346 catch(t2n_version_mismatch &e)
347 { errormsg=e.what(); }
348 catch(...)
349 { throw; }
350
351 CPPUNIT_ASSERT_EQUAL(string("host byte order not matching"),errormsg);
352 }
353 }
354 }
355
356 void OtherServer()
357 {
358 pid_t pid;
359
360 switch(pid=fork())
361 {
362 case -1:
363 {
364 CPPUNIT_FAIL("fork error");
365 break;
366 }
367 case 0:
368 // child
369 {
370 socket_server ss("./socket");
371
372 ostringstream hello;
373 // hmm, we got the wrong socket
374 hello << "* OK intradev.net.lan Cyrus IMAP4 v2.2.13 server ready";
375
376 ss.add_callback(new_connection,bind(&test_hello::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1));
377
378 // max 3 sec
379 for (int i=0; i < 3; i++)
380 ss.fill_buffer(1000000);
381 // don't call atexit and stuff
382 _exit(0);
383 }
384
385 default:
386 // parent
387 {
388 string data;
389
390 // wait till server is up
391 sleep(1);
392 socket_client_connection sc("./socket");
393
394 string errormsg;
395
396 try
397 {
398 command_client cc(sc);
399 }
400 catch(t2n_version_mismatch &e)
401 { errormsg=e.what(); }
402 catch(...)
403 { throw; }
404
405 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
406 }
407 }
408 }
409
410};
411
412CPPUNIT_TEST_SUITE_REGISTRATION(test_hello);