summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2018-09-14 12:54:00 +0300
committerSebastian Dröge <sebastian@centricular.com>2019-01-24 16:25:56 +0200
commit708aa8f4eee119a6dd542904ab962030a9337993 (patch)
tree1c7fb9dfc39482bfa286141c0c823116c0dc9361
parente6f5a50cd77c27bb77a524c6c1239ecc88f8fda7 (diff)
downloadglib-708aa8f4eee119a6dd542904ab962030a9337993.tar.gz
Add some tests for g_output_stream_writev() and its async variant
-rw-r--r--gio/tests/file.c567
-rw-r--r--gio/tests/memory-output-stream.c90
2 files changed, 657 insertions, 0 deletions
diff --git a/gio/tests/file.c b/gio/tests/file.c
index d2f147419..affa0bce6 100644
--- a/gio/tests/file.c
+++ b/gio/tests/file.c
@@ -1162,6 +1162,562 @@ test_load_bytes_async (void)
g_main_loop_unref (data.main_loop);
}
+static void
+test_writev_helper (GOutputVector *vectors,
+ gsize n_vectors,
+ gboolean use_bytes_written,
+ const guint8 *expected_contents,
+ gsize expected_length)
+{
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputStream *ostream;
+ GError *error = NULL;
+ gsize bytes_written = 0;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ res = g_output_stream_writev_all (ostream, vectors, n_vectors, use_bytes_written ? &bytes_written : NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ if (use_bytes_written)
+ g_assert_cmpuint (bytes_written, ==, expected_length);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+
+ g_assert_cmpmem (contents, length, expected_contents, expected_length);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+/* Test that writev() on local file output streams works on a non-empty vector */
+static void
+test_writev (void)
+{
+ GOutputVector vectors[3];
+ const guint8 buffer[] = {1, 2, 3, 4, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 1, 2, 3};
+
+ vectors[0].buffer = buffer;
+ vectors[0].size = 5;
+
+ vectors[1].buffer = buffer + 5;
+ vectors[1].size = 12;
+
+ vectors[2].buffer = buffer + 5 + 12;
+ vectors[2].size = 3;
+
+ test_writev_helper (vectors, G_N_ELEMENTS (vectors), TRUE, buffer, sizeof buffer);
+}
+
+/* Test that writev() on local file output streams works on a non-empty vector without returning bytes_written */
+static void
+test_writev_no_bytes_written (void)
+{
+ GOutputVector vectors[3];
+ const guint8 buffer[] = {1, 2, 3, 4, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 1, 2, 3};
+
+ vectors[0].buffer = buffer;
+ vectors[0].size = 5;
+
+ vectors[1].buffer = buffer + 5;
+ vectors[1].size = 12;
+
+ vectors[2].buffer = buffer + 5 + 12;
+ vectors[2].size = 3;
+
+ test_writev_helper (vectors, G_N_ELEMENTS (vectors), FALSE, buffer, sizeof buffer);
+}
+
+/* Test that writev() on local file output streams works on 0 vectors */
+static void
+test_writev_no_vectors (void)
+{
+ test_writev_helper (NULL, 0, TRUE, NULL, 0);
+}
+
+/* Test that writev() on local file output streams works on empty vectors */
+static void
+test_writev_empty_vectors (void)
+{
+ GOutputVector vectors[3];
+
+ vectors[0].buffer = NULL;
+ vectors[0].size = 0;
+ vectors[1].buffer = NULL;
+ vectors[1].size = 0;
+ vectors[2].buffer = NULL;
+ vectors[2].size = 0;
+
+ test_writev_helper (vectors, G_N_ELEMENTS (vectors), TRUE, NULL, 0);
+}
+
+/* Test that writev() fails if the sum of sizes in the vector is too big */
+static void
+test_writev_too_big_vectors (void)
+{
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputStream *ostream;
+ GError *error = NULL;
+ gsize bytes_written = 0;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+ GOutputVector vectors[3];
+
+ vectors[0].buffer = (void*) 1;
+ vectors[0].size = G_MAXSIZE / 2;
+
+ vectors[1].buffer = (void*) 1;
+ vectors[1].size = G_MAXSIZE / 2;
+
+ vectors[2].buffer = (void*) 1;
+ vectors[2].size = G_MAXSIZE / 2;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ res = g_output_stream_writev_all (ostream, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
+ g_assert_cmpuint (bytes_written, ==, 0);
+ g_assert_false (res);
+ g_clear_error (&error);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+
+ g_assert_cmpmem (contents, length, NULL, 0);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+typedef struct
+{
+ gsize bytes_written;
+ GOutputVector *vectors;
+ gsize n_vectors;
+ GError *error;
+ gboolean done;
+} WritevAsyncData;
+
+static void
+test_writev_async_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GOutputStream *ostream = G_OUTPUT_STREAM (object);
+ WritevAsyncData *data = user_data;
+ GError *error = NULL;
+ gsize bytes_written;
+ gboolean res;
+
+ res = g_output_stream_writev_finish (ostream, result, &bytes_written, &error);
+ g_assert_true (res);
+ g_assert_no_error (error);
+ data->bytes_written += bytes_written;
+
+ /* skip vectors that have been written in full */
+ while (data->n_vectors > 0 && bytes_written >= data->vectors[0].size)
+ {
+ bytes_written -= data->vectors[0].size;
+ ++data->vectors;
+ --data->n_vectors;
+ }
+ /* skip partially written vector data */
+ if (bytes_written > 0 && data->n_vectors > 0)
+ {
+ data->vectors[0].size -= bytes_written;
+ data->vectors[0].buffer = ((guint8 *) data->vectors[0].buffer) + bytes_written;
+ }
+
+ if (data->n_vectors > 0)
+ g_output_stream_writev_async (ostream, data->vectors, data->n_vectors, 0, NULL, test_writev_async_cb, &data);
+}
+
+/* Test that writev_async() on local file output streams works on a non-empty vector */
+static void
+test_writev_async (void)
+{
+ WritevAsyncData data = { 0 };
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputVector vectors[3];
+ const guint8 buffer[] = {1, 2, 3, 4, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 1, 2, 3};
+ GOutputStream *ostream;
+ GError *error = NULL;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+
+ vectors[0].buffer = buffer;
+ vectors[0].size = 5;
+
+ vectors[1].buffer = buffer + 5;
+ vectors[1].size = 12;
+
+ vectors[2].buffer = buffer + 5 + 12;
+ vectors[2].size = 3;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ data.vectors = vectors;
+ data.n_vectors = G_N_ELEMENTS (vectors);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ g_output_stream_writev_async (ostream, data.vectors, data.n_vectors, 0, NULL, test_writev_async_cb, &data);
+
+ while (data.n_vectors > 0)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpuint (data.bytes_written, ==, sizeof buffer);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+
+ g_assert_cmpmem (contents, length, buffer, sizeof buffer);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+static void
+test_writev_all_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GOutputStream *ostream = G_OUTPUT_STREAM (object);
+ WritevAsyncData *data = user_data;
+
+ g_output_stream_writev_all_finish (ostream, result, &data->bytes_written, &data->error);
+ data->done = TRUE;
+}
+
+/* Test that writev_async_all() on local file output streams works on a non-empty vector */
+static void
+test_writev_async_all (void)
+{
+ WritevAsyncData data = { 0 };
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputStream *ostream;
+ GOutputVector vectors[3];
+ const guint8 buffer[] = {1, 2, 3, 4, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 1, 2, 3};
+ GError *error = NULL;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+
+ vectors[0].buffer = buffer;
+ vectors[0].size = 5;
+
+ vectors[1].buffer = buffer + 5;
+ vectors[1].size = 12;
+
+ vectors[2].buffer = buffer + 5 + 12;
+ vectors[2].size = 3;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, NULL, test_writev_all_cb, &data);
+
+ while (!data.done)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpuint (data.bytes_written, ==, sizeof buffer);
+ g_assert_no_error (data.error);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+
+ g_assert_cmpmem (contents, length, buffer, sizeof buffer);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+/* Test that writev_async_all() on local file output streams handles cancellation correctly */
+static void
+test_writev_async_all_cancellation (void)
+{
+ WritevAsyncData data = { 0 };
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputVector vectors[3];
+ const guint8 buffer[] = {1, 2, 3, 4, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 1, 2, 3};
+ GOutputStream *ostream;
+ GError *error = NULL;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+ GCancellable *cancellable;
+
+ vectors[0].buffer = buffer;
+ vectors[0].size = 5;
+
+ vectors[1].buffer = buffer + 5;
+ vectors[1].size = 12;
+
+ vectors[2].buffer = buffer + 5 + 12;
+ vectors[2].size = 3;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ cancellable = g_cancellable_new ();
+
+ g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, cancellable, test_writev_all_cb, &data);
+
+ g_cancellable_cancel (cancellable);
+
+ while (!data.done)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpuint (data.bytes_written, ==, 0);
+ g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
+ g_clear_error (&data.error);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_assert_cmpuint (length, ==, 0);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+ g_object_unref (cancellable);
+}
+
+/* Test that writev_async_all() with empty vectors is handled correctly */
+static void
+test_writev_async_all_empty_vectors (void)
+{
+ WritevAsyncData data = { 0 };
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputVector vectors[3];
+ GOutputStream *ostream;
+ GError *error = NULL;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+
+ vectors[0].buffer = NULL;
+ vectors[0].size = 0;
+
+ vectors[1].buffer = NULL;
+ vectors[1].size = 0;
+
+ vectors[2].buffer = NULL;
+ vectors[2].size = 0;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, NULL, test_writev_all_cb, &data);
+
+ while (!data.done)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpuint (data.bytes_written, ==, 0);
+ g_assert_no_error (data.error);
+ g_clear_error (&data.error);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_assert_cmpuint (length, ==, 0);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+/* Test that writev_async_all() with no vectors is handled correctly */
+static void
+test_writev_async_all_no_vectors (void)
+{
+ WritevAsyncData data = { 0 };
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputStream *ostream;
+ GError *error = NULL;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ g_output_stream_writev_all_async (ostream, NULL, 0, 0, NULL, test_writev_all_cb, &data);
+
+ while (!data.done)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpuint (data.bytes_written, ==, 0);
+ g_assert_no_error (data.error);
+ g_clear_error (&data.error);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_assert_cmpuint (length, ==, 0);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+/* Test that writev_async_all() with too big vectors is handled correctly */
+static void
+test_writev_async_all_too_big_vectors (void)
+{
+ WritevAsyncData data = { 0 };
+ GFile *file;
+ GFileIOStream *iostream = NULL;
+ GOutputVector vectors[3];
+ GOutputStream *ostream;
+ GError *error = NULL;
+ gboolean res;
+ guint8 *contents;
+ gsize length;
+
+ vectors[0].buffer = (void*) 1;
+ vectors[0].size = G_MAXSIZE / 2;
+
+ vectors[1].buffer = (void*) 1;
+ vectors[1].size = G_MAXSIZE / 2;
+
+ vectors[2].buffer = (void*) 1;
+ vectors[2].size = G_MAXSIZE / 2;
+
+ file = g_file_new_tmp ("g_file_writev_XXXXXX",
+ &iostream, NULL);
+ g_assert_nonnull (file);
+ g_assert_nonnull (iostream);
+
+ ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
+ g_output_stream_writev_all_async (ostream, vectors, G_N_ELEMENTS (vectors), 0, NULL, test_writev_all_cb, &data);
+
+ while (!data.done)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpuint (data.bytes_written, ==, 0);
+ g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
+ g_clear_error (&data.error);
+
+ res = g_io_stream_close (G_IO_STREAM (iostream), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_object_unref (iostream);
+
+ res = g_file_load_contents (file, NULL, (gchar **) &contents, &length, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_assert_cmpuint (length, ==, 0);
+
+ g_free (contents);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
int
main (int argc, char *argv[])
{
@@ -1190,6 +1746,17 @@ main (int argc, char *argv[])
g_test_add_func ("/file/measure-async", test_measure_async);
g_test_add_func ("/file/load-bytes", test_load_bytes);
g_test_add_func ("/file/load-bytes-async", test_load_bytes_async);
+ g_test_add_func ("/file/writev", test_writev);
+ g_test_add_func ("/file/writev/no-bytes-written", test_writev_no_bytes_written);
+ g_test_add_func ("/file/writev/no-vectors", test_writev_no_vectors);
+ g_test_add_func ("/file/writev/empty-vectors", test_writev_empty_vectors);
+ g_test_add_func ("/file/writev/too-big-vectors", test_writev_too_big_vectors);
+ g_test_add_func ("/file/writev/async", test_writev_async);
+ g_test_add_func ("/file/writev/async_all", test_writev_async_all);
+ g_test_add_func ("/file/writev/async_all-empty-vectors", test_writev_async_all_empty_vectors);
+ g_test_add_func ("/file/writev/async_all-no-vectors", test_writev_async_all_no_vectors);
+ g_test_add_func ("/file/writev/async_all-to-big-vectors", test_writev_async_all_too_big_vectors);
+ g_test_add_func ("/file/writev/async_all-cancellation", test_writev_async_all_cancellation);
return g_test_run ();
}
diff --git a/gio/tests/memory-output-stream.c b/gio/tests/memory-output-stream.c
index 4c85993e4..72da6263d 100644
--- a/gio/tests/memory-output-stream.c
+++ b/gio/tests/memory-output-stream.c
@@ -300,6 +300,94 @@ test_write_bytes (void)
g_bytes_unref (bytes2);
}
+/* Test that writev() works on #GMemoryOutputStream with a non-empty set of vectors. This
+ * covers the default writev() implementation around write(). */
+static void
+test_writev (void)
+{
+ GOutputStream *mo;
+ GError *error = NULL;
+ gboolean res;
+ gsize bytes_written;
+ GOutputVector vectors[3];
+ const guint8 buffer[] = {1, 2, 3, 4, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 1, 2, 3};
+ guint8 *output_buffer;
+
+ vectors[0].buffer = buffer;
+ vectors[0].size = 5;
+
+ vectors[1].buffer = buffer + vectors[0].size;
+ vectors[1].size = 12;
+
+ vectors[2].buffer = buffer + vectors[0].size + vectors[1].size;
+ vectors[2].size = 3;
+
+ mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
+ "realloc-function", g_realloc,
+ "destroy-function", g_free,
+ NULL);
+ res = g_output_stream_writev_all (mo, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_true (res);
+ g_assert_cmpuint (bytes_written, ==, sizeof buffer);
+
+ g_output_stream_close (mo, NULL, &error);
+ g_assert_no_error (error);
+
+ g_assert_cmpuint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, sizeof buffer);
+ output_buffer = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
+ g_assert_cmpmem (output_buffer, sizeof buffer, buffer, sizeof buffer);
+
+ g_object_unref (mo);
+}
+
+/* Test that writev_nonblocking() works on #GMemoryOutputStream with a non-empty set of vectors. This
+ * covers the default writev_nonblocking() implementation around write_nonblocking(). */
+static void
+test_writev_nonblocking (void)
+{
+ GOutputStream *mo;
+ GError *error = NULL;
+ gboolean res;
+ gsize bytes_written;
+ GOutputVector vectors[3];
+ const guint8 buffer[] = {1, 2, 3, 4, 5,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 1, 2, 3};
+ guint8 *output_buffer;
+
+ vectors[0].buffer = buffer;
+ vectors[0].size = 5;
+
+ vectors[1].buffer = buffer + vectors[0].size;
+ vectors[1].size = 12;
+
+ vectors[2].buffer = buffer + vectors[0].size + vectors[1].size;
+ vectors[2].size = 3;
+
+ mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
+ "realloc-function", g_realloc,
+ "destroy-function", g_free,
+ NULL);
+ res = g_pollable_output_stream_writev_nonblocking (G_POLLABLE_OUTPUT_STREAM (mo),
+ vectors, G_N_ELEMENTS (vectors),
+ &bytes_written, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (res, ==, G_POLLABLE_RETURN_OK);
+ g_assert_cmpuint (bytes_written, ==, sizeof buffer);
+
+ g_output_stream_close (mo, NULL, &error);
+ g_assert_no_error (error);
+
+ g_assert_cmpuint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, sizeof buffer);
+ output_buffer = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
+ g_assert_cmpmem (output_buffer, sizeof buffer, buffer, sizeof buffer);
+
+ g_object_unref (mo);
+}
+
static void
test_steal_as_bytes (void)
{
@@ -350,6 +438,8 @@ main (int argc,
g_test_add_func ("/memory-output-stream/get-data-size", test_data_size);
g_test_add_func ("/memory-output-stream/properties", test_properties);
g_test_add_func ("/memory-output-stream/write-bytes", test_write_bytes);
+ g_test_add_func ("/memory-output-stream/writev", test_writev);
+ g_test_add_func ("/memory-output-stream/writev_nonblocking", test_writev_nonblocking);
g_test_add_func ("/memory-output-stream/steal_as_bytes", test_steal_as_bytes);
return g_test_run();