From fe71a19716bc9e4d632e8af40a1d549c921fe211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 21 Jan 2019 13:49:44 +0200 Subject: [PATCH] Add test for blocking read/write/writev on GSocket*Streams --- gio/tests/socket-service.c | 4 +- gio/tests/socket.c | 152 +++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 2 deletions(-) diff --git a/gio/tests/socket-service.c b/gio/tests/socket-service.c index 14cf24e55..5496b69c0 100644 --- a/gio/tests/socket-service.c +++ b/gio/tests/socket-service.c @@ -269,7 +269,7 @@ written_read_write_async_cb (GOutputStream *ostream, res = g_output_stream_write_all_finish (ostream, result, &bytes_written, &error); g_assert_no_error (error); g_assert_true (res); - g_assert_cmpint (bytes_written, ==, 20); + g_assert_cmpuint (bytes_written, ==, 20); g_io_stream_close_async (G_IO_STREAM (conn), G_PRIORITY_DEFAULT, @@ -339,7 +339,7 @@ writtenv_read_write_async_cb (GOutputStream *ostream, res = g_output_stream_writev_all_finish (ostream, result, &bytes_written, &error); g_assert_no_error (error); g_assert_true (res); - g_assert_cmpint (bytes_written, ==, 20); + g_assert_cmpuint (bytes_written, ==, 20); g_io_stream_close_async (G_IO_STREAM (conn), G_PRIORITY_DEFAULT, diff --git a/gio/tests/socket.c b/gio/tests/socket.c index 9b3adb4e4..8410a3e84 100644 --- a/gio/tests/socket.c +++ b/gio/tests/socket.c @@ -1709,6 +1709,154 @@ test_get_available (gconstpointer user_data) g_object_unref (client); } +typedef struct { + GInputStream *is; + GOutputStream *os; + const guint8 *write_data; + guint8 *read_data; +} TestReadWriteData; + +static gpointer +test_read_write_write_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + + res = g_output_stream_write_all (data->os, data->write_data, 1024, &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_read_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_read; + GError *error = NULL; + gboolean res; + + res = g_input_stream_read_all (data->is, data->read_data, 1024, &bytes_read, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_writev_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + GOutputVector vectors[3]; + + vectors[0].buffer = data->write_data; + vectors[0].size = 256; + vectors[1].buffer = data->write_data + 256; + vectors[1].size = 256; + vectors[2].buffer = data->write_data + 512; + vectors[2].size = 512; + + res = g_output_stream_writev_all (data->os, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, 1024); + + return NULL; +} + +/* test if normal read/write/writev via the GSocket*Streams works on TCP sockets */ +static void +test_read_write (gconstpointer user_data) +{ + gboolean writev = GPOINTER_TO_INT (user_data); + GError *err = NULL; + GSocket *listener, *server, *client; + GInetAddress *addr; + GSocketAddress *saddr; + TestReadWriteData data; + guint8 data_write[1024], data_read[1024]; + GSocketConnection *server_stream, *client_stream; + GThread *write_thread, *read_thread; + guint i; + + listener = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (listener)); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (client)); + + addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, 0); + + g_socket_bind (listener, saddr, TRUE, &err); + g_assert_no_error (err); + g_object_unref (saddr); + g_object_unref (addr); + + saddr = g_socket_get_local_address (listener, &err); + g_assert_no_error (err); + + g_socket_listen (listener, &err); + g_assert_no_error (err); + g_socket_connect (client, saddr, NULL, &err); + g_assert_no_error (err); + + server = g_socket_accept (listener, NULL, &err); + g_assert_no_error (err); + g_socket_set_blocking (server, FALSE); + g_object_unref (listener); + + server_stream = g_socket_connection_factory_create_connection (server); + g_assert_nonnull (server_stream); + client_stream = g_socket_connection_factory_create_connection (client); + g_assert_nonnull (client_stream); + + for (i = 0; i < sizeof (data_write); i++) + data_write[i] = i; + + data.is = g_io_stream_get_input_stream (G_IO_STREAM (server_stream)); + data.os = g_io_stream_get_output_stream (G_IO_STREAM (client_stream)); + data.read_data = data_read; + data.write_data = data_write; + + if (writev) + write_thread = g_thread_new ("writer", test_read_write_writev_thread, &data); + else + write_thread = g_thread_new ("writer", test_read_write_write_thread, &data); + read_thread = g_thread_new ("reader", test_read_write_read_thread, &data); + + g_thread_join (write_thread); + g_thread_join (read_thread); + + g_assert_cmpmem (data_write, sizeof data_write, data_read, sizeof data_read); + + g_socket_close (server, &err); + g_assert_no_error (err); + + g_object_unref (server_stream); + g_object_unref (client_stream); + + g_object_unref (saddr); + g_object_unref (server); + g_object_unref (client); +} + int main (int argc, char *argv[]) @@ -1761,6 +1909,10 @@ main (int argc, test_get_available); g_test_add_data_func ("/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM), test_get_available); + g_test_add_data_func ("/socket/read_write", GUINT_TO_POINTER (FALSE), + test_read_write); + g_test_add_data_func ("/socket/read_writev", GUINT_TO_POINTER (TRUE), + test_read_write); return g_test_run(); }