1 /* GLib testing framework examples and tests
3 * Copyright (C) 2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include <glib/gstdio.h>
24 #include <gio/gunixinputstream.h>
25 #include <gio/gunixoutputstream.h>
29 GPollableInputStream
*in
;
33 poll_source_callback (GPollableInputStream
*in
,
39 gboolean
*success
= user_data
;
41 nread
= g_pollable_input_stream_read_nonblocking (in
, buf
, 2, NULL
, &error
);
42 g_assert_no_error (error
);
43 g_assert_cmpint (nread
, ==, 2);
44 g_assert_cmpstr (buf
, ==, "x");
47 return G_SOURCE_REMOVE
;
51 check_source_readability_callback (gpointer user_data
)
53 gboolean expected
= GPOINTER_TO_INT (user_data
);
56 readable
= g_pollable_input_stream_is_readable (in
);
57 g_assert_cmpint (readable
, ==, expected
);
58 return G_SOURCE_REMOVE
;
62 write_callback (gpointer user_data
)
64 const char *buf
= "x";
68 nwrote
= g_output_stream_write (out
, buf
, 2, NULL
, &error
);
69 g_assert_no_error (error
);
70 g_assert_cmpint (nwrote
, ==, 2);
71 /* Give the pipe a few ticks to propagate the write for sockets. On my
72 * iMac i7, 40 works, 30 doesn't. */
75 check_source_readability_callback (GINT_TO_POINTER (TRUE
));
77 return G_SOURCE_REMOVE
;
81 check_source_and_quit_callback (gpointer user_data
)
83 check_source_readability_callback (user_data
);
84 g_main_loop_quit (loop
);
85 return G_SOURCE_REMOVE
;
96 gboolean success
= FALSE
;
98 g_assert (g_pollable_input_stream_can_poll (in
));
99 g_assert (g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (out
)));
101 readable
= g_pollable_input_stream_is_readable (in
);
102 g_assert (!readable
);
104 nread
= g_pollable_input_stream_read_nonblocking (in
, buf
, 1, NULL
, &error
);
105 g_assert_cmpint (nread
, ==, -1);
106 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_WOULD_BLOCK
);
107 g_clear_error (&error
);
109 /* Create 4 sources, in decreasing order of priority:
110 * 1. poll source on @in
111 * 2. idle source that checks if @in is readable once
112 * (it won't be) and then removes itself
113 * 3. idle source that writes a byte to @out, checks that
114 * @in is now readable, and removes itself
115 * 4. idle source that checks if @in is readable once
116 * (it won't be, since the poll source will fire before
117 * this one does) and then quits the loop.
119 * If the poll source triggers before it should, then it will get a
120 * %G_IO_ERROR_WOULD_BLOCK, and if check() fails in either
121 * direction, we will catch it at some point.
124 poll_source
= g_pollable_input_stream_create_source (in
, NULL
);
125 g_source_set_priority (poll_source
, 1);
126 g_source_set_callback (poll_source
, (GSourceFunc
) poll_source_callback
, &success
, NULL
);
127 g_source_attach (poll_source
, NULL
);
128 g_source_unref (poll_source
);
130 g_idle_add_full (2, check_source_readability_callback
, GINT_TO_POINTER (FALSE
), NULL
);
131 g_idle_add_full (3, write_callback
, NULL
, NULL
);
132 g_idle_add_full (4, check_source_and_quit_callback
, GINT_TO_POINTER (FALSE
), NULL
);
134 loop
= g_main_loop_new (NULL
, FALSE
);
135 g_main_loop_run (loop
);
136 g_main_loop_unref (loop
);
138 g_assert_cmpint (success
, ==, TRUE
);
143 test_pollable_unix (void)
145 int pipefds
[2], status
, fd
;
147 status
= pipe (pipefds
);
148 g_assert_cmpint (status
, ==, 0);
150 in
= G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (pipefds
[0], TRUE
));
151 out
= g_unix_output_stream_new (pipefds
[1], TRUE
);
156 g_object_unref (out
);
158 /* Non-pipe/socket unix streams are not pollable */
159 fd
= g_open ("/dev/null", O_RDWR
, 0);
160 g_assert_cmpint (fd
, !=, -1);
161 in
= G_POLLABLE_INPUT_STREAM (g_unix_input_stream_new (fd
, FALSE
));
162 out
= g_unix_output_stream_new (fd
, FALSE
);
164 g_assert (!g_pollable_input_stream_can_poll (in
));
165 g_assert (!g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (out
)));
168 g_object_unref (out
);
173 test_pollable_converter (void)
175 GConverter
*converter
;
176 GError
*error
= NULL
;
178 int pipefds
[2], status
;
180 status
= pipe (pipefds
);
181 g_assert_cmpint (status
, ==, 0);
183 ibase
= G_INPUT_STREAM (g_unix_input_stream_new (pipefds
[0], TRUE
));
184 converter
= G_CONVERTER (g_charset_converter_new ("UTF-8", "UTF-8", &error
));
185 g_assert_no_error (error
);
187 in
= G_POLLABLE_INPUT_STREAM (g_converter_input_stream_new (ibase
, converter
));
188 g_object_unref (converter
);
189 g_object_unref (ibase
);
191 out
= g_unix_output_stream_new (pipefds
[1], TRUE
);
196 g_object_unref (out
);
202 client_connected (GObject
*source
,
203 GAsyncResult
*result
,
206 GSocketClient
*client
= G_SOCKET_CLIENT (source
);
207 GSocketConnection
**conn
= user_data
;
208 GError
*error
= NULL
;
210 *conn
= g_socket_client_connect_finish (client
, result
, &error
);
211 g_assert_no_error (error
);
215 server_connected (GObject
*source
,
216 GAsyncResult
*result
,
219 GSocketListener
*listener
= G_SOCKET_LISTENER (source
);
220 GSocketConnection
**conn
= user_data
;
221 GError
*error
= NULL
;
223 *conn
= g_socket_listener_accept_finish (listener
, result
, NULL
, &error
);
224 g_assert_no_error (error
);
228 test_pollable_socket (void)
231 GSocketAddress
*saddr
, *effective_address
;
232 GSocketListener
*listener
;
233 GSocketClient
*client
;
234 GError
*error
= NULL
;
235 GSocketConnection
*client_conn
= NULL
, *server_conn
= NULL
;
237 iaddr
= g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4
);
238 saddr
= g_inet_socket_address_new (iaddr
, 0);
239 g_object_unref (iaddr
);
241 listener
= g_socket_listener_new ();
242 g_socket_listener_add_address (listener
, saddr
,
243 G_SOCKET_TYPE_STREAM
,
244 G_SOCKET_PROTOCOL_TCP
,
248 g_assert_no_error (error
);
249 g_object_unref (saddr
);
251 client
= g_socket_client_new ();
253 g_socket_client_connect_async (client
,
254 G_SOCKET_CONNECTABLE (effective_address
),
255 NULL
, client_connected
, &client_conn
);
256 g_socket_listener_accept_async (listener
, NULL
,
257 server_connected
, &server_conn
);
259 while (!client_conn
|| !server_conn
)
260 g_main_context_iteration (NULL
, TRUE
);
262 in
= G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (client_conn
)));
263 out
= g_io_stream_get_output_stream (G_IO_STREAM (server_conn
));
267 g_object_unref (client_conn
);
268 g_object_unref (server_conn
);
269 g_object_unref (client
);
270 g_object_unref (listener
);
271 g_object_unref (effective_address
);
278 g_test_init (&argc
, &argv
, NULL
);
281 g_test_add_func ("/pollable/unix", test_pollable_unix
);
282 g_test_add_func ("/pollable/converter", test_pollable_converter
);
284 g_test_add_func ("/pollable/socket", test_pollable_socket
);