nexmon – Blame information for rev 1

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