Prepare libt2n 0.7 release
[libt2n] / test / getsocket.cpp
1 /*
2 Copyright (C) 2013 by Intra2net AG
3
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 */
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 #include <set>
33
34 #define BOOST_TEST_DYN_LINK
35 #include <boost/test/unit_test.hpp>
36
37 #include <boost/archive/binary_oarchive.hpp>
38 #include <boost/archive/binary_iarchive.hpp>
39 #include <boost/archive/xml_oarchive.hpp>
40 #include <boost/archive/xml_iarchive.hpp>
41 #include <boost/serialization/serialization.hpp>
42
43 #include <container.hxx>
44 #include <socket_client.hxx>
45 #include <socket_server.hxx>
46 #include <command_client.hxx>
47 #include <command_server.hxx>
48
49 #include "test_fixtures.hxx"
50
51 using namespace std;
52
53 set<int> SocketSet;
54
55 bool check_sockets(const int& test_socket)
56 {
57     bool ret = false;
58     set<int>::iterator it;
59     for (it = SocketSet.begin(); it != SocketSet.end(); it++)
60     {
61         if (test_socket == *it)
62         {
63             ret = true;
64             break;
65         }
66     }
67     return ret;
68 }
69
70 class checkfunc_res : public libt2n::result
71 {
72     private:
73         bool res;
74
75         friend class boost::serialization::access;
76         template<class Archive>
77         void serialize(Archive & ar, const unsigned int version)
78         {
79             ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
80             ar & BOOST_SERIALIZATION_NVP(res);
81         }
82
83     public:
84         checkfunc_res()
85             { }
86
87         checkfunc_res(const bool& value)
88         {
89             res=value;
90         }
91
92         bool get_data()
93         {
94             return res;
95         }
96 };
97
98
99 class checkfunc_cmd : public libt2n::command
100 {
101     private:
102         int param;
103
104         friend class boost::serialization::access;
105         template<class Archive>
106         void serialize(Archive & ar, const unsigned int version)
107         {
108             ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
109             ar & BOOST_SERIALIZATION_NVP(param);
110         }
111
112     public:
113         checkfunc_cmd()
114             {}
115
116         checkfunc_cmd(const int& value)
117         {
118             param=value;
119         }
120
121         libt2n::result* operator()()
122         {
123             return new checkfunc_res(check_sockets(param));
124         }
125 };
126
127 #include <boost/serialization/export.hpp>
128
129 BOOST_CLASS_EXPORT(checkfunc_cmd)
130 BOOST_CLASS_EXPORT(checkfunc_res)
131
132 using namespace libt2n;
133
134 BOOST_FIXTURE_TEST_SUITE(test_getsocket, KillChildOnShutdownFixture)
135
136 BOOST_AUTO_TEST_CASE(SocketCheck)
137 {
138     switch(child_pid=fork())
139     {
140         case -1:
141         {
142             BOOST_FAIL("fork error");
143             break;
144         }
145         case 0:
146         // child
147         {
148             try
149             {
150                 socket_server ss("./socket");
151                 command_server cs(ss);
152
153                 // max 10 sec
154                 for (int i=0; i < 10; i++)
155                 {
156                     SocketSet = ss.get_sockets_set();
157                     cs.handle(1000000);
158                 }
159             } catch(...)
160             {
161                 std::cerr << "exception in child. ignoring\n";
162             }
163
164             // don't call atexit and stuff
165             _exit(0);
166         }
167
168         default:
169         // parent
170         {
171             // wait till server is up
172             sleep(1);
173             socket_client_connection sc("./socket");
174             sc.set_logging(&cerr,debug);
175             command_client cc(&sc);
176
177             result_container rc;
178             int socket_fd = sc.get_socket();
179             // Next line causes problem
180             cc.send_command(new checkfunc_cmd(socket_fd),rc);
181
182             bool ret=dynamic_cast<checkfunc_res*>(rc.get_result())->get_data();
183
184             BOOST_CHECK(ret);
185         }
186     }
187 }
188
189
190 BOOST_AUTO_TEST_SUITE_END()