mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
gio/tests/socket: add some basic IPv4 and IPv6 tests
This commit is contained in:
parent
aefda965f6
commit
eac8d47e37
@ -1,6 +1,6 @@
|
||||
/* GLib testing framework examples and tests
|
||||
*
|
||||
* Copyright (C) 2008-2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008-2011 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -16,8 +16,6 @@
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: David Zeuthen <davidz@redhat.com>
|
||||
*/
|
||||
|
||||
#include <gio/gio.h>
|
||||
@ -32,6 +30,379 @@
|
||||
#include <gio/gunixconnection.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
GSocket *server;
|
||||
GSocket *client;
|
||||
GSocketFamily family;
|
||||
GThread *thread;
|
||||
GMainLoop *loop;
|
||||
} IPTestData;
|
||||
|
||||
static gpointer
|
||||
echo_server_thread (gpointer user_data)
|
||||
{
|
||||
IPTestData *data = user_data;
|
||||
GSocket *sock;
|
||||
GError *error = NULL;
|
||||
gssize nread, nwrote;
|
||||
gchar buf[128];
|
||||
|
||||
sock = g_socket_accept (data->server, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (nread, >=, 0);
|
||||
|
||||
if (nread == 0)
|
||||
break;
|
||||
|
||||
nwrote = g_socket_send (sock, buf, nread, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (nwrote, ==, nread);
|
||||
}
|
||||
|
||||
g_socket_close (sock, &error);
|
||||
g_assert_no_error (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static IPTestData *
|
||||
create_server (GSocketFamily family)
|
||||
{
|
||||
IPTestData *data;
|
||||
GSocket *server;
|
||||
GError *error = NULL;
|
||||
GSocketAddress *addr;
|
||||
GInetAddress *iaddr;
|
||||
|
||||
data = g_slice_new (IPTestData);
|
||||
data->family = family;
|
||||
|
||||
data->server = server = g_socket_new (family,
|
||||
G_SOCKET_TYPE_STREAM,
|
||||
G_SOCKET_PROTOCOL_DEFAULT,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_cmpint (g_socket_get_family (server), ==, family);
|
||||
g_assert_cmpint (g_socket_get_socket_type (server), ==, G_SOCKET_TYPE_STREAM);
|
||||
g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT);
|
||||
|
||||
g_socket_set_blocking (server, TRUE);
|
||||
|
||||
iaddr = g_inet_address_new_loopback (family);
|
||||
addr = g_inet_socket_address_new (iaddr, 0);
|
||||
g_object_unref (iaddr);
|
||||
|
||||
g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), ==, 0);
|
||||
g_socket_bind (server, addr, TRUE, &error);
|
||||
g_assert_no_error (error);
|
||||
g_object_unref (addr);
|
||||
|
||||
addr = g_socket_get_local_address (server, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), !=, 0);
|
||||
|
||||
g_socket_listen (server, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
data->thread = g_thread_create (echo_server_thread, data, TRUE, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static const gchar *testbuf = "0123456789abcdef";
|
||||
|
||||
static gboolean
|
||||
test_ip_async_read_ready (GSocket *client,
|
||||
GIOCondition cond,
|
||||
gpointer user_data)
|
||||
{
|
||||
IPTestData *data = user_data;
|
||||
GError *error = NULL;
|
||||
gssize len;
|
||||
gchar buf[128];
|
||||
|
||||
g_assert_cmpint (cond, ==, G_IO_IN);
|
||||
|
||||
len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (len, ==, strlen (testbuf) + 1);
|
||||
|
||||
g_assert_cmpstr (testbuf, ==, buf);
|
||||
|
||||
g_main_loop_quit (data->loop);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_ip_async_write_ready (GSocket *client,
|
||||
GIOCondition cond,
|
||||
gpointer user_data)
|
||||
{
|
||||
IPTestData *data = user_data;
|
||||
GError *error = NULL;
|
||||
GSource *source;
|
||||
gssize len;
|
||||
|
||||
g_assert_cmpint (cond, ==, G_IO_OUT);
|
||||
|
||||
len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (len, ==, strlen (testbuf) + 1);
|
||||
|
||||
source = g_socket_create_source (client, G_IO_IN, NULL);
|
||||
g_source_set_callback (source, (GSourceFunc)test_ip_async_read_ready,
|
||||
data, NULL);
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_ip_async_timed_out (GSocket *client,
|
||||
GIOCondition cond,
|
||||
gpointer user_data)
|
||||
{
|
||||
IPTestData *data = user_data;
|
||||
GError *error = NULL;
|
||||
GSource *source;
|
||||
gssize len;
|
||||
gchar buf[128];
|
||||
|
||||
if (data->family == G_SOCKET_FAMILY_IPV4)
|
||||
{
|
||||
g_assert_cmpint (cond, ==, 0);
|
||||
len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_cmpint (len, ==, -1);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
source = g_socket_create_source (client, G_IO_OUT, NULL);
|
||||
g_source_set_callback (source, (GSourceFunc)test_ip_async_write_ready,
|
||||
data, NULL);
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_ip_async_connected (GSocket *client,
|
||||
GIOCondition cond,
|
||||
gpointer user_data)
|
||||
{
|
||||
IPTestData *data = user_data;
|
||||
GError *error = NULL;
|
||||
GSource *source;
|
||||
gssize len;
|
||||
gchar buf[128];
|
||||
|
||||
g_socket_check_connect_result (client, &error);
|
||||
g_assert_no_error (error);
|
||||
/* We do this after the check_connect_result, since that will give a
|
||||
* more useful assertion in case of error.
|
||||
*/
|
||||
g_assert_cmpint (cond, ==, G_IO_OUT);
|
||||
|
||||
g_assert (g_socket_is_connected (client));
|
||||
|
||||
/* This adds 1 second to "make check", so let's just only do it once. */
|
||||
if (data->family == G_SOCKET_FAMILY_IPV4)
|
||||
{
|
||||
len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_cmpint (len, ==, -1);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
|
||||
g_clear_error (&error);
|
||||
|
||||
source = g_socket_create_source (client, G_IO_IN, NULL);
|
||||
g_source_set_callback (source, (GSourceFunc)test_ip_async_timed_out,
|
||||
data, NULL);
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
}
|
||||
else
|
||||
test_ip_async_timed_out (client, 0, data);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
idle_test_ip_async_connected (gpointer user_data)
|
||||
{
|
||||
IPTestData *data = user_data;
|
||||
|
||||
return test_ip_async_connected (data->client, G_IO_OUT, data);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ip_async (GSocketFamily family)
|
||||
{
|
||||
IPTestData *data;
|
||||
GError *error = NULL;
|
||||
GSocket *client;
|
||||
GSocketAddress *addr;
|
||||
GSource *source;
|
||||
gssize len;
|
||||
gchar buf[128];
|
||||
|
||||
data = create_server (family);
|
||||
addr = g_socket_get_local_address (data->server, &error);
|
||||
|
||||
client = g_socket_new (family,
|
||||
G_SOCKET_TYPE_STREAM,
|
||||
G_SOCKET_PROTOCOL_DEFAULT,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
data->client = client;
|
||||
|
||||
g_assert_cmpint (g_socket_get_family (client), ==, family);
|
||||
g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
|
||||
g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
|
||||
|
||||
g_socket_set_blocking (client, FALSE);
|
||||
g_socket_set_timeout (client, 1);
|
||||
|
||||
if (g_socket_connect (client, addr, NULL, &error))
|
||||
{
|
||||
g_assert_no_error (error);
|
||||
g_idle_add (idle_test_ip_async_connected, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
|
||||
g_clear_error (&error);
|
||||
source = g_socket_create_source (client, G_IO_OUT, NULL);
|
||||
g_source_set_callback (source, (GSourceFunc)test_ip_async_connected,
|
||||
data, NULL);
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
}
|
||||
|
||||
data->loop = g_main_loop_new (NULL, TRUE);
|
||||
g_main_loop_run (data->loop);
|
||||
g_main_loop_unref (data->loop);
|
||||
|
||||
g_socket_shutdown (client, FALSE, TRUE, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_thread_join (data->thread);
|
||||
|
||||
len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (len, ==, 0);
|
||||
|
||||
g_socket_close (client, &error);
|
||||
g_assert_no_error (error);
|
||||
g_socket_close (data->server, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_object_unref (data->server);
|
||||
g_object_unref (client);
|
||||
|
||||
g_slice_free (IPTestData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ipv4_async (void)
|
||||
{
|
||||
test_ip_async (G_SOCKET_FAMILY_IPV4);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ipv6_async (void)
|
||||
{
|
||||
test_ip_async (G_SOCKET_FAMILY_IPV6);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ip_sync (GSocketFamily family)
|
||||
{
|
||||
IPTestData *data;
|
||||
GError *error = NULL;
|
||||
GSocket *client;
|
||||
GSocketAddress *addr;
|
||||
gssize len;
|
||||
gchar buf[128];
|
||||
|
||||
data = create_server (family);
|
||||
addr = g_socket_get_local_address (data->server, &error);
|
||||
|
||||
client = g_socket_new (family,
|
||||
G_SOCKET_TYPE_STREAM,
|
||||
G_SOCKET_PROTOCOL_DEFAULT,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert_cmpint (g_socket_get_family (client), ==, family);
|
||||
g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
|
||||
g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
|
||||
|
||||
g_socket_set_blocking (client, TRUE);
|
||||
g_socket_set_timeout (client, 1);
|
||||
|
||||
g_socket_connect (client, addr, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (g_socket_is_connected (client));
|
||||
|
||||
/* This adds 1 second to "make check", so let's just only do it once. */
|
||||
if (family == G_SOCKET_FAMILY_IPV4)
|
||||
{
|
||||
len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_cmpint (len, ==, -1);
|
||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (len, ==, strlen (testbuf) + 1);
|
||||
|
||||
len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (len, ==, strlen (testbuf) + 1);
|
||||
|
||||
g_assert_cmpstr (testbuf, ==, buf);
|
||||
|
||||
g_socket_shutdown (client, FALSE, TRUE, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_thread_join (data->thread);
|
||||
|
||||
len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpint (len, ==, 0);
|
||||
|
||||
g_socket_close (client, &error);
|
||||
g_assert_no_error (error);
|
||||
g_socket_close (data->server, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_object_unref (data->server);
|
||||
g_object_unref (client);
|
||||
|
||||
g_slice_free (IPTestData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ipv4_sync (void)
|
||||
{
|
||||
test_ip_sync (G_SOCKET_FAMILY_IPV4);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ipv6_sync (void)
|
||||
{
|
||||
test_ip_sync (G_SOCKET_FAMILY_IPV6);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
static void
|
||||
test_unix_from_fd (void)
|
||||
@ -180,6 +551,10 @@ main (int argc,
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/socket/ipv4_sync", test_ipv4_sync);
|
||||
g_test_add_func ("/socket/ipv4_async", test_ipv4_async);
|
||||
g_test_add_func ("/socket/ipv6_sync", test_ipv6_sync);
|
||||
g_test_add_func ("/socket/ipv6_sync", test_ipv6_async);
|
||||
#ifdef G_OS_UNIX
|
||||
g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
|
||||
g_test_add_func ("/socket/unix-connection", test_unix_connection);
|
||||
|
Loading…
Reference in New Issue
Block a user