blob: 45397cef4870d965bdb0c6f726c711132b652b74 [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{
252 int bytes = 0;
253 ThriftServerTransport *transport = NULL;
254 ThriftTransport *client = NULL;
255 guchar buf[10]; /* a buffer */
256 guchar match[10] = TEST_DATA;
257 int i;
258
259 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
260 "port", port, NULL);
261
262 transport = THRIFT_SERVER_TRANSPORT (tsocket);
263 thrift_server_transport_listen (transport, NULL);
264 for(i=0;i<times;i++){
265 client = thrift_server_transport_accept (transport, NULL);
266 g_assert (client != NULL);
267 thrift_socket_close (client, NULL);
268 g_object_unref (client);
Roger Meier7fa98482014-09-01 20:21:33 +0200269 }
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200270 g_object_unref (tsocket);
Roger Meier7fa98482014-09-01 20:21:33 +0200271}
272
Roger Meier213a6642010-10-27 12:30:11 +0000273static void
274thrift_server (const int port)
275{
276 int bytes = 0;
277 ThriftServerTransport *transport = NULL;
278 ThriftTransport *client = NULL;
Roger Meierc75797d2012-04-28 11:33:58 +0000279 guchar buf[12]; /* a buffer */
Roger Meier213a6642010-10-27 12:30:11 +0000280 guchar match[10] = TEST_DATA;
281
282 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200283 "port", port, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000284
285 transport = THRIFT_SERVER_TRANSPORT (tsocket);
286 thrift_server_transport_listen (transport, NULL);
287
288 /* wrap the client in a BufferedTransport */
289 client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport",
Gonzalo Aguilar Delgado87ad2bc2017-09-15 12:26:02 +0200290 thrift_server_transport_accept (transport, NULL),
291 "r_buf_size", 5, NULL);
James E. King, III43f4bf22017-10-28 12:54:02 -0400292 g_assert (client != NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000293
294 /* read 10 bytes */
295 bytes = thrift_framed_transport_read (client, buf, 10, NULL);
James E. King, III43f4bf22017-10-28 12:54:02 -0400296 g_assert (bytes == 10); /* make sure we've read 10 bytes */
297 g_assert ( memcmp (buf, match, 10) == 0 ); /* make sure what we got matches */
Roger Meier213a6642010-10-27 12:30:11 +0000298
299 bytes = thrift_framed_transport_read (client, buf, 6, NULL);
300 bytes = thrift_framed_transport_read (client, buf, 5, NULL);
301 bytes = thrift_framed_transport_read (client, buf, 1, NULL);
302
303 bytes = thrift_framed_transport_read (client, buf, 12, NULL);
304
305 thrift_framed_transport_read_end (client, NULL);
306 thrift_framed_transport_close (client, NULL);
307 g_object_unref (client);
308 g_object_unref (tsocket);
309}
310
311int
Roger Meierc1010922010-11-26 10:17:48 +0000312main(int argc, char *argv[])
Roger Meier213a6642010-10-27 12:30:11 +0000313{
Jens Geyer1c190272015-07-28 23:15:18 +0200314#if (!GLIB_CHECK_VERSION (2, 36, 0))
Roger Meier213a6642010-10-27 12:30:11 +0000315 g_type_init();
Jens Geyer1c190272015-07-28 23:15:18 +0200316#endif
317
Roger Meierc1010922010-11-26 10:17:48 +0000318 g_test_init (&argc, &argv, NULL);
Roger Meier213a6642010-10-27 12:30:11 +0000319
Roger Meierc1010922010-11-26 10:17:48 +0000320 g_test_add_func ("/testframedtransport/CreateAndDestroy", test_create_and_destroy);
321 g_test_add_func ("/testframedtransport/OpenAndClose", test_open_and_close);
322 g_test_add_func ("/testframedtransport/ReadAndWrite", test_read_and_write);
Roger Meier7fa98482014-09-01 20:21:33 +0200323 g_test_add_func ("/testframedtransport/ReadAfterPeerClose", test_read_after_peer_close);
Roger Meierc1010922010-11-26 10:17:48 +0000324
325 return g_test_run ();
Roger Meier213a6642010-10-27 12:30:11 +0000326}