mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-30 17:36:16 +01:00
cf85241aba
This doesn't trigger the cancellation assertion issue when run locally (the task didn't return yet, so the error is simply overwritten), but perhaps it ever does in CI. Anyhow, it's good to have a cancellation test.
231 lines
6.5 KiB
C
231 lines
6.5 KiB
C
/* GLib testing framework examples and tests
|
|
* Copyright (C) 2010-2012 Collabora Ltd.
|
|
* Authors: Xavier Claessens <xclaesse@gmail.com>
|
|
* Mike Ruprecht <mike.ruprecht@collabora.co.uk>
|
|
*
|
|
* This work is provided "as is"; redistribution and modification
|
|
* in whole or in part, in any medium, physical or electronic is
|
|
* permitted without restriction.
|
|
*
|
|
* This work is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* In no event shall the authors or contributors be liable for any
|
|
* direct, indirect, incidental, special, exemplary, or consequential
|
|
* damages (including, but not limited to, procurement of substitute
|
|
* goods or services; loss of use, data, or profits; or business
|
|
* interruption) however caused and on any theory of liability, whether
|
|
* in contract, strict liability, or tort (including negligence or
|
|
* otherwise) arising in any way out of the use of this software, even
|
|
* if advised of the possibility of such damage.
|
|
*/
|
|
|
|
#include <glib/glib.h>
|
|
#include <glib/gstdio.h>
|
|
#include <gio/gio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef enum
|
|
{
|
|
TEST_THREADED_NONE = 0,
|
|
TEST_THREADED_ISTREAM = 1,
|
|
TEST_THREADED_OSTREAM = 2,
|
|
TEST_CANCEL = 4,
|
|
TEST_THREADED_BOTH = TEST_THREADED_ISTREAM | TEST_THREADED_OSTREAM,
|
|
} TestThreadedFlags;
|
|
|
|
typedef struct
|
|
{
|
|
GMainLoop *main_loop;
|
|
const gchar *data;
|
|
GInputStream *istream;
|
|
GOutputStream *ostream;
|
|
TestThreadedFlags flags;
|
|
gchar *input_path;
|
|
gchar *output_path;
|
|
} TestCopyChunksData;
|
|
|
|
static void
|
|
test_copy_chunks_splice_cb (GObject *source,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
TestCopyChunksData *data = user_data;
|
|
gchar *received_data;
|
|
GError *error = NULL;
|
|
gssize bytes_spliced;
|
|
|
|
bytes_spliced = g_output_stream_splice_finish (G_OUTPUT_STREAM (source),
|
|
res, &error);
|
|
|
|
if (data->flags & TEST_CANCEL)
|
|
{
|
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
|
|
g_main_loop_quit (data->main_loop);
|
|
return;
|
|
}
|
|
|
|
g_assert_no_error (error);
|
|
g_assert_cmpint (bytes_spliced, ==, strlen (data->data));
|
|
|
|
if (data->flags & TEST_THREADED_OSTREAM)
|
|
{
|
|
gsize length = 0;
|
|
|
|
g_file_get_contents (data->output_path, &received_data,
|
|
&length, &error);
|
|
g_assert_no_error (error);
|
|
g_assert_cmpstr (received_data, ==, data->data);
|
|
g_free (received_data);
|
|
}
|
|
else
|
|
{
|
|
received_data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->ostream));
|
|
g_assert_cmpstr (received_data, ==, data->data);
|
|
}
|
|
|
|
g_assert (g_input_stream_is_closed (data->istream));
|
|
g_assert (g_output_stream_is_closed (data->ostream));
|
|
|
|
if (data->flags & TEST_THREADED_ISTREAM)
|
|
{
|
|
g_unlink (data->input_path);
|
|
g_free (data->input_path);
|
|
}
|
|
|
|
if (data->flags & TEST_THREADED_OSTREAM)
|
|
{
|
|
g_unlink (data->output_path);
|
|
g_free (data->output_path);
|
|
}
|
|
|
|
g_main_loop_quit (data->main_loop);
|
|
}
|
|
|
|
static void
|
|
test_copy_chunks_start (TestThreadedFlags flags)
|
|
{
|
|
TestCopyChunksData data;
|
|
GError *error = NULL;
|
|
GCancellable *cancellable = NULL;
|
|
|
|
data.main_loop = g_main_loop_new (NULL, FALSE);
|
|
data.data = "abcdefghijklmnopqrstuvwxyz";
|
|
data.flags = flags;
|
|
|
|
if (data.flags & TEST_CANCEL)
|
|
{
|
|
cancellable = g_cancellable_new ();
|
|
g_cancellable_cancel (cancellable);
|
|
}
|
|
|
|
if (data.flags & TEST_THREADED_ISTREAM)
|
|
{
|
|
GFile *file;
|
|
GFileIOStream *stream;
|
|
|
|
file = g_file_new_tmp ("test-inputXXXXXX", &stream, &error);
|
|
g_assert_no_error (error);
|
|
g_object_unref (stream);
|
|
data.input_path = g_file_get_path (file);
|
|
g_file_set_contents (data.input_path,
|
|
data.data, strlen (data.data),
|
|
&error);
|
|
g_assert_no_error (error);
|
|
data.istream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
|
|
g_assert_no_error (error);
|
|
g_object_unref (file);
|
|
}
|
|
else
|
|
{
|
|
data.istream = g_memory_input_stream_new_from_data (data.data, -1, NULL);
|
|
}
|
|
|
|
if (data.flags & TEST_THREADED_OSTREAM)
|
|
{
|
|
GFile *file;
|
|
GFileIOStream *stream;
|
|
|
|
file = g_file_new_tmp ("test-outputXXXXXX", &stream, &error);
|
|
g_assert_no_error (error);
|
|
g_object_unref (stream);
|
|
data.output_path = g_file_get_path (file);
|
|
data.ostream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE,
|
|
G_FILE_CREATE_NONE,
|
|
NULL, &error));
|
|
g_assert_no_error (error);
|
|
g_object_unref (file);
|
|
}
|
|
else
|
|
{
|
|
data.ostream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
|
|
}
|
|
|
|
g_output_stream_splice_async (data.ostream, data.istream,
|
|
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
|
|
G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
|
G_PRIORITY_DEFAULT, cancellable,
|
|
test_copy_chunks_splice_cb, &data);
|
|
|
|
/* We do not hold a ref in data struct, this is to make sure the operation
|
|
* keeps the iostream objects alive until it finishes
|
|
*/
|
|
g_object_unref (data.istream);
|
|
g_object_unref (data.ostream);
|
|
g_clear_object (&cancellable);
|
|
|
|
g_main_loop_run (data.main_loop);
|
|
g_main_loop_unref (data.main_loop);
|
|
}
|
|
|
|
static void
|
|
test_copy_chunks (void)
|
|
{
|
|
test_copy_chunks_start (TEST_THREADED_NONE);
|
|
}
|
|
|
|
static void
|
|
test_copy_chunks_threaded_input (void)
|
|
{
|
|
test_copy_chunks_start (TEST_THREADED_ISTREAM);
|
|
}
|
|
|
|
static void
|
|
test_copy_chunks_threaded_output (void)
|
|
{
|
|
test_copy_chunks_start (TEST_THREADED_OSTREAM);
|
|
}
|
|
|
|
static void
|
|
test_copy_chunks_threaded (void)
|
|
{
|
|
test_copy_chunks_start (TEST_THREADED_BOTH);
|
|
}
|
|
|
|
static void
|
|
test_cancelled (void)
|
|
{
|
|
test_copy_chunks_start (TEST_THREADED_NONE | TEST_CANCEL);
|
|
}
|
|
|
|
int
|
|
main (int argc,
|
|
char *argv[])
|
|
{
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
g_test_add_func ("/async-splice/copy-chunks", test_copy_chunks);
|
|
g_test_add_func ("/async-splice/copy-chunks-threaded-input",
|
|
test_copy_chunks_threaded_input);
|
|
g_test_add_func ("/async-splice/copy-chunks-threaded-output",
|
|
test_copy_chunks_threaded_output);
|
|
g_test_add_func ("/async-splice/copy-chunks-threaded",
|
|
test_copy_chunks_threaded);
|
|
g_test_add_func ("/async-splice/cancelled",
|
|
test_cancelled);
|
|
|
|
return g_test_run();
|
|
}
|