Branch data Line data Source code
1 : : /* GLib testing framework examples and tests
2 : : * Copyright (C) 2010-2012 Collabora Ltd.
3 : : * Authors: Xavier Claessens <xclaesse@gmail.com>
4 : : * Mike Ruprecht <mike.ruprecht@collabora.co.uk>
5 : : *
6 : : * SPDX-License-Identifier: LicenseRef-old-glib-tests
7 : : *
8 : : * This work is provided "as is"; redistribution and modification
9 : : * in whole or in part, in any medium, physical or electronic is
10 : : * permitted without restriction.
11 : : *
12 : : * This work is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 : : *
16 : : * In no event shall the authors or contributors be liable for any
17 : : * direct, indirect, incidental, special, exemplary, or consequential
18 : : * damages (including, but not limited to, procurement of substitute
19 : : * goods or services; loss of use, data, or profits; or business
20 : : * interruption) however caused and on any theory of liability, whether
21 : : * in contract, strict liability, or tort (including negligence or
22 : : * otherwise) arising in any way out of the use of this software, even
23 : : * if advised of the possibility of such damage.
24 : : */
25 : :
26 : : #include <glib/glib.h>
27 : : #include <glib/gstdio.h>
28 : : #include <gio/gio.h>
29 : : #include <stdlib.h>
30 : : #include <string.h>
31 : :
32 : : typedef enum
33 : : {
34 : : TEST_THREADED_NONE = 0,
35 : : TEST_THREADED_ISTREAM = 1,
36 : : TEST_THREADED_OSTREAM = 2,
37 : : TEST_CANCEL = 4,
38 : : TEST_THREADED_BOTH = TEST_THREADED_ISTREAM | TEST_THREADED_OSTREAM,
39 : : } TestThreadedFlags;
40 : :
41 : : typedef struct
42 : : {
43 : : GMainLoop *main_loop;
44 : : const gchar *data;
45 : : GInputStream *istream;
46 : : GOutputStream *ostream;
47 : : TestThreadedFlags flags;
48 : : gchar *input_path;
49 : : gchar *output_path;
50 : : } TestCopyChunksData;
51 : :
52 : : static void
53 : 5 : test_copy_chunks_splice_cb (GObject *source,
54 : : GAsyncResult *res,
55 : : gpointer user_data)
56 : : {
57 : 5 : TestCopyChunksData *data = user_data;
58 : : gchar *received_data;
59 : 5 : GError *error = NULL;
60 : : gssize bytes_spliced;
61 : :
62 : 5 : bytes_spliced = g_output_stream_splice_finish (G_OUTPUT_STREAM (source),
63 : : res, &error);
64 : :
65 : 5 : if (data->flags & TEST_CANCEL)
66 : : {
67 : 1 : g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
68 : 1 : g_error_free (error);
69 : 1 : g_main_loop_quit (data->main_loop);
70 : 1 : return;
71 : : }
72 : :
73 : 4 : g_assert_no_error (error);
74 : 4 : g_assert_cmpint (bytes_spliced, ==, strlen (data->data));
75 : :
76 : 4 : if (data->flags & TEST_THREADED_OSTREAM)
77 : : {
78 : 2 : gsize length = 0;
79 : :
80 : 2 : g_file_get_contents (data->output_path, &received_data,
81 : : &length, &error);
82 : 2 : g_assert_no_error (error);
83 : 2 : g_assert_cmpstr (received_data, ==, data->data);
84 : 2 : g_free (received_data);
85 : : }
86 : : else
87 : : {
88 : 2 : received_data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->ostream));
89 : 2 : g_assert_cmpstr (received_data, ==, data->data);
90 : : }
91 : :
92 : 4 : g_assert (g_input_stream_is_closed (data->istream));
93 : 4 : g_assert (g_output_stream_is_closed (data->ostream));
94 : :
95 : 4 : if (data->flags & TEST_THREADED_ISTREAM)
96 : : {
97 : 2 : g_unlink (data->input_path);
98 : 2 : g_free (data->input_path);
99 : : }
100 : :
101 : 4 : if (data->flags & TEST_THREADED_OSTREAM)
102 : : {
103 : 2 : g_unlink (data->output_path);
104 : 2 : g_free (data->output_path);
105 : : }
106 : :
107 : 4 : g_main_loop_quit (data->main_loop);
108 : : }
109 : :
110 : : static void
111 : 5 : test_copy_chunks_start (TestThreadedFlags flags)
112 : : {
113 : : TestCopyChunksData data;
114 : 5 : GError *error = NULL;
115 : 5 : GCancellable *cancellable = NULL;
116 : :
117 : 5 : data.main_loop = g_main_loop_new (NULL, FALSE);
118 : 5 : data.data = "abcdefghijklmnopqrstuvwxyz";
119 : 5 : data.flags = flags;
120 : :
121 : 5 : if (data.flags & TEST_CANCEL)
122 : : {
123 : 1 : cancellable = g_cancellable_new ();
124 : 1 : g_cancellable_cancel (cancellable);
125 : : }
126 : :
127 : 5 : if (data.flags & TEST_THREADED_ISTREAM)
128 : : {
129 : : GFile *file;
130 : : GFileIOStream *stream;
131 : :
132 : 2 : file = g_file_new_tmp ("test-inputXXXXXX", &stream, &error);
133 : 2 : g_assert_no_error (error);
134 : 2 : g_object_unref (stream);
135 : 2 : data.input_path = g_file_get_path (file);
136 : 2 : g_file_set_contents (data.input_path,
137 : 2 : data.data, strlen (data.data),
138 : : &error);
139 : 2 : g_assert_no_error (error);
140 : 2 : data.istream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
141 : 2 : g_assert_no_error (error);
142 : 2 : g_object_unref (file);
143 : : }
144 : : else
145 : : {
146 : 3 : data.istream = g_memory_input_stream_new_from_data (data.data, -1, NULL);
147 : : }
148 : :
149 : 5 : if (data.flags & TEST_THREADED_OSTREAM)
150 : : {
151 : : GFile *file;
152 : : GFileIOStream *stream;
153 : :
154 : 2 : file = g_file_new_tmp ("test-outputXXXXXX", &stream, &error);
155 : 2 : g_assert_no_error (error);
156 : 2 : g_object_unref (stream);
157 : 2 : data.output_path = g_file_get_path (file);
158 : 2 : data.ostream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE,
159 : : G_FILE_CREATE_NONE,
160 : : NULL, &error));
161 : 2 : g_assert_no_error (error);
162 : 2 : g_object_unref (file);
163 : : }
164 : : else
165 : : {
166 : 3 : data.ostream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
167 : : }
168 : :
169 : 5 : g_output_stream_splice_async (data.ostream, data.istream,
170 : : G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
171 : : G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
172 : : G_PRIORITY_DEFAULT, cancellable,
173 : : test_copy_chunks_splice_cb, &data);
174 : :
175 : : /* We do not hold a ref in data struct, this is to make sure the operation
176 : : * keeps the iostream objects alive until it finishes
177 : : */
178 : 5 : g_object_unref (data.istream);
179 : 5 : g_object_unref (data.ostream);
180 : 5 : g_clear_object (&cancellable);
181 : :
182 : 5 : g_main_loop_run (data.main_loop);
183 : 5 : g_main_loop_unref (data.main_loop);
184 : 5 : }
185 : :
186 : : static void
187 : 1 : test_copy_chunks (void)
188 : : {
189 : 1 : test_copy_chunks_start (TEST_THREADED_NONE);
190 : 1 : }
191 : :
192 : : static void
193 : 1 : test_copy_chunks_threaded_input (void)
194 : : {
195 : 1 : test_copy_chunks_start (TEST_THREADED_ISTREAM);
196 : 1 : }
197 : :
198 : : static void
199 : 1 : test_copy_chunks_threaded_output (void)
200 : : {
201 : 1 : test_copy_chunks_start (TEST_THREADED_OSTREAM);
202 : 1 : }
203 : :
204 : : static void
205 : 1 : test_copy_chunks_threaded (void)
206 : : {
207 : 1 : test_copy_chunks_start (TEST_THREADED_BOTH);
208 : 1 : }
209 : :
210 : : static void
211 : 1 : test_cancelled (void)
212 : : {
213 : 1 : test_copy_chunks_start (TEST_THREADED_NONE | TEST_CANCEL);
214 : 1 : }
215 : :
216 : : int
217 : 1 : main (int argc,
218 : : char *argv[])
219 : : {
220 : 1 : g_test_init (&argc, &argv, NULL);
221 : :
222 : 1 : g_test_add_func ("/async-splice/copy-chunks", test_copy_chunks);
223 : 1 : g_test_add_func ("/async-splice/copy-chunks-threaded-input",
224 : : test_copy_chunks_threaded_input);
225 : 1 : g_test_add_func ("/async-splice/copy-chunks-threaded-output",
226 : : test_copy_chunks_threaded_output);
227 : 1 : g_test_add_func ("/async-splice/copy-chunks-threaded",
228 : : test_copy_chunks_threaded);
229 : 1 : g_test_add_func ("/async-splice/cancelled",
230 : : test_cancelled);
231 : :
232 : 1 : return g_test_run();
233 : : }
|