blob: 008e61e40cb00445245f9cbe481b5cf0374272b7 [file] [log] [blame]
Roger Meierc1010922010-11-26 10:17:48 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Roger Meier213a6642010-10-27 12:30:11 +000020#include <netdb.h>
Jens Geyer1c190272015-07-28 23:15:18 +020021#include <sys/wait.h>
Roger Meier213a6642010-10-27 12:30:11 +000022
Roger Meiere3da7682013-01-11 11:41:53 +010023#include <thrift/c_glib/transport/thrift_transport.h>
24#include <thrift/c_glib/transport/thrift_socket.h>
25#include <thrift/c_glib/transport/thrift_server_transport.h>
26#include <thrift/c_glib/transport/thrift_server_socket.h>
Roger Meier213a6642010-10-27 12:30:11 +000027
28#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
29
Roger Meiere3da7682013-01-11 11:41:53 +010030#include "../src/thrift/c_glib/transport/thrift_framed_transport.c"
Roger Meier213a6642010-10-27 12:30:11 +000031
Roger Meier213a6642010-10-27 12:30:11 +000032static void thrift_server (const int port);
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020033static void thrift_socket_server_open (const int port, int times);
Roger Meier213a6642010-10-27 12:30:11 +000034
35/* test object creation and destruction */
36static void
37test_create_and_destroy(void)
38{
39 ThriftTransport *transport = NULL;
40 guint r_buf_size = 0;
41 guint w_buf_size = 0;
42
43 GObject *object = NULL;
44 object = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, NULL);
James E. King, III43f4bf22017-10-28 12:54:02 -040045 g_assert (object != NULL);
Roger Meier213a6642010-10-27 12:30:11 +000046 g_object_get (G_OBJECT (object), "transport", &transport,
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020047 "r_buf_size", &r_buf_size,
48 "w_buf_size", &w_buf_size, NULL);
Roger Meier213a6642010-10-27 12:30:11 +000049 g_object_unref (object);
50}
51
52static void
53test_open_and_close(void)
54{
55 ThriftSocket *tsocket = NULL;
56 ThriftTransport *transport = NULL;
57 GError *err = NULL;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020058 pid_t pid;
59 int port = 51199;
60 int status;
Roger Meier213a6642010-10-27 12:30:11 +000061
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020062 pid = fork ();
63 g_assert ( pid >= 0 );
Roger Meier213a6642010-10-27 12:30:11 +000064
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020065 if ( pid == 0 )
66 {
67 /* child listens */
68 thrift_socket_server_open (port,1);
69 exit (0);
70 } else {
71 /* parent connects, wait a bit for the socket to be created */
72 sleep (1);
73 /* create a ThriftSocket */
74 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
75 "port", port, NULL);
Roger Meier213a6642010-10-27 12:30:11 +000076
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020077 /* create a BufferedTransport wrapper of the Socket */
78 transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
79 "transport", THRIFT_TRANSPORT (tsocket), NULL);
Roger Meier213a6642010-10-27 12:30:11 +000080
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020081 /* this shouldn't work */
82 g_assert (thrift_framed_transport_open (transport, NULL) == TRUE);
83 g_assert (thrift_framed_transport_is_open (transport) == TRUE);
84 g_assert (thrift_framed_transport_close (transport, NULL) == TRUE);
85 g_object_unref (transport);
86 g_object_unref (tsocket);
Roger Meier213a6642010-10-27 12:30:11 +000087
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020088 /* try and underlying socket failure */
89 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
90 NULL);
Roger Meier213a6642010-10-27 12:30:11 +000091
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +020092 /* create a BufferedTransport wrapper of the Socket */
93 transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
94 "transport", THRIFT_TRANSPORT (tsocket), NULL);
95
96 g_assert (thrift_framed_transport_open (transport, &err) == FALSE);
97 g_object_unref (transport);
98 g_object_unref (tsocket);
99 g_error_free (err);
100 err = NULL;
101
102 g_assert ( wait (&status) == pid );
103 g_assert ( status == 0 );
104 }
Roger Meier213a6642010-10-27 12:30:11 +0000105}
106
107static void
108test_read_and_write(void)
109{
110 int status;
111 pid_t pid;
112 ThriftSocket *tsocket = NULL;
113 ThriftTransport *transport = NULL;
114 int port = 51199;
115 guchar buf[10] = TEST_DATA; /* a buffer */
116
117 pid = fork ();
James E. King, III43f4bf22017-10-28 12:54:02 -0400118 g_assert ( pid >= 0 );
Roger Meier213a6642010-10-27 12:30:11 +0000119
120 if ( pid == 0 )
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200121 {
122 /* child listens */
123 thrift_server (port);
124 exit (0);
125 } else {
126 /* parent connects, wait a bit for the socket to be created */
127 sleep (1);
Roger Meier213a6642010-10-27 12:30:11 +0000128
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200129 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
130 "port", port, NULL);
131 transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
132 "transport", THRIFT_TRANSPORT (tsocket),
133 "w_buf_size", 4, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000134
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200135 g_assert (thrift_framed_transport_open (transport, NULL) == TRUE);
136 g_assert (thrift_framed_transport_is_open (transport));
Roger Meier213a6642010-10-27 12:30:11 +0000137
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200138 /* write 10 bytes */
139 thrift_framed_transport_write (transport, buf, 10, NULL);
140 thrift_framed_transport_flush (transport, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000141
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200142 thrift_framed_transport_write (transport, buf, 1, NULL);
143 thrift_framed_transport_flush (transport, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000144
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200145 thrift_framed_transport_write (transport, buf, 10, NULL);
146 thrift_framed_transport_flush (transport, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000147
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200148 thrift_framed_transport_write (transport, buf, 10, NULL);
149 thrift_framed_transport_flush (transport, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000150
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200151 thrift_framed_transport_write_end (transport, NULL);
152 thrift_framed_transport_flush (transport, NULL);
153 thrift_framed_transport_close (transport, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000154
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200155 g_object_unref (transport);
156 g_object_unref (tsocket);
Roger Meier213a6642010-10-27 12:30:11 +0000157
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200158 g_assert ( wait (&status) == pid );
159 g_assert ( status == 0 );
160 }
Roger Meier213a6642010-10-27 12:30:11 +0000161}
162
Roger Meier7fa98482014-09-01 20:21:33 +0200163/* test reading from the transport after the peer has unexpectedly
164 closed the connection */
165static void
166test_read_after_peer_close(void)
167{
168 int status;
169 pid_t pid;
170 int port = 51199;
171 GError *err = NULL;
172
173 pid = fork ();
174 g_assert (pid >= 0);
175
176 if (pid == 0)
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200177 {
178 ThriftServerTransport *server_transport = NULL;
179 ThriftTransport *client_transport = NULL;
Roger Meier7fa98482014-09-01 20:21:33 +0200180
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200181 /* child listens */
182 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
183 "port", port,
184 NULL);
185 g_assert (server_transport != NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200186
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200187 thrift_server_transport_listen (server_transport, &err);
188 g_assert (err == NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200189
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200190 /* wrap the client transport in a ThriftFramedTransport */
191 client_transport = g_object_new
192 (THRIFT_TYPE_FRAMED_TRANSPORT,
193 "transport", thrift_server_transport_accept (server_transport, &err),
194 "r_buf_size", 0,
195 NULL);
196 g_assert (err == NULL);
197 g_assert (client_transport != NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200198
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200199 /* close the connection immediately after the client connects */
200 thrift_transport_close (client_transport, NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200201
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200202 g_object_unref (client_transport);
203 g_object_unref (server_transport);
Roger Meier7fa98482014-09-01 20:21:33 +0200204
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200205 exit (0);
206 } else {
207 ThriftSocket *tsocket = NULL;
208 ThriftTransport *transport = NULL;
209 guchar buf[10]; /* a buffer */
Roger Meier7fa98482014-09-01 20:21:33 +0200210
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200211 /* parent connects, wait a bit for the socket to be created */
212 sleep (1);
Roger Meier7fa98482014-09-01 20:21:33 +0200213
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200214 tsocket = g_object_new (THRIFT_TYPE_SOCKET,
215 "hostname", "localhost",
216 "port", port,
217 NULL);
218 transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
219 "transport", THRIFT_TRANSPORT (tsocket),
220 "w_buf_size", 0,
221 NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200222
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200223 g_assert (thrift_transport_open (transport, NULL) == TRUE);
224 g_assert (thrift_transport_is_open (transport));
Roger Meier7fa98482014-09-01 20:21:33 +0200225
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200226 /* attempting to read from the transport after the peer has closed
Roger Meier7fa98482014-09-01 20:21:33 +0200227 the connection fails gracefully without generating a critical
228 warning or segmentation fault */
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200229 thrift_transport_read (transport, buf, 10, &err);
230 g_assert (err != NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200231
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200232 g_error_free (err);
233 err = NULL;
Roger Meier7fa98482014-09-01 20:21:33 +0200234
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200235 thrift_transport_read_end (transport, &err);
236 g_assert (err == NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200237
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200238 thrift_transport_close (transport, &err);
239 g_assert (err == NULL);
Roger Meier7fa98482014-09-01 20:21:33 +0200240
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200241 g_object_unref (transport);
242 g_object_unref (tsocket);
Roger Meier7fa98482014-09-01 20:21:33 +0200243
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200244 g_assert (wait (&status) == pid);
245 g_assert (status == 0);
246 }
247}
248
249static void
250thrift_socket_server_open (const int port, int times)
251{
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200252 ThriftServerTransport *transport = NULL;
253 ThriftTransport *client = NULL;
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200254 int i;
255
256 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
257 "port", port, NULL);
258
259 transport = THRIFT_SERVER_TRANSPORT (tsocket);
260 thrift_server_transport_listen (transport, NULL);
261 for(i=0;i<times;i++){
262 client = thrift_server_transport_accept (transport, NULL);
263 g_assert (client != NULL);
264 thrift_socket_close (client, NULL);
265 g_object_unref (client);
Roger Meier7fa98482014-09-01 20:21:33 +0200266 }
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200267 g_object_unref (tsocket);
Roger Meier7fa98482014-09-01 20:21:33 +0200268}
269
Roger Meier213a6642010-10-27 12:30:11 +0000270static void
271thrift_server (const int port)
272{
273 int bytes = 0;
274 ThriftServerTransport *transport = NULL;
275 ThriftTransport *client = NULL;
Roger Meierc75797d2012-04-28 11:33:58 +0000276 guchar buf[12]; /* a buffer */
Roger Meier213a6642010-10-27 12:30:11 +0000277 guchar match[10] = TEST_DATA;
278
279 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200280 "port", port, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000281
282 transport = THRIFT_SERVER_TRANSPORT (tsocket);
283 thrift_server_transport_listen (transport, NULL);
284
285 /* wrap the client in a BufferedTransport */
286 client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport",
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200287 thrift_server_transport_accept (transport, NULL),
288 "r_buf_size", 5, NULL);
James E. King, III43f4bf22017-10-28 12:54:02 -0400289 g_assert (client != NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000290
291 /* read 10 bytes */
292 bytes = thrift_framed_transport_read (client, buf, 10, NULL);
James E. King, III43f4bf22017-10-28 12:54:02 -0400293 g_assert (bytes == 10); /* make sure we've read 10 bytes */
294 g_assert ( memcmp (buf, match, 10) == 0 ); /* make sure what we got matches */
Roger Meier213a6642010-10-27 12:30:11 +0000295
296 bytes = thrift_framed_transport_read (client, buf, 6, NULL);
297 bytes = thrift_framed_transport_read (client, buf, 5, NULL);
298 bytes = thrift_framed_transport_read (client, buf, 1, NULL);
299
300 bytes = thrift_framed_transport_read (client, buf, 12, NULL);
301
302 thrift_framed_transport_read_end (client, NULL);
303 thrift_framed_transport_close (client, NULL);
304 g_object_unref (client);
305 g_object_unref (tsocket);
306}
307
308int
Roger Meierc1010922010-11-26 10:17:48 +0000309main(int argc, char *argv[])
Roger Meier213a6642010-10-27 12:30:11 +0000310{
Jens Geyer1c190272015-07-28 23:15:18 +0200311#if (!GLIB_CHECK_VERSION (2, 36, 0))
Roger Meier213a6642010-10-27 12:30:11 +0000312 g_type_init();
Jens Geyer1c190272015-07-28 23:15:18 +0200313#endif
314
Roger Meierc1010922010-11-26 10:17:48 +0000315 g_test_init (&argc, &argv, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000316
Roger Meierc1010922010-11-26 10:17:48 +0000317 g_test_add_func ("/testframedtransport/CreateAndDestroy", test_create_and_destroy);
318 g_test_add_func ("/testframedtransport/OpenAndClose", test_open_and_close);
319 g_test_add_func ("/testframedtransport/ReadAndWrite", test_read_and_write);
Roger Meier7fa98482014-09-01 20:21:33 +0200320 g_test_add_func ("/testframedtransport/ReadAfterPeerClose", test_read_after_peer_close);
Roger Meierc1010922010-11-26 10:17:48 +0000321
322 return g_test_run ();
Roger Meier213a6642010-10-27 12:30:11 +0000323}