811b5412b3709fef635a32f9e59427bb48676196
[profile/ivi/gsignond.git] / test / plugins / pluginproxytest.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of gsignond
5  *
6  * Copyright (C) 2012 Intel Corporation.
7  *
8  * Contact: Alexander Kanavin <alex.kanavin@gmail.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include <check.h>
27 #include <stdlib.h>
28 #include <glib-object.h>
29 #include <string.h>
30
31 #include "gsignond-plugin-proxy.h"
32 #include "gsignond-plugin-proxy-factory.h"
33 #include "gsignond-plugin-remote.h"
34 #include "gsignond/gsignond-error.h"
35 #include "gsignond/gsignond-log.h"
36 #include "common/gsignond-plugin-loader.h"
37
38 static GMainLoop *main_loop = NULL;
39
40 static void
41 _stop_mainloop ()
42 {
43     if (main_loop) {
44         g_main_loop_quit (main_loop);
45     }
46 }
47
48 static void
49 _run_mainloop ()
50 {
51     g_main_loop_run (main_loop);
52 }
53
54
55 static void
56 _setup ()
57 {
58 #if !GLIB_CHECK_VERSION (2, 36, 0)
59     g_type_init ();
60 #endif
61     if (main_loop == NULL) {
62         main_loop = g_main_loop_new (NULL, FALSE);
63     }
64 }
65
66 static void
67 _teardown ()
68 {
69     if (main_loop) {
70         _stop_mainloop ();
71         g_main_loop_unref (main_loop);
72         main_loop = NULL;
73     }
74 }
75
76 struct _GSignondAuthSession
77 {
78     GObject parent;
79
80 };
81
82 struct _GSignondAuthSessionClass
83 {
84     GObjectClass parent_class;
85 };
86
87 G_DEFINE_TYPE (GSignondAuthSession, gsignond_auth_session, G_TYPE_OBJECT);
88
89 static void
90 gsignond_auth_session_init (
91         GSignondAuthSession *self)
92 {
93 }
94
95 static void
96 gsignond_auth_session_class_init (
97         GSignondAuthSessionClass *klass)
98 {
99 //    GObjectClass *object_class = G_OBJECT_CLASS (klass);
100 }
101
102 gboolean testing_proxy_process = FALSE;
103 gboolean testing_proxy_process_cancel = FALSE;
104 gboolean testing_proxy_process_queue = FALSE;
105 gint proxy_process_queue_results = 0;
106 gboolean testing_proxy_process_queue_cancel = FALSE;
107 gint proxy_process_queue_cancel_results = 0;
108 gboolean testing_proxy_process_cancel_triggered = FALSE;
109
110 void
111 gsignond_auth_session_notify_process_result (
112         GSignondAuthSession *iface,
113         GSignondSessionData *result,
114         gpointer user_data)
115 {
116     int i;
117
118     DBG ("");
119
120     if (testing_proxy_process) {
121         testing_proxy_process = FALSE;
122         fail_if(g_strcmp0(
123             gsignond_session_data_get_username(result), "megauser") != 0);
124         fail_if(g_strcmp0(
125             gsignond_session_data_get_secret(result), "megapassword") != 0);
126         _stop_mainloop ();
127
128     } else if (testing_proxy_process_queue) {
129         proxy_process_queue_results++;
130         if (proxy_process_queue_results == 1) {
131             GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
132             GSignondSessionData* data = gsignond_dictionary_new();
133             fail_if(data == NULL);
134             gsignond_session_data_set_username(data, "megauser");
135             gsignond_session_data_set_secret(data, "megapassword");
136
137             gsignond_plugin_proxy_process(proxy, iface, data, NULL, "password",
138                     proxy);
139
140             gsignond_plugin_proxy_process(proxy, iface, data, NULL, "password",
141                     proxy);
142     
143             gsignond_dictionary_unref(data);
144         }
145         if (proxy_process_queue_results == 3) {
146             testing_proxy_process_queue = FALSE;
147             _stop_mainloop ();
148         }
149     } else if (testing_proxy_process_queue_cancel) {
150         proxy_process_queue_cancel_results++;
151         if (proxy_process_queue_cancel_results == 1) {
152             GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
153             GSignondSessionData* data = gsignond_dictionary_new();
154             fail_if(data == NULL);
155
156             for (i = 0; i < 9; i++) {
157                 gsignond_plugin_proxy_process(proxy, iface, data, NULL, "mech1",
158                         proxy);
159             }
160             gsignond_dictionary_unref(data);
161         }
162         if (proxy_process_queue_cancel_results == 10) {
163             testing_proxy_process_queue_cancel = FALSE;
164             _stop_mainloop ();
165         }
166     } else 
167         fail_if(TRUE);    
168 }
169
170 void
171 gsignond_auth_session_notify_process_error (
172         GSignondAuthSession *iface,
173         const GError *error,
174         gpointer user_data)
175 {
176     DBG ("");
177
178     if (testing_proxy_process_cancel) {
179         fail_if(error->code != GSIGNOND_ERROR_SESSION_CANCELED);
180         testing_proxy_process_cancel = FALSE;
181         _stop_mainloop ();
182     } else if (testing_proxy_process_queue_cancel) {
183         fail_if(error->code != GSIGNOND_ERROR_SESSION_CANCELED);
184         proxy_process_queue_cancel_results++;
185     }
186
187 }
188
189 void 
190 gsignond_auth_session_notify_store (
191         GSignondAuthSession *self,
192         GSignondSessionData *session_data)
193 {
194     DBG ("");
195     fail_if(TRUE);
196 }
197
198 void 
199 gsignond_auth_session_notify_user_action_required (
200         GSignondAuthSession *self,
201         GSignondSignonuiData *session_data)
202 {
203     DBG ("");
204     fail_if(TRUE);
205 }
206
207 void 
208 gsignond_auth_session_notify_refreshed (
209         GSignondAuthSession *self,
210         GSignondSignonuiData *session_data)
211 {
212     DBG ("");
213     fail_if(TRUE);
214 }
215
216 void 
217 gsignond_auth_session_notify_state_changed (
218         GSignondAuthSession *self,
219         gint state,
220         const gchar *message,
221         gpointer user_data)
222 {
223     if (testing_proxy_process_cancel &&
224             !testing_proxy_process_cancel_triggered &&
225             state == GSIGNOND_PLUGIN_STATE_WAITING) {
226         GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
227         gsignond_plugin_proxy_cancel(proxy, self);
228         testing_proxy_process_cancel_triggered = TRUE;
229     } else if (testing_proxy_process_queue_cancel &&
230             state == GSIGNOND_PLUGIN_STATE_WAITING &&
231             proxy_process_queue_cancel_results == 5) {
232         GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
233         gsignond_plugin_proxy_cancel(proxy, self);
234     }
235 }
236
237 static void
238 check_plugin_proxy(
239         GSignondPluginProxy* proxy,
240         gchar *type,
241         gchar **mechanisms)
242 {
243     gchar* ptype = NULL;
244     gchar** pmechanisms = NULL;
245     gint i = 0;
246
247     fail_if(proxy == NULL);
248
249     g_object_get(proxy, "type", &ptype, "mechanisms", &pmechanisms, NULL);
250     fail_unless(g_strcmp0(ptype, type) == 0);
251     g_free(ptype);
252
253     guint len = g_strv_length (pmechanisms);
254     fail_unless (len == g_strv_length (mechanisms));
255
256     for (i=0; i<len; i++) {
257         fail_unless(g_strcmp0(pmechanisms[i], mechanisms[i]) == 0);
258     }
259     if (pmechanisms) {
260         g_strfreev(pmechanisms);
261     }
262 }
263
264 START_TEST (test_pluginproxy_create)
265 {
266     DBG("test_pluginproxy_create\n");
267
268     gchar *pass_mechs[] = {"password", NULL};
269
270     GSignondConfig* config = gsignond_config_new();
271     fail_if(config == NULL);
272
273     GSignondPluginProxy* proxy2 = gsignond_plugin_proxy_new(config,
274             "absentplugin");
275     fail_if (proxy2 != NULL);
276
277     GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
278     fail_if (proxy == NULL);
279     check_plugin_proxy(proxy, "password", pass_mechs);
280
281     g_object_unref(proxy);
282     g_object_unref(config);
283 }
284 END_TEST
285
286 START_TEST (test_pluginproxy_process)
287 {
288     DBG("test_pluginproxy_process\n");
289
290     GSignondConfig* config = gsignond_config_new();
291     fail_if(config == NULL);
292     
293     GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
294     fail_if (proxy == NULL);
295     
296     GSignondSessionData* data = gsignond_dictionary_new();
297     fail_if(data == NULL);
298     gsignond_session_data_set_username(data, "megauser");
299     gsignond_session_data_set_secret(data, "megapassword");
300     
301     GSignondAuthSession* test_auth_session =
302             g_object_new(gsignond_auth_session_get_type(), NULL);
303
304     testing_proxy_process = TRUE;
305
306     gsignond_plugin_proxy_process(proxy, test_auth_session, data, NULL, "password",
307             proxy);
308
309     _run_mainloop ();
310
311     fail_if(testing_proxy_process);
312     
313     gsignond_dictionary_unref(data);
314     g_object_unref(test_auth_session);
315     g_object_unref(proxy);
316     g_object_unref(config);
317 }
318 END_TEST
319
320 START_TEST (test_pluginproxy_process_cancel)
321 {
322     DBG("test_pluginproxy_process_cancel\n");
323
324     GSignondConfig* config = gsignond_config_new();
325     fail_if(config == NULL);
326     
327     GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "ssotest");
328     fail_if (proxy == NULL);
329     
330     GSignondSessionData* data = gsignond_dictionary_new();
331     fail_if(data == NULL);
332
333     GSignondAuthSession* test_auth_session = g_object_new(
334             gsignond_auth_session_get_type(), NULL);
335     
336     testing_proxy_process_cancel = TRUE;
337     
338     gsignond_plugin_proxy_process(proxy, test_auth_session, data, NULL, "mech1",
339             proxy);
340
341     _run_mainloop ();
342
343     fail_if(testing_proxy_process_cancel);
344     
345     gsignond_dictionary_unref(data);
346     g_object_unref(test_auth_session);
347     g_object_unref(proxy);
348     g_object_unref(config);
349 }
350 END_TEST
351
352 START_TEST (test_pluginproxy_process_queue)
353 {
354     DBG("test_pluginproxy_process_queue\n");
355
356     GSignondConfig* config = gsignond_config_new();
357     fail_if(config == NULL);
358     
359     GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
360     fail_if (proxy == NULL);
361     
362     GSignondSessionData* data = gsignond_dictionary_new();
363     fail_if(data == NULL);
364     gsignond_session_data_set_username(data, "megauser");
365     gsignond_session_data_set_secret(data, "megapassword");
366
367     GSignondAuthSession* test_auth_session = g_object_new(
368             gsignond_auth_session_get_type(), NULL);
369     
370     testing_proxy_process_queue = TRUE;
371     
372     gsignond_plugin_proxy_process(proxy, test_auth_session, data, NULL, "password",
373             proxy);
374     _run_mainloop ();
375
376     fail_if(testing_proxy_process_queue);
377     fail_if(proxy_process_queue_results < 3);
378
379     gsignond_dictionary_unref(data);
380     g_object_unref(test_auth_session);
381     g_object_unref(proxy);
382     g_object_unref(config);
383 }
384 END_TEST
385
386 START_TEST (test_pluginproxy_process_queue_cancel)
387 {
388     GSignondConfig* config = gsignond_config_new();
389     fail_if(config == NULL);
390     
391     GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "ssotest");
392     fail_if (proxy == NULL);
393     
394     GSignondSessionData* data = gsignond_dictionary_new();
395     fail_if(data == NULL);
396
397     GSignondAuthSession* test_auth_session = g_object_new(
398             gsignond_auth_session_get_type(), NULL);
399     
400     testing_proxy_process_queue_cancel = TRUE;
401     
402     gsignond_plugin_proxy_process(proxy, test_auth_session, data, NULL, "mech1",
403             proxy);
404
405     _run_mainloop ();
406
407     fail_if(testing_proxy_process_queue_cancel);
408     fail_if(proxy_process_queue_cancel_results != 10);
409
410     gsignond_dictionary_unref(data);
411     g_object_unref(test_auth_session);
412     g_object_unref(proxy);
413     g_object_unref(config);
414 }
415 END_TEST
416
417 START_TEST (test_pluginproxyfactory_methods_and_mechanisms)
418 {
419     DBG("");
420     GSignondConfig* config = gsignond_config_new();
421     fail_if(config == NULL);
422     
423     GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(
424             config);
425     fail_if(factory == NULL);
426     const gchar *pass_method = NULL;
427     const gchar** pmethods = NULL;
428     
429     const gchar** methods = gsignond_plugin_proxy_factory_get_plugin_types(
430             factory);
431     fail_if(methods == NULL);
432     pmethods = methods;
433     while (pmethods[0] != NULL) {
434         DBG ("Method %s", pmethods[0]);
435         if (g_strcmp0 (pmethods[0], "password") == 0) {
436             pass_method = pmethods[0];
437         }
438         pmethods++;
439     }
440     const gchar** mechanisms =
441             gsignond_plugin_proxy_factory_get_plugin_mechanisms(factory,
442                     pass_method);
443     fail_if(mechanisms == NULL);
444     fail_if(strcmp(mechanisms[0], "password") != 0);
445     fail_if(mechanisms[1] != NULL);
446     
447     g_object_unref(factory);
448     g_object_unref(config);
449 }
450 END_TEST
451
452 START_TEST (test_pluginproxyfactory_get)
453 {
454     DBG("");
455     gchar *pass_mechs[] = {"password", NULL};
456     GSignondConfig* config = gsignond_config_new();
457     fail_if(config == NULL);
458     
459     GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(
460             config);
461     fail_if(factory == NULL);
462     
463     fail_if(gsignond_plugin_proxy_factory_get_plugin(factory, "absentplugin")
464             != NULL);
465
466     GSignondPluginProxy* proxy1 = gsignond_plugin_proxy_factory_get_plugin(
467         factory, "password");
468     GSignondPluginProxy* proxy2 = gsignond_plugin_proxy_factory_get_plugin(
469         factory, "password");
470     GSignondPluginProxy* proxy3 = gsignond_plugin_proxy_factory_get_plugin(
471         factory, "password");
472     fail_if(proxy1 == NULL || proxy2 == NULL || proxy3 == NULL);
473     fail_if(proxy1 != proxy3 || proxy1 != proxy2);
474     check_plugin_proxy(proxy1, "password", pass_mechs);
475
476     g_object_unref(proxy1);
477     g_object_unref(proxy2);
478     g_object_unref(proxy3);    
479     
480     g_object_unref(factory);
481     g_object_unref(config);
482 }
483 END_TEST
484
485 START_TEST (test_pluginproxyfactory_add)
486 {
487     DBG("");
488     GSignondConfig* config = gsignond_config_new();
489     fail_if(config == NULL);
490     
491     GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(
492             config);
493     fail_if(factory == NULL);
494
495     GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
496     fail_if (proxy == NULL);
497     fail_if(gsignond_plugin_proxy_factory_add_plugin(factory, proxy) == FALSE);
498     fail_if(gsignond_plugin_proxy_factory_add_plugin(factory, proxy) == TRUE);
499     fail_if(gsignond_plugin_proxy_factory_get_plugin(factory, "password")
500             != proxy);
501     g_object_unref(proxy);
502     
503     g_object_unref(proxy);
504     g_object_unref(factory);
505     g_object_unref(config);
506 }
507 END_TEST
508
509 typedef struct {
510     GSignondPluginProxyFactory *factory;
511     GSignondPluginProxy *proxy;
512 } ProxyTimeoutData;
513
514 static gboolean
515 _validate_new_proxy(gpointer userdata)
516 {
517     ProxyTimeoutData *data = (ProxyTimeoutData *)userdata;
518     fail_if (data == NULL);
519
520     GSignondPluginProxy *proxy = gsignond_plugin_proxy_factory_get_plugin (data->factory, "ssotest");
521     fail_if (proxy == NULL);
522
523     fail_if (proxy == data->proxy, "expected new proxy object, but got cached object");
524     g_object_unref(proxy);
525
526     g_free (userdata);
527
528     _stop_mainloop();
529
530     return FALSE;
531 }
532
533 static gboolean
534 _validate_cached_proxy (gpointer userdata)
535 {
536     ProxyTimeoutData *data = (ProxyTimeoutData *)userdata;
537     fail_if (data == NULL);
538     
539     GSignondPluginProxy *proxy = gsignond_plugin_proxy_factory_get_plugin (data->factory, "ssotest");
540     fail_if (proxy == NULL);
541
542     fail_unless (proxy == data->proxy, "expected cached proxy object, but got new object");
543
544     g_object_unref (proxy);
545
546     g_timeout_add (2200, _validate_new_proxy, userdata);
547
548     return FALSE;
549 }
550
551 START_TEST (test_pluginproxyfactory_proxy_timeout)
552 {
553     DBG("test_pluginproxyfactory_proxy_timeout\n");
554     GSignondPluginProxyFactory *factory = NULL;
555     GSignondPluginProxy *proxy1 = NULL, *proxy2 = NULL;
556     GSignondConfig *config = NULL;
557
558     /* CASE 1: proxy timeout disabled */
559     g_setenv ("SSO_PLUGIN_TIMEOUT", "0", TRUE);
560   
561     config = gsignond_config_new();
562     fail_if(config == NULL);
563
564     factory = gsignond_plugin_proxy_factory_new ( config);
565     fail_if (factory == NULL);
566
567     proxy1 = gsignond_plugin_proxy_factory_get_plugin (factory, "ssotest");
568     fail_if (proxy1 == NULL);
569     g_object_unref (proxy1);
570
571     proxy2 = gsignond_plugin_proxy_factory_get_plugin (factory, "ssotest");
572     fail_if (proxy2 == NULL);
573
574     fail_unless (proxy1 == proxy2, "got new plugin proxy object, "
575                                    "where expected cached object(%p,%p)",
576                                     proxy1, proxy2);
577     g_object_unref (proxy2);
578
579     g_object_unref (config);
580     g_object_unref (factory);
581
582     /* CASE 2: proxy timeout enbled */ 
583     g_setenv ("SSO_PLUGIN_TIMEOUT", "1", TRUE);
584
585     config = gsignond_config_new();
586     fail_if(config == NULL);
587
588     factory = gsignond_plugin_proxy_factory_new (config);
589     fail_if (factory == NULL);
590
591     proxy1 = gsignond_plugin_proxy_factory_get_plugin (factory, "ssotest");
592     fail_if (proxy1 == NULL);
593     g_object_unref (proxy1);
594
595     ProxyTimeoutData *data = g_new0(ProxyTimeoutData, 1);
596     data->factory = factory;
597     data->proxy = proxy1;
598     g_timeout_add_seconds (2, _validate_new_proxy, (gpointer)data);
599
600     _run_mainloop ();
601
602     g_object_unref(config);
603     g_object_unref(factory);
604
605     /* CASE 3: proxy timeout enable - request recently closed plugin */
606     g_setenv ("SSO_PLUGIN_TIMEOUT", "2", TRUE);
607     config = gsignond_config_new ();
608     fail_if (config == NULL);
609
610     factory = gsignond_plugin_proxy_factory_new(config);
611     fail_if (factory == NULL);
612
613     proxy1 = gsignond_plugin_proxy_factory_get_plugin(factory, "ssotest");
614     fail_if (proxy1 == NULL);
615     g_object_unref (proxy1);
616
617     ProxyTimeoutData *data1 = g_new0(ProxyTimeoutData, 1);
618     data1->factory = factory;
619     data1->proxy = proxy1;
620
621     g_timeout_add_seconds (1, _validate_cached_proxy, (gpointer)data1);
622
623     _run_mainloop();
624
625     g_object_unref(config);
626     g_object_unref(factory);
627 }
628 END_TEST
629
630 Suite* pluginproxy_suite (void)
631 {
632     Suite *s = suite_create ("Plugin proxy");
633     
634     /* Core test case */
635     TCase *tc_core = tcase_create ("Tests");
636     tcase_add_checked_fixture (tc_core, _setup, _teardown);
637
638     tcase_set_timeout (tc_core, 10);
639     tcase_add_test (tc_core, test_pluginproxy_create);
640     tcase_add_test (tc_core, test_pluginproxy_process);
641     tcase_add_test (tc_core, test_pluginproxy_process_cancel);
642     tcase_add_test (tc_core, test_pluginproxy_process_queue);
643     tcase_add_test (tc_core, test_pluginproxy_process_queue_cancel);
644     tcase_add_test (tc_core, test_pluginproxyfactory_methods_and_mechanisms);
645     tcase_add_test (tc_core, test_pluginproxyfactory_get);
646     tcase_add_test (tc_core, test_pluginproxyfactory_add);
647     tcase_add_test (tc_core, test_pluginproxyfactory_proxy_timeout);
648
649     suite_add_tcase (s, tc_core);
650     return s;
651 }
652
653 int main (void)
654 {
655     int number_failed;
656     
657     Suite *s = pluginproxy_suite();
658     SRunner *sr = srunner_create(s);
659     srunner_run_all(sr, CK_NORMAL);
660     number_failed = srunner_ntests_failed(sr);
661     srunner_free(sr);
662     return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
663 }
664   
665