Branch data Line data Source code
1 : : /* GLib testing framework examples and tests
2 : : *
3 : : * Copyright (C) 2011 Collabora Ltd.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library 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. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : *
20 : : * Author: Stef Walter <stefw@collobora.co.uk>
21 : : */
22 : :
23 : : #include "config.h"
24 : :
25 : : #include <gio/gio.h>
26 : :
27 : : #include "gtesttlsbackend.h"
28 : :
29 : : static GPtrArray *fixtures = NULL;
30 : :
31 : : typedef struct {
32 : : /* Class virtual interaction methods */
33 : : gpointer ask_password_func;
34 : : gpointer ask_password_async_func;
35 : : gpointer ask_password_finish_func;
36 : : gpointer request_certificate_func;
37 : : gpointer request_certificate_async_func;
38 : : gpointer request_certificate_finish_func;
39 : :
40 : : /* Expected results */
41 : : GTlsInteractionResult result;
42 : : GQuark error_domain;
43 : : gint error_code;
44 : : const gchar *error_message;
45 : : } Fixture;
46 : :
47 : : typedef struct {
48 : : GTlsInteraction *interaction;
49 : : GTlsPassword *password;
50 : : GTlsConnection *connection;
51 : : GMainLoop *loop;
52 : : GThread *interaction_thread;
53 : : GThread *test_thread;
54 : : GThread *loop_thread;
55 : : const Fixture *fixture;
56 : : } Test;
57 : :
58 : : typedef struct {
59 : : GTlsInteraction parent;
60 : : Test *test;
61 : : } TestInteraction;
62 : :
63 : : typedef struct {
64 : : GTlsInteractionClass parent;
65 : : } TestInteractionClass;
66 : :
67 : : static GType test_interaction_get_type (void);
68 : 224 : G_DEFINE_TYPE (TestInteraction, test_interaction, G_TYPE_TLS_INTERACTION)
69 : :
70 : : #define TEST_TYPE_INTERACTION (test_interaction_get_type ())
71 : : #define TEST_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_INTERACTION, TestInteraction))
72 : : #define TEST_IS_INTERACTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TEST_TYPE_INTERACTION))
73 : :
74 : : static void
75 : 42 : test_interaction_init (TestInteraction *self)
76 : : {
77 : :
78 : 42 : }
79 : :
80 : : static void
81 : 1 : test_interaction_class_init (TestInteractionClass *klass)
82 : : {
83 : : /* By default no virtual methods */
84 : 1 : }
85 : :
86 : : static void
87 : 4 : test_interaction_ask_password_async_success (GTlsInteraction *interaction,
88 : : GTlsPassword *password,
89 : : GCancellable *cancellable,
90 : : GAsyncReadyCallback callback,
91 : : gpointer user_data)
92 : : {
93 : : GTask *task;
94 : : TestInteraction *self;
95 : :
96 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
97 : 4 : self = TEST_INTERACTION (interaction);
98 : :
99 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
100 : :
101 : 4 : g_assert (G_IS_TLS_PASSWORD (password));
102 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
103 : :
104 : 4 : task = g_task_new (self, cancellable, callback, user_data);
105 : :
106 : : /* Don't do this in real life. Include a null terminator for testing */
107 : 4 : g_tls_password_set_value (password, (const guchar *)"the password", 13);
108 : 4 : g_task_return_int (task, G_TLS_INTERACTION_HANDLED);
109 : 4 : g_object_unref (task);
110 : 4 : }
111 : :
112 : :
113 : : static GTlsInteractionResult
114 : 4 : test_interaction_ask_password_finish_success (GTlsInteraction *interaction,
115 : : GAsyncResult *result,
116 : : GError **error)
117 : : {
118 : : TestInteraction *self;
119 : :
120 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
121 : 4 : self = TEST_INTERACTION (interaction);
122 : :
123 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
124 : :
125 : 4 : g_assert (g_task_is_valid (result, interaction));
126 : 4 : g_assert (error != NULL);
127 : 4 : g_assert (*error == NULL);
128 : :
129 : 4 : return g_task_propagate_int (G_TASK (result), error);
130 : : }
131 : :
132 : : static void
133 : 4 : test_interaction_ask_password_async_failure (GTlsInteraction *interaction,
134 : : GTlsPassword *password,
135 : : GCancellable *cancellable,
136 : : GAsyncReadyCallback callback,
137 : : gpointer user_data)
138 : : {
139 : : GTask *task;
140 : : TestInteraction *self;
141 : :
142 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
143 : 4 : self = TEST_INTERACTION (interaction);
144 : :
145 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
146 : :
147 : 4 : g_assert (G_IS_TLS_PASSWORD (password));
148 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
149 : :
150 : 4 : task = g_task_new (self, cancellable, callback, user_data);
151 : :
152 : 4 : g_task_return_new_error_literal (task, G_FILE_ERROR, G_FILE_ERROR_ACCES, "The message");
153 : 4 : g_object_unref (task);
154 : 4 : }
155 : :
156 : : static GTlsInteractionResult
157 : 4 : test_interaction_ask_password_finish_failure (GTlsInteraction *interaction,
158 : : GAsyncResult *result,
159 : : GError **error)
160 : : {
161 : : TestInteraction *self;
162 : :
163 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
164 : 4 : self = TEST_INTERACTION (interaction);
165 : :
166 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
167 : :
168 : 4 : g_assert (g_task_is_valid (result, interaction));
169 : 4 : g_assert (error != NULL);
170 : 4 : g_assert (*error == NULL);
171 : :
172 : 4 : if (g_task_propagate_int (G_TASK (result), error) != -1)
173 : : g_assert_not_reached ();
174 : :
175 : 4 : return G_TLS_INTERACTION_FAILED;
176 : : }
177 : :
178 : :
179 : : /* Return a copy of @str that is allocated in a silly way, to exercise
180 : : * custom free-functions. The returned pointer points to a copy of @str
181 : : * in a buffer of the form "BEFORE \0 str \0 AFTER". */
182 : : static guchar *
183 : 8 : special_dup (const char *str)
184 : : {
185 : 8 : GString *buf = g_string_new ("BEFORE");
186 : : guchar *ret;
187 : :
188 : : g_string_append_c (buf, '\0');
189 : : g_string_append (buf, str);
190 : : g_string_append_c (buf, '\0');
191 : 8 : g_string_append (buf, "AFTER");
192 : 8 : ret = (guchar *) g_string_free (buf, FALSE);
193 : 8 : return ret + strlen ("BEFORE") + 1;
194 : : }
195 : :
196 : :
197 : : /* Free a copy of @str that was made with special_dup(), after asserting
198 : : * that it has not been corrupted. */
199 : : static void
200 : 8 : special_free (gpointer p)
201 : : {
202 : 8 : gchar *s = p;
203 : 8 : gchar *buf = s - strlen ("BEFORE") - 1;
204 : :
205 : 8 : g_assert_cmpstr (buf, ==, "BEFORE");
206 : 8 : g_assert_cmpstr (s + strlen (s) + 1, ==, "AFTER");
207 : 8 : g_free (buf);
208 : 8 : }
209 : :
210 : :
211 : : static GTlsInteractionResult
212 : 4 : test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
213 : : GTlsPassword *password,
214 : : GCancellable *cancellable,
215 : : GError **error)
216 : : {
217 : : TestInteraction *self;
218 : : const guchar *value;
219 : : gsize len;
220 : :
221 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
222 : 4 : self = TEST_INTERACTION (interaction);
223 : :
224 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
225 : :
226 : 4 : g_assert (G_IS_TLS_PASSWORD (password));
227 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
228 : 4 : g_assert (error != NULL);
229 : 4 : g_assert (*error == NULL);
230 : :
231 : : /* Exercise different ways to set the value */
232 : 4 : g_tls_password_set_value (password, (const guchar *) "foo", 4);
233 : 4 : len = 0;
234 : 4 : value = g_tls_password_get_value (password, &len);
235 : 4 : g_assert_cmpmem (value, len, "foo", 4);
236 : :
237 : 4 : g_tls_password_set_value (password, (const guchar *) "bar", -1);
238 : 4 : len = 0;
239 : 4 : value = g_tls_password_get_value (password, &len);
240 : 4 : g_assert_cmpmem (value, len, "bar", 3);
241 : :
242 : 4 : g_tls_password_set_value_full (password, special_dup ("baa"), 4, special_free);
243 : 4 : len = 0;
244 : 4 : value = g_tls_password_get_value (password, &len);
245 : 4 : g_assert_cmpmem (value, len, "baa", 4);
246 : :
247 : 4 : g_tls_password_set_value_full (password, special_dup ("baz"), -1, special_free);
248 : 4 : len = 0;
249 : 4 : value = g_tls_password_get_value (password, &len);
250 : 4 : g_assert_cmpmem (value, len, "baz", 3);
251 : :
252 : : /* Don't do this in real life. Include a null terminator for testing */
253 : 4 : g_tls_password_set_value (password, (const guchar *)"the password", 13);
254 : 4 : return G_TLS_INTERACTION_HANDLED;
255 : : }
256 : :
257 : : static GTlsInteractionResult
258 : 4 : test_interaction_ask_password_sync_failure (GTlsInteraction *interaction,
259 : : GTlsPassword *password,
260 : : GCancellable *cancellable,
261 : : GError **error)
262 : : {
263 : : TestInteraction *self;
264 : :
265 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
266 : 4 : self = TEST_INTERACTION (interaction);
267 : :
268 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
269 : :
270 : 4 : g_assert (G_IS_TLS_PASSWORD (password));
271 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
272 : 4 : g_assert (error != NULL);
273 : 4 : g_assert (*error == NULL);
274 : :
275 : 4 : g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_ACCES, "The message");
276 : 4 : return G_TLS_INTERACTION_FAILED;
277 : : }
278 : :
279 : : static void
280 : 4 : test_interaction_request_certificate_async_success (GTlsInteraction *interaction,
281 : : GTlsConnection *connection,
282 : : gint unused_flags,
283 : : GCancellable *cancellable,
284 : : GAsyncReadyCallback callback,
285 : : gpointer user_data)
286 : : {
287 : : GTask *task;
288 : : TestInteraction *self;
289 : :
290 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
291 : 4 : self = TEST_INTERACTION (interaction);
292 : :
293 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
294 : :
295 : 4 : g_assert (G_IS_TLS_CONNECTION (connection));
296 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
297 : 4 : g_assert (unused_flags == 0);
298 : :
299 : 4 : task = g_task_new (self, cancellable, callback, user_data);
300 : :
301 : : /*
302 : : * IRL would call g_tls_connection_set_certificate(). But here just touch
303 : : * the connection in a detectable way.
304 : : */
305 : 4 : g_object_set_data (G_OBJECT (connection), "chosen-certificate", "my-certificate");
306 : 4 : g_task_return_int (task, G_TLS_INTERACTION_HANDLED);
307 : 4 : g_object_unref (task);
308 : 4 : }
309 : :
310 : : static GTlsInteractionResult
311 : 4 : test_interaction_request_certificate_finish_success (GTlsInteraction *interaction,
312 : : GAsyncResult *result,
313 : : GError **error)
314 : : {
315 : : TestInteraction *self;
316 : :
317 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
318 : 4 : self = TEST_INTERACTION (interaction);
319 : :
320 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
321 : :
322 : 4 : g_assert (g_task_is_valid (result, interaction));
323 : 4 : g_assert (error != NULL);
324 : 4 : g_assert (*error == NULL);
325 : :
326 : 4 : return g_task_propagate_int (G_TASK (result), error);
327 : : }
328 : :
329 : : static void
330 : 4 : test_interaction_request_certificate_async_failure (GTlsInteraction *interaction,
331 : : GTlsConnection *connection,
332 : : gint unused_flags,
333 : : GCancellable *cancellable,
334 : : GAsyncReadyCallback callback,
335 : : gpointer user_data)
336 : : {
337 : : GTask *task;
338 : : TestInteraction *self;
339 : :
340 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
341 : 4 : self = TEST_INTERACTION (interaction);
342 : :
343 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
344 : :
345 : 4 : g_assert (G_IS_TLS_CONNECTION (connection));
346 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
347 : 4 : g_assert (unused_flags == 0);
348 : :
349 : 4 : task = g_task_new (self, cancellable, callback, user_data);
350 : :
351 : 4 : g_task_return_new_error_literal (task, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message");
352 : 4 : g_object_unref (task);
353 : 4 : }
354 : :
355 : : static GTlsInteractionResult
356 : 4 : test_interaction_request_certificate_finish_failure (GTlsInteraction *interaction,
357 : : GAsyncResult *result,
358 : : GError **error)
359 : : {
360 : : TestInteraction *self;
361 : :
362 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
363 : 4 : self = TEST_INTERACTION (interaction);
364 : :
365 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
366 : :
367 : 4 : g_assert (g_task_is_valid (result, interaction));
368 : 4 : g_assert (error != NULL);
369 : 4 : g_assert (*error == NULL);
370 : :
371 : 4 : if (g_task_propagate_int (G_TASK (result), error) != -1)
372 : : g_assert_not_reached ();
373 : :
374 : 4 : return G_TLS_INTERACTION_FAILED;
375 : : }
376 : :
377 : : static GTlsInteractionResult
378 : 4 : test_interaction_request_certificate_sync_success (GTlsInteraction *interaction,
379 : : GTlsConnection *connection,
380 : : gint unused_flags,
381 : : GCancellable *cancellable,
382 : : GError **error)
383 : : {
384 : : TestInteraction *self;
385 : :
386 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
387 : 4 : self = TEST_INTERACTION (interaction);
388 : :
389 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
390 : :
391 : 4 : g_assert (G_IS_TLS_CONNECTION (connection));
392 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
393 : 4 : g_assert (error != NULL);
394 : 4 : g_assert (*error == NULL);
395 : :
396 : : /*
397 : : * IRL would call g_tls_connection_set_certificate(). But here just touch
398 : : * the connection in a detectable way.
399 : : */
400 : 4 : g_object_set_data (G_OBJECT (connection), "chosen-certificate", "my-certificate");
401 : 4 : return G_TLS_INTERACTION_HANDLED;
402 : : }
403 : :
404 : : static GTlsInteractionResult
405 : 4 : test_interaction_request_certificate_sync_failure (GTlsInteraction *interaction,
406 : : GTlsConnection *connection,
407 : : gint unused_flags,
408 : : GCancellable *cancellable,
409 : : GError **error)
410 : : {
411 : : TestInteraction *self;
412 : :
413 : 4 : g_assert (TEST_IS_INTERACTION (interaction));
414 : 4 : self = TEST_INTERACTION (interaction);
415 : :
416 : 4 : g_assert (g_thread_self () == self->test->interaction_thread);
417 : :
418 : 4 : g_assert (G_IS_TLS_CONNECTION (connection));
419 : 4 : g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
420 : 4 : g_assert (unused_flags == 0);
421 : 4 : g_assert (error != NULL);
422 : 4 : g_assert (*error == NULL);
423 : :
424 : 4 : g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, "Another message");
425 : 4 : return G_TLS_INTERACTION_FAILED;
426 : : }
427 : :
428 : : /* ----------------------------------------------------------------------------
429 : : * ACTUAL TESTS
430 : : */
431 : :
432 : : static void
433 : 3 : on_ask_password_async_call (GObject *source,
434 : : GAsyncResult *result,
435 : : gpointer user_data)
436 : : {
437 : 3 : Test *test = user_data;
438 : : GTlsInteractionResult res;
439 : 3 : GError *error = NULL;
440 : :
441 : 3 : g_assert (G_IS_TLS_INTERACTION (source));
442 : 3 : g_assert (G_TLS_INTERACTION (source) == test->interaction);
443 : :
444 : : /* Check that this callback is being run in the right place */
445 : 3 : g_assert (g_thread_self () == test->interaction_thread);
446 : :
447 : 3 : res = g_tls_interaction_ask_password_finish (test->interaction, result,
448 : : &error);
449 : :
450 : : /* Check that the results match the fixture */
451 : 3 : g_assert_cmpuint (test->fixture->result, ==, res);
452 : 3 : switch (test->fixture->result)
453 : : {
454 : 1 : case G_TLS_INTERACTION_HANDLED:
455 : 1 : g_assert_no_error (error);
456 : 1 : g_assert_cmpstr ((const gchar *)g_tls_password_get_value (test->password, NULL), ==, "the password");
457 : 1 : break;
458 : 1 : case G_TLS_INTERACTION_FAILED:
459 : 1 : g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
460 : 1 : g_assert_cmpstr (error->message, ==, test->fixture->error_message);
461 : 1 : g_clear_error (&error);
462 : 1 : break;
463 : 1 : case G_TLS_INTERACTION_UNHANDLED:
464 : 1 : g_assert_no_error (error);
465 : 1 : break;
466 : 0 : default:
467 : : g_assert_not_reached ();
468 : : }
469 : :
470 : : /* Signal the end of the test */
471 : 3 : g_main_loop_quit (test->loop);
472 : 3 : }
473 : :
474 : : static void
475 : 3 : test_ask_password_async (Test *test,
476 : : gconstpointer unused)
477 : : {
478 : : /* This test only works with a main loop */
479 : 3 : g_assert (test->loop);
480 : :
481 : 3 : g_tls_interaction_ask_password_async (test->interaction,
482 : : test->password, NULL,
483 : : on_ask_password_async_call,
484 : : test);
485 : :
486 : : /* teardown waits until g_main_loop_quit(). called from callback */
487 : 3 : }
488 : :
489 : : static void
490 : 15 : test_invoke_ask_password (Test *test,
491 : : gconstpointer unused)
492 : : {
493 : : GTlsInteractionResult res;
494 : 15 : GError *error = NULL;
495 : :
496 : 15 : res = g_tls_interaction_invoke_ask_password (test->interaction, test->password,
497 : : NULL, &error);
498 : :
499 : : /* Check that the results match the fixture */
500 : 15 : g_assert_cmpuint (test->fixture->result, ==, res);
501 : 15 : switch (test->fixture->result)
502 : : {
503 : 6 : case G_TLS_INTERACTION_HANDLED:
504 : 6 : g_assert_no_error (error);
505 : 6 : g_assert_cmpstr ((const gchar *)g_tls_password_get_value (test->password, NULL), ==, "the password");
506 : 6 : break;
507 : 6 : case G_TLS_INTERACTION_FAILED:
508 : 6 : g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
509 : 6 : g_assert_cmpstr (error->message, ==, test->fixture->error_message);
510 : 6 : g_clear_error (&error);
511 : 6 : break;
512 : 3 : case G_TLS_INTERACTION_UNHANDLED:
513 : 3 : g_assert_no_error (error);
514 : 3 : break;
515 : 0 : default:
516 : : g_assert_not_reached ();
517 : : }
518 : :
519 : : /* This allows teardown to stop if running with loop */
520 : 15 : if (test->loop)
521 : 10 : g_main_loop_quit (test->loop);
522 : 15 : }
523 : :
524 : : static void
525 : 3 : test_ask_password (Test *test,
526 : : gconstpointer unused)
527 : : {
528 : : GTlsInteractionResult res;
529 : 3 : GError *error = NULL;
530 : :
531 : 3 : res = g_tls_interaction_ask_password (test->interaction, test->password,
532 : : NULL, &error);
533 : :
534 : : /* Check that the results match the fixture */
535 : 3 : g_assert_cmpuint (test->fixture->result, ==, res);
536 : 3 : switch (test->fixture->result)
537 : : {
538 : 1 : case G_TLS_INTERACTION_HANDLED:
539 : 1 : g_assert_no_error (error);
540 : 1 : g_assert_cmpstr ((const gchar *)g_tls_password_get_value (test->password, NULL), ==, "the password");
541 : 1 : break;
542 : 1 : case G_TLS_INTERACTION_FAILED:
543 : 1 : g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
544 : 1 : g_assert_cmpstr (error->message, ==, test->fixture->error_message);
545 : 1 : g_clear_error (&error);
546 : 1 : break;
547 : 1 : case G_TLS_INTERACTION_UNHANDLED:
548 : 1 : g_assert_no_error (error);
549 : 1 : break;
550 : 0 : default:
551 : : g_assert_not_reached ();
552 : : }
553 : :
554 : : /* This allows teardown to stop if running with loop */
555 : 3 : if (test->loop)
556 : 0 : g_main_loop_quit (test->loop);
557 : 3 : }
558 : :
559 : : static void
560 : 3 : on_request_certificate_async_call (GObject *source,
561 : : GAsyncResult *result,
562 : : gpointer user_data)
563 : : {
564 : 3 : Test *test = user_data;
565 : : GTlsInteractionResult res;
566 : 3 : GError *error = NULL;
567 : :
568 : 3 : g_assert (G_IS_TLS_INTERACTION (source));
569 : 3 : g_assert (G_TLS_INTERACTION (source) == test->interaction);
570 : :
571 : : /* Check that this callback is being run in the right place */
572 : 3 : g_assert (g_thread_self () == test->interaction_thread);
573 : :
574 : 3 : res = g_tls_interaction_request_certificate_finish (test->interaction, result, &error);
575 : :
576 : : /* Check that the results match the fixture */
577 : 3 : g_assert_cmpuint (test->fixture->result, ==, res);
578 : 3 : switch (test->fixture->result)
579 : : {
580 : 1 : case G_TLS_INTERACTION_HANDLED:
581 : 1 : g_assert_no_error (error);
582 : 1 : g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate");
583 : 1 : break;
584 : 1 : case G_TLS_INTERACTION_FAILED:
585 : 1 : g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
586 : 1 : g_assert_cmpstr (error->message, ==, test->fixture->error_message);
587 : 1 : g_clear_error (&error);
588 : 1 : break;
589 : 1 : case G_TLS_INTERACTION_UNHANDLED:
590 : 1 : g_assert_no_error (error);
591 : 1 : break;
592 : 0 : default:
593 : : g_assert_not_reached ();
594 : : }
595 : :
596 : : /* Signal the end of the test */
597 : 3 : g_main_loop_quit (test->loop);
598 : 3 : }
599 : :
600 : : static void
601 : 3 : test_request_certificate_async (Test *test,
602 : : gconstpointer unused)
603 : : {
604 : : /* This test only works with a main loop */
605 : 3 : g_assert (test->loop);
606 : :
607 : 3 : g_tls_interaction_request_certificate_async (test->interaction,
608 : : test->connection, 0, NULL,
609 : : on_request_certificate_async_call,
610 : : test);
611 : :
612 : : /* teardown waits until g_main_loop_quit(). called from callback */
613 : 3 : }
614 : :
615 : : static void
616 : 15 : test_invoke_request_certificate (Test *test,
617 : : gconstpointer unused)
618 : : {
619 : : GTlsInteractionResult res;
620 : 15 : GError *error = NULL;
621 : :
622 : 15 : res = g_tls_interaction_invoke_request_certificate (test->interaction,
623 : : test->connection,
624 : : 0, NULL, &error);
625 : :
626 : : /* Check that the results match the fixture */
627 : 15 : g_assert_cmpuint (test->fixture->result, ==, res);
628 : 15 : switch (test->fixture->result)
629 : : {
630 : 6 : case G_TLS_INTERACTION_HANDLED:
631 : 6 : g_assert_no_error (error);
632 : 6 : g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate");
633 : 6 : break;
634 : 6 : case G_TLS_INTERACTION_FAILED:
635 : 6 : g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
636 : 6 : g_assert_cmpstr (error->message, ==, test->fixture->error_message);
637 : 6 : g_clear_error (&error);
638 : 6 : break;
639 : 3 : case G_TLS_INTERACTION_UNHANDLED:
640 : 3 : g_assert_no_error (error);
641 : 3 : break;
642 : 0 : default:
643 : : g_assert_not_reached ();
644 : : }
645 : :
646 : : /* This allows teardown to stop if running with loop */
647 : 15 : if (test->loop)
648 : 10 : g_main_loop_quit (test->loop);
649 : 15 : }
650 : :
651 : : static void
652 : 3 : test_request_certificate (Test *test,
653 : : gconstpointer unused)
654 : : {
655 : : GTlsInteractionResult res;
656 : 3 : GError *error = NULL;
657 : :
658 : 3 : res = g_tls_interaction_request_certificate (test->interaction, test->connection,
659 : : 0, NULL, &error);
660 : :
661 : : /* Check that the results match the fixture */
662 : 3 : g_assert_cmpuint (test->fixture->result, ==, res);
663 : 3 : switch (test->fixture->result)
664 : : {
665 : 1 : case G_TLS_INTERACTION_HANDLED:
666 : 1 : g_assert_no_error (error);
667 : 1 : g_assert_cmpstr (g_object_get_data (G_OBJECT (test->connection), "chosen-certificate"), ==, "my-certificate");
668 : 1 : break;
669 : 1 : case G_TLS_INTERACTION_FAILED:
670 : 1 : g_assert_error (error, test->fixture->error_domain, test->fixture->error_code);
671 : 1 : g_assert_cmpstr (error->message, ==, test->fixture->error_message);
672 : 1 : g_clear_error (&error);
673 : 1 : break;
674 : 1 : case G_TLS_INTERACTION_UNHANDLED:
675 : 1 : g_assert_no_error (error);
676 : 1 : break;
677 : 0 : default:
678 : : g_assert_not_reached ();
679 : : }
680 : :
681 : : /* This allows teardown to stop if running with loop */
682 : 3 : if (test->loop)
683 : 0 : g_main_loop_quit (test->loop);
684 : 3 : }
685 : :
686 : : /* ----------------------------------------------------------------------------
687 : : * TEST SETUP
688 : : */
689 : :
690 : : static void
691 : 42 : setup_without_loop (Test *test,
692 : : gconstpointer user_data)
693 : : {
694 : 42 : const Fixture *fixture = user_data;
695 : : GTlsInteractionClass *klass;
696 : : GTlsBackend *backend;
697 : 42 : GError *error = NULL;
698 : :
699 : 42 : test->fixture = fixture;
700 : :
701 : 42 : test->interaction = g_object_new (TEST_TYPE_INTERACTION, NULL);
702 : 42 : g_assert (TEST_IS_INTERACTION (test->interaction));
703 : :
704 : 42 : TEST_INTERACTION (test->interaction)->test = test;
705 : :
706 : 42 : klass = G_TLS_INTERACTION_GET_CLASS (test->interaction);
707 : 42 : klass->ask_password = fixture->ask_password_func;
708 : 42 : klass->ask_password_async = fixture->ask_password_async_func;
709 : 42 : klass->ask_password_finish = fixture->ask_password_finish_func;
710 : 42 : klass->request_certificate = fixture->request_certificate_func;
711 : 42 : klass->request_certificate_async = fixture->request_certificate_async_func;
712 : 42 : klass->request_certificate_finish = fixture->request_certificate_finish_func;
713 : :
714 : 42 : backend = g_object_new (G_TYPE_TEST_TLS_BACKEND, NULL);
715 : 42 : test->connection = g_object_new (g_tls_backend_get_server_connection_type (backend), NULL);
716 : 42 : g_assert_no_error (error);
717 : 42 : g_object_unref (backend);
718 : :
719 : 42 : test->password = g_tls_password_new (0, "Description");
720 : 42 : test->test_thread = g_thread_self ();
721 : :
722 : : /*
723 : : * If no loop is running then interaction should happen in the same
724 : : * thread that the tests are running in.
725 : : */
726 : 42 : test->interaction_thread = test->test_thread;
727 : 42 : }
728 : :
729 : : static void
730 : 42 : teardown_without_loop (Test *test,
731 : : gconstpointer unused)
732 : : {
733 : 42 : g_object_unref (test->connection);
734 : 42 : g_object_unref (test->password);
735 : :
736 : 42 : g_assert_finalize_object (test->interaction);
737 : 42 : }
738 : :
739 : : typedef struct {
740 : : GMutex loop_mutex;
741 : : GCond loop_started;
742 : : gboolean started;
743 : : Test *test;
744 : : } ThreadLoop;
745 : :
746 : : static gpointer
747 : 10 : thread_loop (gpointer user_data)
748 : : {
749 : 10 : GMainContext *context = g_main_context_default ();
750 : 10 : ThreadLoop *closure = user_data;
751 : 10 : Test *test = closure->test;
752 : :
753 : 10 : g_mutex_lock (&closure->loop_mutex);
754 : :
755 : 10 : g_assert (test->loop_thread == g_thread_self ());
756 : 10 : g_assert (test->loop == NULL);
757 : 10 : test->loop = g_main_loop_new (context, TRUE);
758 : :
759 : 10 : g_main_context_acquire (context);
760 : 10 : closure->started = TRUE;
761 : 10 : g_cond_signal (&closure->loop_started);
762 : 10 : g_mutex_unlock (&closure->loop_mutex);
763 : :
764 : 33 : while (g_main_loop_is_running (test->loop))
765 : 23 : g_main_context_iteration (context, TRUE);
766 : :
767 : 10 : g_main_context_release (context);
768 : 10 : return test;
769 : : }
770 : :
771 : : static void
772 : 10 : setup_with_thread_loop (Test *test,
773 : : gconstpointer user_data)
774 : : {
775 : : ThreadLoop closure;
776 : :
777 : 10 : setup_without_loop (test, user_data);
778 : :
779 : 10 : g_mutex_init (&closure.loop_mutex);
780 : 10 : g_cond_init (&closure.loop_started);
781 : 10 : closure.started = FALSE;
782 : 10 : closure.test = test;
783 : :
784 : 10 : g_mutex_lock (&closure.loop_mutex);
785 : 10 : test->loop_thread = g_thread_new ("loop", thread_loop, &closure);
786 : 20 : while (!closure.started)
787 : 10 : g_cond_wait (&closure.loop_started, &closure.loop_mutex);
788 : 10 : g_mutex_unlock (&closure.loop_mutex);
789 : :
790 : : /*
791 : : * When a loop is running then interaction should always occur in the main
792 : : * context of that loop.
793 : : */
794 : 10 : test->interaction_thread = test->loop_thread;
795 : :
796 : 10 : g_mutex_clear (&closure.loop_mutex);
797 : 10 : g_cond_clear (&closure.loop_started);
798 : 10 : }
799 : :
800 : : static void
801 : 10 : teardown_with_thread_loop (Test *test,
802 : : gconstpointer unused)
803 : : {
804 : : gpointer check;
805 : :
806 : 10 : g_assert (test->loop_thread);
807 : 10 : check = g_thread_join (test->loop_thread);
808 : 10 : g_assert (check == test);
809 : 10 : test->loop_thread = NULL;
810 : :
811 : 10 : g_main_loop_unref (test->loop);
812 : :
813 : 10 : teardown_without_loop (test, unused);
814 : 10 : }
815 : :
816 : : static void
817 : 16 : setup_with_normal_loop (Test *test,
818 : : gconstpointer user_data)
819 : : {
820 : : GMainContext *context;
821 : :
822 : 16 : setup_without_loop (test, user_data);
823 : :
824 : 16 : context = g_main_context_default ();
825 : 16 : if (!g_main_context_acquire (context))
826 : : g_assert_not_reached ();
827 : :
828 : 16 : test->loop = g_main_loop_new (context, TRUE);
829 : 16 : g_assert (g_main_loop_is_running (test->loop));
830 : 16 : }
831 : :
832 : : static void
833 : 16 : teardown_with_normal_loop (Test *test,
834 : : gconstpointer unused)
835 : : {
836 : : GMainContext *context;
837 : :
838 : 16 : context = g_main_context_default ();
839 : 22 : while (g_main_loop_is_running (test->loop))
840 : 6 : g_main_context_iteration (context, TRUE);
841 : :
842 : 16 : g_main_context_release (context);
843 : :
844 : : /* Run test until complete */
845 : 16 : g_main_loop_unref (test->loop);
846 : 16 : test->loop = NULL;
847 : :
848 : 16 : teardown_without_loop (test, unused);
849 : 16 : }
850 : :
851 : : typedef void (*TestFunc) (Test *test, gconstpointer data);
852 : :
853 : : static void
854 : 4 : test_with_async_ask_password (const gchar *name,
855 : : TestFunc setup,
856 : : TestFunc func,
857 : : TestFunc teardown)
858 : : {
859 : : gchar *test_name;
860 : : Fixture *fixture;
861 : :
862 : : /* Async implementation that succeeds */
863 : 4 : fixture = g_new0 (Fixture, 1);
864 : 4 : fixture->ask_password_async_func = test_interaction_ask_password_async_success;
865 : 4 : fixture->ask_password_finish_func = test_interaction_ask_password_finish_success;
866 : 4 : fixture->ask_password_func = NULL;
867 : 4 : fixture->result = G_TLS_INTERACTION_HANDLED;
868 : 4 : test_name = g_strdup_printf ("%s/async-implementation-success", name);
869 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
870 : 4 : g_free (test_name);
871 : 4 : g_ptr_array_add (fixtures, fixture);
872 : :
873 : : /* Async implementation that fails */
874 : 4 : fixture = g_new0 (Fixture, 1);
875 : 4 : fixture->ask_password_async_func = test_interaction_ask_password_async_failure;
876 : 4 : fixture->ask_password_finish_func = test_interaction_ask_password_finish_failure;
877 : 4 : fixture->ask_password_func = NULL;
878 : 4 : fixture->result = G_TLS_INTERACTION_FAILED;
879 : 4 : fixture->error_domain = G_FILE_ERROR;
880 : 4 : fixture->error_code = G_FILE_ERROR_ACCES;
881 : 4 : fixture->error_message = "The message";
882 : 4 : test_name = g_strdup_printf ("%s/async-implementation-failure", name);
883 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
884 : 4 : g_free (test_name);
885 : 4 : g_ptr_array_add (fixtures, fixture);
886 : 4 : }
887 : :
888 : : static void
889 : 5 : test_with_unhandled_ask_password (const gchar *name,
890 : : TestFunc setup,
891 : : TestFunc func,
892 : : TestFunc teardown)
893 : : {
894 : : gchar *test_name;
895 : : Fixture *fixture;
896 : :
897 : : /* Unhandled implementation */
898 : 5 : fixture = g_new0 (Fixture, 1);
899 : 5 : fixture->ask_password_async_func = NULL;
900 : 5 : fixture->ask_password_finish_func = NULL;
901 : 5 : fixture->ask_password_func = NULL;
902 : 5 : fixture->result = G_TLS_INTERACTION_UNHANDLED;
903 : 5 : test_name = g_strdup_printf ("%s/unhandled-implementation", name);
904 : 5 : g_test_add (test_name, Test, fixture, setup, func, teardown);
905 : 5 : g_free (test_name);
906 : 5 : g_ptr_array_add (fixtures, fixture);
907 : 5 : }
908 : :
909 : : static void
910 : 4 : test_with_sync_ask_password (const gchar *name,
911 : : TestFunc setup,
912 : : TestFunc func,
913 : : TestFunc teardown)
914 : : {
915 : : gchar *test_name;
916 : : Fixture *fixture;
917 : :
918 : : /* Sync implementation that succeeds */
919 : 4 : fixture = g_new0 (Fixture, 1);
920 : 4 : fixture->ask_password_async_func = NULL;
921 : 4 : fixture->ask_password_finish_func = NULL;
922 : 4 : fixture->ask_password_func = test_interaction_ask_password_sync_success;
923 : 4 : fixture->result = G_TLS_INTERACTION_HANDLED;
924 : 4 : test_name = g_strdup_printf ("%s/sync-implementation-success", name);
925 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
926 : 4 : g_free (test_name);
927 : 4 : g_ptr_array_add (fixtures, fixture);
928 : :
929 : : /* Async implementation that fails */
930 : 4 : fixture = g_new0 (Fixture, 1);
931 : 4 : fixture->ask_password_async_func = NULL;
932 : 4 : fixture->ask_password_finish_func = NULL;
933 : 4 : fixture->ask_password_func = test_interaction_ask_password_sync_failure;
934 : 4 : fixture->result = G_TLS_INTERACTION_FAILED;
935 : 4 : fixture->error_domain = G_FILE_ERROR;
936 : 4 : fixture->error_code = G_FILE_ERROR_ACCES;
937 : 4 : fixture->error_message = "The message";
938 : 4 : test_name = g_strdup_printf ("%s/sync-implementation-failure", name);
939 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
940 : 4 : g_free (test_name);
941 : 4 : g_ptr_array_add (fixtures, fixture);
942 : 4 : }
943 : :
944 : : static void
945 : 3 : test_with_all_ask_password (const gchar *name,
946 : : TestFunc setup,
947 : : TestFunc func,
948 : : TestFunc teardown)
949 : : {
950 : 3 : test_with_unhandled_ask_password (name, setup, func, teardown);
951 : 3 : test_with_async_ask_password (name, setup, func, teardown);
952 : 3 : test_with_sync_ask_password (name, setup, func, teardown);
953 : 3 : }
954 : :
955 : : static void
956 : 4 : test_with_async_request_certificate (const gchar *name,
957 : : TestFunc setup,
958 : : TestFunc func,
959 : : TestFunc teardown)
960 : : {
961 : : gchar *test_name;
962 : : Fixture *fixture;
963 : :
964 : : /* Async implementation that succeeds */
965 : 4 : fixture = g_new0 (Fixture, 1);
966 : 4 : fixture->request_certificate_async_func = test_interaction_request_certificate_async_success;
967 : 4 : fixture->request_certificate_finish_func = test_interaction_request_certificate_finish_success;
968 : 4 : fixture->request_certificate_func = NULL;
969 : 4 : fixture->result = G_TLS_INTERACTION_HANDLED;
970 : 4 : test_name = g_strdup_printf ("%s/async-implementation-success", name);
971 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
972 : 4 : g_free (test_name);
973 : 4 : g_ptr_array_add (fixtures, fixture);
974 : :
975 : : /* Async implementation that fails */
976 : 4 : fixture = g_new0 (Fixture, 1);
977 : 4 : fixture->request_certificate_async_func = test_interaction_request_certificate_async_failure;
978 : 4 : fixture->request_certificate_finish_func = test_interaction_request_certificate_finish_failure;
979 : 4 : fixture->request_certificate_func = NULL;
980 : 4 : fixture->result = G_TLS_INTERACTION_FAILED;
981 : 4 : fixture->error_domain = G_FILE_ERROR;
982 : 4 : fixture->error_code = G_FILE_ERROR_NOENT;
983 : 4 : fixture->error_message = "Another message";
984 : 4 : test_name = g_strdup_printf ("%s/async-implementation-failure", name);
985 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
986 : 4 : g_free (test_name);
987 : 4 : g_ptr_array_add (fixtures, fixture);
988 : 4 : }
989 : :
990 : : static void
991 : 5 : test_with_unhandled_request_certificate (const gchar *name,
992 : : TestFunc setup,
993 : : TestFunc func,
994 : : TestFunc teardown)
995 : : {
996 : : gchar *test_name;
997 : : Fixture *fixture;
998 : :
999 : : /* Unhandled implementation */
1000 : 5 : fixture = g_new0 (Fixture, 1);
1001 : 5 : fixture->request_certificate_async_func = NULL;
1002 : 5 : fixture->request_certificate_finish_func = NULL;
1003 : 5 : fixture->request_certificate_func = NULL;
1004 : 5 : fixture->result = G_TLS_INTERACTION_UNHANDLED;
1005 : 5 : test_name = g_strdup_printf ("%s/unhandled-implementation", name);
1006 : 5 : g_test_add (test_name, Test, fixture, setup, func, teardown);
1007 : 5 : g_free (test_name);
1008 : 5 : g_ptr_array_add (fixtures, fixture);
1009 : 5 : }
1010 : :
1011 : : static void
1012 : 4 : test_with_sync_request_certificate (const gchar *name,
1013 : : TestFunc setup,
1014 : : TestFunc func,
1015 : : TestFunc teardown)
1016 : : {
1017 : : gchar *test_name;
1018 : : Fixture *fixture;
1019 : :
1020 : : /* Sync implementation that succeeds */
1021 : 4 : fixture = g_new0 (Fixture, 1);
1022 : 4 : fixture->request_certificate_async_func = NULL;
1023 : 4 : fixture->request_certificate_finish_func = NULL;
1024 : 4 : fixture->request_certificate_func = test_interaction_request_certificate_sync_success;
1025 : 4 : fixture->result = G_TLS_INTERACTION_HANDLED;
1026 : 4 : test_name = g_strdup_printf ("%s/sync-implementation-success", name);
1027 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
1028 : 4 : g_free (test_name);
1029 : 4 : g_ptr_array_add (fixtures, fixture);
1030 : :
1031 : : /* Async implementation that fails */
1032 : 4 : fixture = g_new0 (Fixture, 1);
1033 : 4 : fixture->request_certificate_async_func = NULL;
1034 : 4 : fixture->request_certificate_finish_func = NULL;
1035 : 4 : fixture->request_certificate_func = test_interaction_request_certificate_sync_failure;
1036 : 4 : fixture->result = G_TLS_INTERACTION_FAILED;
1037 : 4 : fixture->error_domain = G_FILE_ERROR;
1038 : 4 : fixture->error_code = G_FILE_ERROR_NOENT;
1039 : 4 : fixture->error_message = "Another message";
1040 : 4 : test_name = g_strdup_printf ("%s/sync-implementation-failure", name);
1041 : 4 : g_test_add (test_name, Test, fixture, setup, func, teardown);
1042 : 4 : g_free (test_name);
1043 : 4 : g_ptr_array_add (fixtures, fixture);
1044 : 4 : }
1045 : :
1046 : : static void
1047 : 3 : test_with_all_request_certificate (const gchar *name,
1048 : : TestFunc setup,
1049 : : TestFunc func,
1050 : : TestFunc teardown)
1051 : : {
1052 : 3 : test_with_unhandled_request_certificate (name, setup, func, teardown);
1053 : 3 : test_with_async_request_certificate (name, setup, func, teardown);
1054 : 3 : test_with_sync_request_certificate (name, setup, func, teardown);
1055 : 3 : }
1056 : : int
1057 : 1 : main (int argc,
1058 : : char *argv[])
1059 : : {
1060 : : gint ret;
1061 : :
1062 : 1 : g_test_init (&argc, &argv, NULL);
1063 : :
1064 : 1 : fixtures = g_ptr_array_new_with_free_func (g_free);
1065 : :
1066 : : /* Tests for g_tls_interaction_invoke_ask_password */
1067 : 1 : test_with_all_ask_password ("/tls-interaction/ask-password/invoke-with-loop",
1068 : : setup_with_thread_loop, test_invoke_ask_password, teardown_with_thread_loop);
1069 : 1 : test_with_all_ask_password ("/tls-interaction/ask-password/invoke-without-loop",
1070 : : setup_without_loop, test_invoke_ask_password, teardown_without_loop);
1071 : 1 : test_with_all_ask_password ("/tls-interaction/ask-password/invoke-in-loop",
1072 : : setup_with_normal_loop, test_invoke_ask_password, teardown_with_normal_loop);
1073 : :
1074 : : /* Tests for g_tls_interaction_ask_password */
1075 : 1 : test_with_unhandled_ask_password ("/tls-interaction/ask-password/sync",
1076 : : setup_without_loop, test_ask_password, teardown_without_loop);
1077 : 1 : test_with_sync_ask_password ("/tls-interaction/ask-password/sync",
1078 : : setup_without_loop, test_ask_password, teardown_without_loop);
1079 : :
1080 : : /* Tests for g_tls_interaction_ask_password_async */
1081 : 1 : test_with_unhandled_ask_password ("/tls-interaction/ask-password/async",
1082 : : setup_with_normal_loop, test_ask_password_async, teardown_with_normal_loop);
1083 : 1 : test_with_async_ask_password ("/tls-interaction/ask-password/async",
1084 : : setup_with_normal_loop, test_ask_password_async, teardown_with_normal_loop);
1085 : :
1086 : : /* Tests for g_tls_interaction_invoke_request_certificate */
1087 : 1 : test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-with-loop",
1088 : : setup_with_thread_loop, test_invoke_request_certificate, teardown_with_thread_loop);
1089 : 1 : test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-without-loop",
1090 : : setup_without_loop, test_invoke_request_certificate, teardown_without_loop);
1091 : 1 : test_with_all_request_certificate ("/tls-interaction/request-certificate/invoke-in-loop",
1092 : : setup_with_normal_loop, test_invoke_request_certificate, teardown_with_normal_loop);
1093 : :
1094 : : /* Tests for g_tls_interaction_ask_password */
1095 : 1 : test_with_unhandled_request_certificate ("/tls-interaction/request-certificate/sync",
1096 : : setup_without_loop, test_request_certificate, teardown_without_loop);
1097 : 1 : test_with_sync_request_certificate ("/tls-interaction/request-certificate/sync",
1098 : : setup_without_loop, test_request_certificate, teardown_without_loop);
1099 : :
1100 : : /* Tests for g_tls_interaction_ask_password_async */
1101 : 1 : test_with_unhandled_request_certificate ("/tls-interaction/request-certificate/async",
1102 : : setup_with_normal_loop, test_request_certificate_async, teardown_with_normal_loop);
1103 : 1 : test_with_async_request_certificate ("/tls-interaction/request-certificate/async",
1104 : : setup_with_normal_loop, test_request_certificate_async, teardown_with_normal_loop);
1105 : :
1106 : 1 : ret = g_test_run();
1107 : 1 : g_ptr_array_free (fixtures, TRUE);
1108 : 1 : return ret;
1109 : : }
|