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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
23 #include <thrift/c_glib/transport/thrift_transport.h>
24 #include <thrift/c_glib/transport/thrift_buffered_transport.h>
25 #include <thrift/c_glib/transport/thrift_server_transport.h>
26 #include <thrift/c_glib/transport/thrift_server_socket.h>
28 #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
30 /* substituted functions to test failures of system and library calls */
31 static int socket_error
= 0;
33 my_socket(int domain
, int type
, int protocol
)
35 if (socket_error
== 0)
37 return socket (domain
, type
, protocol
);
42 static int recv_error
= 0;
44 my_recv(int socket
, void *buffer
, size_t length
, int flags
)
48 return recv (socket
, buffer
, length
, flags
);
53 static int send_error
= 0;
55 my_send(int socket
, const void *buffer
, size_t length
, int flags
)
59 return send (socket
, buffer
, length
, flags
);
64 #define socket my_socket
67 #include "../src/thrift/c_glib/transport/thrift_socket.c"
72 static void thrift_socket_server (const int port
);
73 static void thrift_socket_server_open (const int port
, int times
);
74 /* test object creation and destruction */
76 test_create_and_destroy(void)
78 gchar
*hostname
= NULL
;
81 GObject
*object
= NULL
;
82 object
= g_object_new (THRIFT_TYPE_SOCKET
, NULL
);
83 g_assert (object
!= NULL
);
84 g_object_get (G_OBJECT(object
), "hostname", &hostname
, "port", &port
, NULL
);
87 g_object_unref (object
);
91 test_open_and_close(void)
93 ThriftSocket
*tsocket
= NULL
;
94 ThriftTransport
*transport
= NULL
;
101 g_assert ( pid
>= 0 );
106 thrift_socket_server_open (port
, 1);
109 /* parent connects, wait a bit for the socket to be created */
112 /* open a connection and close it */
113 tsocket
= g_object_new (THRIFT_TYPE_SOCKET
, "hostname", "localhost",
115 transport
= THRIFT_TRANSPORT (tsocket
);
116 thrift_socket_open (transport
, NULL
);
117 g_assert (thrift_socket_is_open (transport
) == TRUE
);
118 thrift_socket_close (transport
, NULL
);
119 g_assert (thrift_socket_is_open (transport
) == FALSE
);
121 /* test close failure */
123 thrift_socket_close (transport
, NULL
);
124 g_object_unref (tsocket
);
126 /* try a hostname lookup failure */
127 tsocket
= g_object_new (THRIFT_TYPE_SOCKET
, "hostname", "localhost.broken",
129 transport
= THRIFT_TRANSPORT (tsocket
);
130 g_assert (thrift_socket_open (transport
, &err
) == FALSE
);
131 g_object_unref (tsocket
);
135 /* try an error call to socket() */
136 tsocket
= g_object_new (THRIFT_TYPE_SOCKET
, "hostname", "localhost", NULL
);
137 transport
= THRIFT_TRANSPORT (tsocket
);
139 g_assert (thrift_socket_open (transport
, &err
) == FALSE
);
141 g_object_unref (tsocket
);
143 g_assert ( wait (&status
) == pid
);
144 g_assert ( status
== 0 );
149 test_read_and_write(void)
151 ThriftSocket
*tsocket
= NULL
;
152 ThriftTransport
*transport
= NULL
;
156 guchar buf
[10] = TEST_DATA
; /* a buffer */
159 g_assert ( pid
>= 0 );
164 thrift_socket_server (port
);
167 /* parent connects, wait a bit for the socket to be created */
170 tsocket
= g_object_new (THRIFT_TYPE_SOCKET
, "hostname", "localhost",
172 transport
= THRIFT_TRANSPORT (tsocket
);
173 g_assert (thrift_socket_open (transport
, NULL
) == TRUE
);
174 g_assert (thrift_socket_is_open (transport
));
175 thrift_socket_write (transport
, buf
, 10, NULL
);
179 thrift_socket_write (transport
, buf
, 1, NULL
);
182 thrift_socket_write_end (transport
, NULL
);
183 thrift_socket_flush (transport
, NULL
);
184 thrift_socket_close (transport
, NULL
);
185 g_object_unref (tsocket
);
187 g_assert ( wait (&status
) == pid
);
188 g_assert ( status
== 0 );
192 /* test ThriftSocket's peek() implementation */
200 ThriftTransport
*client_transport
;
201 GError
*error
= NULL
;
203 client_transport
= g_object_new (THRIFT_TYPE_SOCKET
,
204 "hostname", "localhost",
208 /* thrift_transport_peek returns FALSE when the socket is closed */
209 g_assert (thrift_transport_is_open (client_transport
) == FALSE
);
210 g_assert (thrift_transport_peek (client_transport
, &error
) == FALSE
);
211 g_assert (error
== NULL
);
218 ThriftServerTransport
*server_transport
= NULL
;
220 g_object_unref (client_transport
);
223 server_transport
= g_object_new (THRIFT_TYPE_SERVER_SOCKET
,
226 g_assert (server_transport
!= NULL
);
228 thrift_server_transport_listen (server_transport
, &error
);
229 g_assert (error
== NULL
);
231 client_transport
= g_object_new
232 (THRIFT_TYPE_BUFFERED_TRANSPORT
,
233 "transport", thrift_server_transport_accept (server_transport
, &error
),
235 "w_buf_size", sizeof data
,
237 g_assert (error
== NULL
);
238 g_assert (client_transport
!= NULL
);
240 /* write exactly one character to the client */
241 g_assert (thrift_transport_write (client_transport
,
246 thrift_transport_flush (client_transport
, &error
);
247 thrift_transport_write_end (client_transport
, &error
);
248 thrift_transport_close (client_transport
, &error
);
250 g_object_unref (client_transport
);
251 g_object_unref (server_transport
);
256 /* parent connects, wait a bit for the socket to be created */
259 /* connect to the child */
260 thrift_transport_open (client_transport
, &error
);
261 g_assert (error
== NULL
);
262 g_assert (thrift_transport_is_open (client_transport
) == TRUE
);
264 /* thrift_transport_peek returns TRUE when the socket is open and there is
265 data available to be read */
266 g_assert (thrift_transport_peek (client_transport
, &error
) == TRUE
);
267 g_assert (error
== NULL
);
269 /* read exactly one character from the server */
270 g_assert_cmpint (thrift_transport_read (client_transport
,
273 &error
), ==, sizeof data
);
275 /* thrift_transport_peek returns FALSE when the socket is open but there is
276 no (more) data available to be read */
277 g_assert (thrift_transport_is_open (client_transport
) == TRUE
);
278 g_assert (thrift_transport_peek (client_transport
, &error
) == FALSE
);
279 g_assert (error
== NULL
);
281 thrift_transport_read_end (client_transport
, &error
);
282 thrift_transport_close (client_transport
, &error
);
284 g_object_unref (client_transport
);
286 g_assert (wait (&status
) == pid
);
287 g_assert (status
== 0);
292 thrift_socket_server_open (const int port
, int times
)
294 ThriftServerTransport
*transport
= NULL
;
295 ThriftTransport
*client
= NULL
;
297 ThriftServerSocket
*tsocket
= g_object_new (THRIFT_TYPE_SERVER_SOCKET
,
300 transport
= THRIFT_SERVER_TRANSPORT (tsocket
);
301 thrift_server_transport_listen (transport
, NULL
);
302 for(i
=0;i
<times
;i
++){
303 client
= thrift_server_transport_accept (transport
, NULL
);
304 g_assert (client
!= NULL
);
305 thrift_socket_close (client
, NULL
);
306 g_object_unref (client
);
308 g_object_unref (tsocket
);
313 thrift_socket_server (const int port
)
316 ThriftServerTransport
*transport
= NULL
;
317 ThriftTransport
*client
= NULL
;
318 guchar buf
[10]; /* a buffer */
319 guchar match
[10] = TEST_DATA
;
321 ThriftServerSocket
*tsocket
= g_object_new (THRIFT_TYPE_SERVER_SOCKET
,
324 transport
= THRIFT_SERVER_TRANSPORT (tsocket
);
325 thrift_server_transport_listen (transport
, NULL
);
326 client
= thrift_server_transport_accept (transport
, NULL
);
327 g_assert (client
!= NULL
);
330 bytes
= thrift_socket_read (client
, buf
, 10, NULL
);
331 g_assert (bytes
== 10); /* make sure we've read 10 bytes */
332 g_assert ( memcmp(buf
, match
, 10) == 0 ); /* make sure what we got matches */
336 thrift_socket_read (client
, buf
, 1, NULL
);
339 thrift_socket_read_end (client
, NULL
);
340 thrift_socket_close (client
, NULL
);
341 g_object_unref (tsocket
);
342 g_object_unref (client
);
346 main(int argc
, char *argv
[])
348 #if (!GLIB_CHECK_VERSION (2, 36, 0))
352 g_test_init (&argc
, &argv
, NULL
);
354 g_test_add_func ("/testtransportsocket/CreateAndDestroy", test_create_and_destroy
);
355 g_test_add_func ("/testtransportsocket/OpenAndClose", test_open_and_close
);
356 g_test_add_func ("/testtransportsocket/ReadAndWrite", test_read_and_write
);
357 g_test_add_func ("/testtransportsocket/Peek", test_peek
);
359 return g_test_run ();