libt2n: (tomj) added exception handling to every child after fork(). This is needed...
[libt2n] / test / newserver.cpp
CommitLineData
039e52da
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 <cppunit/extensions/TestFactoryRegistry.h>
19#include <cppunit/ui/text/TestRunner.h>
20#include <cppunit/extensions/HelperMacros.h>
21
22#include <boost/archive/binary_oarchive.hpp>
23#include <boost/archive/binary_iarchive.hpp>
24#include <boost/archive/xml_oarchive.hpp>
25#include <boost/archive/xml_iarchive.hpp>
26#include <boost/serialization/serialization.hpp>
27
28#include <container.hxx>
29#include <socket_client.hxx>
30#include <socket_server.hxx>
31#include <command_client.hxx>
32#include <command_server.hxx>
33
34using namespace std;
35using namespace CppUnit;
36
37int newserver_func(int i)
38{
39
40 return 1;
41}
42
43class newserver_res : public libt2n::result
44{
45 private:
46 int res;
47
48 friend class boost::serialization::access;
49 template<class Archive>
50 void serialize(Archive & ar, const unsigned int version)
51 {
52 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
53 ar & BOOST_SERIALIZATION_NVP(res);
54 }
55
56 public:
57 newserver_res()
58 { }
59
60 newserver_res(int i)
61 {
62 res=i;
63 }
64
65 int get_data()
66 {
67 return res;
68 }
69};
70
71
72class newserver_cmd : public libt2n::command
73{
74 private:
75 int param;
76
77 friend class boost::serialization::access;
78 template<class Archive>
79 void serialize(Archive & ar, const unsigned int version)
80 {
81 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
82 ar & BOOST_SERIALIZATION_NVP(param);
83 }
84
85 public:
86 newserver_cmd()
87 { }
88
89 newserver_cmd(int i)
90 {
91 param=i;
92 }
93
94 libt2n::result* operator()()
95 {
96 return new newserver_res(newserver_func(param));
97 }
98};
99
100#include <boost/serialization/export.hpp>
101
102BOOST_CLASS_EXPORT(newserver_cmd)
103BOOST_CLASS_EXPORT(newserver_res)
104
105using namespace libt2n;
106
107class test_newserver : public TestFixture
108{
109 CPPUNIT_TEST_SUITE(test_newserver);
110
111 CPPUNIT_TEST(NewServerSocket);
112
113 CPPUNIT_TEST_SUITE_END();
114
115 pid_t child_pid;
116
117 public:
118
119 void setUp()
120 { }
121
122 void tearDown()
123 {
124 // make sure the server-child is dead before the next test runs
125 kill(child_pid,SIGKILL);
126 sleep(1);
127 }
128
129 void NewServerSocket()
130 {
131 switch(child_pid=fork())
132 {
133 case -1:
134 {
135 CPPUNIT_FAIL("fork error");
136 break;
137 }
138 case 0:
139 // child
140 {
441d41fe 141 try
039e52da 142 {
441d41fe
TJ
143 {
144 socket_server ss("./socket");
145 command_server cs(ss);
146
147 // handle new connection and just one command
148 cs.handle(10000000);
149 cs.handle(10000000);
150 }
151 // close socket, create new one
152 {
153 socket_server ss("./socket");
154 ss.set_logging(&cerr,debug);
155 command_server cs(ss);
156
157 // max 30 sec
158 for (int i=0; i < 30; i++)
159 cs.handle(1000000);
160 }
161 } catch(...)
039e52da 162 {
441d41fe 163 std::cerr << "exception in child. ignoring\n";
039e52da
GE
164 }
165
166 // don't call atexit and stuff
167 _exit(0);
168 }
169
170 default:
171 // parent
172 {
56f3994d
TJ
173 // don't kill us on broken pipe
174 signal(SIGPIPE, SIG_IGN);
175
039e52da
GE
176 // wait till server is up
177 sleep(1);
178 socket_client_connection sc("./socket");
179 sc.set_logging(&cerr,debug);
180 command_client cc(&sc);
181
182 result_container rc;
183 cc.send_command(new newserver_cmd(1),rc);
184
185 // very short sleep to make sure new server socket is up
186 usleep(10000);
187
188 // still has connection to the old server-socket
189 string errormsg;
190
191 try
192 {
193 sc.write("some stuff");
194 }
195 catch(t2n_transfer_error &e)
196 { errormsg=e.what(); }
197 catch(...)
198 { throw; }
199
56f3994d 200 CPPUNIT_ASSERT_EQUAL(string("write() returned Bad file descriptor"),errormsg);
039e52da
GE
201 }
202 }
203 }
204};
205
206CPPUNIT_TEST_SUITE_REGISTRATION(test_newserver);