libt2n: (gerd) make sure no exception is thrown in command_client constructor, fix...
[libt2n] / test / serialize.cpp
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
34 using namespace std;
35 using namespace CppUnit;
36
37 string testfunc3(const string& str)
38 {
39     if (str=="throw")
40         throw libt2n::t2n_runtime_error("throw me around");
41     string ret(str);
42     ret+=", testfunc() was here";
43     return ret;
44 }
45
46 class testfunc3_res : public libt2n::result
47 {
48     private:
49         string res;
50
51         friend class boost::serialization::access;
52         template<class Archive>
53         void serialize(Archive & ar, const unsigned int version)
54         {
55             ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
56             ar & BOOST_SERIALIZATION_NVP(res);
57         }
58
59     public:
60         testfunc3_res()
61             { }
62
63         testfunc3_res(const string& str)
64         {
65             res=str;
66         }
67
68         string get_data()
69         {
70             return res;
71         }
72 };
73
74
75 class testfunc3_cmd : public libt2n::command
76 {
77     private:
78         string param;
79
80         friend class boost::serialization::access;
81         template<class Archive>
82         void serialize(Archive & ar, const unsigned int version)
83         {
84             ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
85             ar & BOOST_SERIALIZATION_NVP(param);
86         }
87
88     public:
89         testfunc3_cmd()
90             { }
91
92         testfunc3_cmd(const string& str)
93         {
94             param=str;
95         }
96
97         libt2n::result* operator()()
98         {
99             return new testfunc3_res(testfunc3(param));
100         }
101 };
102
103 #include <boost/serialization/export.hpp>
104
105 using namespace libt2n;
106
107 class test_serialize : public TestFixture
108 {
109     CPPUNIT_TEST_SUITE(test_serialize);
110
111     CPPUNIT_TEST(ClientSerializeErr);
112
113     // TODO: Server Deserialization Error
114     // TODO: Server Serialization Error
115     // TODO: Client Deserialization Error
116     // but those probably need separate client/server binaries
117
118     CPPUNIT_TEST_SUITE_END();
119
120     pid_t child_pid;
121
122     public:
123
124     void setUp()
125     { }
126
127     void tearDown()
128     {
129         // make sure the server-child is dead before the next test runs
130         kill(child_pid,SIGKILL);
131         sleep(1);
132     }
133
134     void ClientSerializeErr()
135     {
136         switch(child_pid=fork())
137         {
138             case -1:
139             {
140                 CPPUNIT_FAIL("fork error");
141                 break;
142             }
143             case 0:
144             // child
145             {
146                 socket_server ss("./socket");
147                 command_server cs(ss);
148
149                 // max 10 sec
150                 for (int i=0; i < 10; i++)
151                     cs.handle(1000000);
152
153                 // don't call atexit and stuff
154                 _exit(0);
155             }
156
157             default:
158             // parent
159             {
160                 // wait till server is up
161                 sleep(1);
162                 socket_client_connection sc("./socket");
163                 command_client cc(&sc);
164
165                 string errormsg;
166
167                 result_container rc;
168                 try
169                 {
170                     cc.send_command(new testfunc3_cmd("xyz"),rc);
171                 }
172                 catch(t2n_serialization_error &e)
173                     { errormsg=e.what(); }
174                 catch(...)
175                     { throw; }
176
177                 CPPUNIT_ASSERT_EQUAL(string("archive_exception while serializing on client-side, code 2 (unregistered class)"),errormsg);
178             }
179         }
180     }
181
182 };
183
184 CPPUNIT_TEST_SUITE_REGISTRATION(test_serialize);