Add test for blocking read/write/writev on GSocket*Streams

This commit is contained in:
Sebastian Dröge 2019-01-21 13:49:44 +02:00
parent 61520ae601
commit fe71a19716
2 changed files with 154 additions and 2 deletions

View File

@ -269,7 +269,7 @@ written_read_write_async_cb (GOutputStream *ostream,
res = g_output_stream_write_all_finish (ostream, result, &bytes_written, &error); res = g_output_stream_write_all_finish (ostream, result, &bytes_written, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_assert_true (res); 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_io_stream_close_async (G_IO_STREAM (conn),
G_PRIORITY_DEFAULT, 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); res = g_output_stream_writev_all_finish (ostream, result, &bytes_written, &error);
g_assert_no_error (error); g_assert_no_error (error);
g_assert_true (res); 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_io_stream_close_async (G_IO_STREAM (conn),
G_PRIORITY_DEFAULT, G_PRIORITY_DEFAULT,

View File

@ -1709,6 +1709,154 @@ test_get_available (gconstpointer user_data)
g_object_unref (client); 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 int
main (int argc, main (int argc,
char *argv[]) char *argv[])
@ -1761,6 +1909,10 @@ main (int argc,
test_get_available); test_get_available);
g_test_add_data_func ("/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM), g_test_add_data_func ("/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM),
test_get_available); 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(); return g_test_run();
} }