gio/tests/socket: add some basic IPv4 and IPv6 tests

This commit is contained in:
Dan Winship 2011-07-24 14:55:05 -04:00
parent aefda965f6
commit eac8d47e37

View File

@ -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);