Update to upstream 1.0.1
[profile/ivi/gsignond.git] / test / plugins / pluginremotetest.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 <errno.h>
29
30 #include "daemon/gsignond-types.h"
31 #include "gsignond-plugin-remote-private.h"
32 #include "gsignond-plugin-remote.h"
33 #include "gplugind/gsignond-plugin-daemon.h"
34 #include <gsignond/gsignond-plugin-interface.h>
35 #include <gsignond/gsignond-error.h>
36 #include <gsignond/gsignond-config.h>
37 #include <gsignond/gsignond-log.h>
38
39 static GMainLoop *main_loop = NULL;
40 guint child_watch_id = 0;
41
42 struct _GSignondAuthSession
43 {
44     GObject parent;
45 };
46
47 struct _GSignondAuthSessionClass
48 {
49     GObjectClass parent_class;
50 };
51
52 G_DEFINE_TYPE (GSignondAuthSession, gsignond_auth_session, G_TYPE_OBJECT);
53
54 static void
55 _stop_mainloop ()
56 {
57     if (main_loop) {
58         g_main_loop_quit (main_loop);
59     }
60 }
61
62 static void
63 _run_mainloop ()
64 {
65     g_main_loop_run (main_loop);
66 }
67
68 static void
69 _setup ()
70 {
71 #if !GLIB_CHECK_VERSION (2, 36, 0)
72     g_type_init ();
73 #endif
74
75     if (main_loop == NULL) {
76         main_loop = g_main_loop_new (NULL, FALSE);
77     }
78 }
79
80 static void
81 _teardown ()
82 {
83     if (main_loop) {
84         _stop_mainloop ();
85         g_main_loop_unref (main_loop);
86         main_loop = NULL;
87     }
88 }
89
90 static gboolean
91 _timeout_quit_loop (gpointer data)
92 {
93     _stop_mainloop ();
94     return FALSE;
95 }
96
97 static void
98 _run_loop_with_timeout (guint timeout)
99 {
100     g_timeout_add_seconds (timeout, _timeout_quit_loop, NULL);
101     _run_mainloop ();
102 }
103
104 static void
105 gsignond_auth_session_init (
106         GSignondAuthSession *self)
107 {
108 }
109
110 static void
111 gsignond_auth_session_class_init (
112         GSignondAuthSessionClass *klass)
113 {
114 }
115
116 void
117 gsignond_auth_session_notify_process_result (
118         GSignondAuthSession *iface,
119         GSignondSessionData *result,
120         gpointer user_data)
121 {
122 }
123
124 void
125 gsignond_auth_session_notify_process_error (
126         GSignondAuthSession *iface,
127         const GError *error,
128         gpointer user_data)
129 {
130 }
131
132 void
133 gsignond_auth_session_notify_store (
134         GSignondAuthSession *self,
135         GSignondSessionData *session_data)
136 {
137 }
138
139 void
140 gsignond_auth_session_notify_user_action_required (
141         GSignondAuthSession *self,
142         GSignondSignonuiData *session_data)
143 {
144 }
145
146 void
147 gsignond_auth_session_notify_refreshed (
148         GSignondAuthSession *self,
149         GSignondSignonuiData *session_data)
150 {
151 }
152
153 void
154 gsignond_auth_session_notify_state_changed (
155         GSignondAuthSession *self,
156         gint state,
157         const gchar *message,
158         gpointer user_data)
159 {
160 }
161
162 static void
163 check_plugin(
164         GSignondPlugin* plugin)
165 {
166     gchar* type;
167     gchar** mechanisms;
168
169     fail_if(plugin == NULL);
170     
171     g_object_get(plugin, "type", &type, "mechanisms", &mechanisms, NULL);
172     
173     fail_unless(g_strcmp0(type, "password") == 0);
174     fail_unless(g_strcmp0(mechanisms[0], "password") == 0);
175     fail_unless(mechanisms[1] == NULL);
176     
177     g_free(type);
178     g_strfreev(mechanisms);
179 }
180
181 static void
182 response_callback(
183         GSignondPlugin* plugin,
184         GSignondSessionData* result,
185         gpointer user_data)
186 {
187     DBG ("");
188     GSignondSessionData** user_data_p = user_data;
189     *user_data_p = gsignond_dictionary_copy(result);
190     _stop_mainloop ();
191 }
192
193 static void
194 user_action_required_callback(
195         GSignondPlugin* plugin,
196         GSignondSignonuiData* ui_request,
197         gpointer user_data)
198 {
199     DBG ("");
200     GSignondSignonuiData** user_data_p = user_data;
201     *user_data_p = gsignond_dictionary_copy(ui_request);
202     _stop_mainloop ();
203 }
204
205 static void
206 error_callback(
207         GSignondPlugin* plugin,
208         GError* error,
209         gpointer user_data)
210 {
211     DBG ("");
212     GError** user_data_p = user_data;
213     *user_data_p = g_error_copy(error);
214     _stop_mainloop ();
215 }
216
217 START_TEST (test_pluginremote_create)
218 {
219     DBG ("");
220     GSignondPlugin *plugin = NULL;
221     const gchar *plugin_type = "password";
222
223     GSignondConfig* config = gsignond_config_new ();
224     fail_if (config == NULL);
225
226     gchar* loader_path = g_build_filename (g_getenv("SSO_BIN_DIR"), "gsignond-plugind", NULL);
227     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(loader_path, plugin_type));
228     g_free(loader_path);
229     g_object_unref (config);
230
231     check_plugin (plugin);
232     g_object_unref (plugin);
233 }
234 END_TEST
235
236 START_TEST (test_pluginremote_plugind_create)
237 {
238     DBG ("");
239     GSignondPlugin *plugin = NULL;
240     const gchar *plugin_type = "password";
241     GSignondPluginRemotePrivate* priv = NULL;
242
243     GSignondConfig* config = gsignond_config_new ();
244     fail_if (config == NULL);
245
246     gchar* loader_path = g_build_filename (g_getenv("SSO_BIN_DIR"), "gsignond-plugind", NULL);
247     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(loader_path, plugin_type));
248     g_free(loader_path);
249     g_object_unref (config);
250
251     fail_if (plugin == NULL);
252     priv = (GSignondPluginRemotePrivate *)GSIGNOND_PLUGIN_REMOTE (plugin)->priv;
253
254     fail_unless (priv->cpid > 0);
255     fail_unless (kill (priv->cpid, 0) == 0);
256
257     check_plugin (plugin);
258
259     g_object_unref (plugin);
260 }
261 END_TEST
262
263 START_TEST (test_pluginremote_plugind_unref)
264 {
265     DBG ("");
266     GSignondPlugin *plugin = NULL;
267     const gchar *plugin_type = "password";
268     GSignondPluginRemotePrivate* priv = NULL;
269     gint cpid = 0;
270
271     GSignondConfig* config = gsignond_config_new ();
272     fail_if (config == NULL);
273
274     gchar* loader_path = g_build_filename (g_getenv("SSO_BIN_DIR"), "gsignond-plugind", NULL);
275     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(loader_path, plugin_type));
276     g_free(loader_path);
277     fail_if (plugin == NULL);
278     priv = (GSignondPluginRemotePrivate *)GSIGNOND_PLUGIN_REMOTE (plugin)->priv;
279
280     fail_unless (priv->cpid > 0);
281     fail_unless (kill (priv->cpid, 0) == 0);
282     cpid = priv->cpid;
283
284     g_object_unref (plugin);
285     g_object_unref (config);
286
287     fail_unless (kill (cpid, 0) != 0);
288 }
289 END_TEST
290
291 START_TEST (test_pluginremote_plugind_kill)
292 {
293     DBG ("");
294     GSignondPlugin *plugin = NULL;
295     const gchar *plugin_type = "password";
296     GSignondPluginRemotePrivate* priv = NULL;
297     gint cpid = 0;
298
299     GSignondConfig* config = gsignond_config_new ();
300     fail_if (config == NULL);
301
302     gchar* loader_path = g_build_filename (g_getenv("SSO_BIN_DIR"), "gsignond-plugind", NULL);
303     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(loader_path, plugin_type));
304     g_free(loader_path);
305     fail_if (plugin == NULL);
306     priv = (GSignondPluginRemotePrivate *)GSIGNOND_PLUGIN_REMOTE (plugin)->priv;
307
308     fail_unless (priv->cpid > 0);
309     fail_unless (kill (priv->cpid, 0) == 0);
310     cpid = priv->cpid;
311     check_plugin (plugin);
312
313     kill (priv->cpid, SIGTERM);
314
315     _run_loop_with_timeout (1);
316
317     fail_unless (kill (cpid, 0) != 0);
318
319     g_object_unref (plugin);
320     g_object_unref (config);
321 }
322 END_TEST
323
324 START_TEST (test_pluginremote_request)
325 {
326     DBG ("");
327     GSignondPlugin *plugin = NULL;
328     const gchar *plugin_type = "password";
329
330     GSignondConfig* config = gsignond_config_new ();
331     fail_if(config == NULL);
332     
333     gchar* loader_path = g_build_filename (g_getenv("SSO_BIN_DIR"), "gsignond-plugind", NULL);
334     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(loader_path, plugin_type));
335     g_free(loader_path);
336     fail_if(plugin == NULL);
337
338     GSignondSessionData* result = NULL;
339     GSignondSignonuiData* ui_action = NULL;
340     GError* error = NULL;
341     gboolean bool_res;
342
343     g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback),
344             &result);
345     g_signal_connect(plugin, "user-action-required", 
346                      G_CALLBACK(user_action_required_callback), &ui_action);
347     g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
348
349     GSignondSessionData* data = gsignond_dictionary_new ();
350
351     // username empty, password not empty
352     gsignond_session_data_set_secret(data, "megapassword");
353     gsignond_plugin_request_initial(plugin, data, NULL, "password");
354     _run_mainloop ();
355
356     fail_if(result == NULL);    
357     fail_if(ui_action != NULL);
358     fail_if(error != NULL);
359     fail_if(gsignond_session_data_get_username(result) != NULL);
360     fail_if(g_strcmp0(
361         gsignond_session_data_get_secret(result), "megapassword") != 0);
362     gsignond_dictionary_unref(result);
363     result = NULL;
364     
365     // username and password not empty
366     gsignond_session_data_set_username(data, "megauser");
367     gsignond_plugin_request_initial(plugin, data, NULL, "password");
368     _run_mainloop ();
369
370     fail_if(result == NULL);    
371     fail_if(ui_action != NULL);
372     fail_if(error != NULL);
373     fail_if(g_strcmp0(
374         gsignond_session_data_get_username(result), "megauser") != 0);
375     fail_if(g_strcmp0(
376         gsignond_session_data_get_secret(result), "megapassword") != 0);
377     gsignond_dictionary_unref(result);
378     result = NULL;
379     
380     //username and password empty
381     gsignond_dictionary_unref(data);
382     data = gsignond_dictionary_new();
383     gsignond_plugin_request_initial(plugin, data, NULL, "password");
384     _run_mainloop ();
385
386     fail_if(result != NULL);    
387     fail_if(ui_action == NULL);
388     fail_if(error != NULL);
389     fail_if(gsignond_signonui_data_get_query_username(ui_action, &bool_res)
390             == FALSE);
391     fail_if(bool_res == FALSE);
392     fail_if(gsignond_signonui_data_get_query_password(ui_action, &bool_res)
393             == FALSE);
394     fail_if(bool_res == FALSE);    
395     gsignond_dictionary_unref(ui_action);
396     ui_action = NULL;
397     
398     //username not empty, password empty
399     gsignond_session_data_set_username(data, "megauser");
400     gsignond_plugin_request_initial(plugin, data, NULL, "password");
401     _run_mainloop ();
402
403     fail_if(result != NULL);    
404     fail_if(ui_action == NULL);
405     fail_if(error != NULL);
406     fail_if(gsignond_signonui_data_get_query_username(ui_action, &bool_res)
407             == FALSE);
408     fail_if(bool_res == TRUE);
409     fail_if(gsignond_signonui_data_get_query_password(ui_action, &bool_res)
410             == FALSE);
411     fail_if(bool_res == FALSE);    
412     gsignond_dictionary_unref(ui_action);
413     ui_action = NULL;
414     
415     gsignond_dictionary_unref(data);
416
417     g_object_unref(config);
418     g_object_unref(plugin);
419 }
420 END_TEST
421
422 START_TEST (test_pluginremote_user_action_finished)
423 {
424     DBG ("");
425     GSignondPlugin *plugin = NULL;
426     const gchar *plugin_type = "password";
427
428     GSignondConfig* config = gsignond_config_new ();
429     fail_if(config == NULL);
430     
431     gchar* loader_path = g_build_filename (g_getenv("SSO_BIN_DIR"), "gsignond-plugind", NULL);
432     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(loader_path, plugin_type));
433     g_free(loader_path);
434     fail_if(plugin == NULL);
435
436     GSignondSessionData* result = NULL;
437     GSignondSignonuiData* ui_action = NULL;
438     GError* error = NULL;
439
440     g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback),
441             &result);
442     g_signal_connect(plugin, "user-action-required", 
443                      G_CALLBACK(user_action_required_callback), &ui_action);
444     g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
445
446     GSignondSignonuiData* data = gsignond_dictionary_new();
447     
448     //empty data
449     gsignond_plugin_user_action_finished(plugin, data);
450     _run_mainloop ();
451
452     fail_if(result != NULL);    
453     fail_if(ui_action != NULL);
454     fail_if(error == NULL);
455     fail_unless (error->code == GSIGNOND_ERROR_USER_INTERACTION);
456     g_error_free(error);
457     error = NULL;
458     
459     // correct values
460     gsignond_signonui_data_set_username(data, "megauser");
461     gsignond_signonui_data_set_password(data, "megapassword");
462     gsignond_signonui_data_set_query_error(data, SIGNONUI_ERROR_NONE);
463     gsignond_plugin_user_action_finished(plugin, data);
464     _run_mainloop ();
465
466     fail_if(result == NULL);    
467     fail_if(ui_action != NULL);
468     fail_if(error != NULL);
469     fail_if(g_strcmp0(
470         gsignond_session_data_get_username(result), "megauser") != 0);
471     fail_if(g_strcmp0(
472         gsignond_session_data_get_secret(result), "megapassword") != 0);
473     gsignond_dictionary_unref(result);
474     result = NULL;
475
476     // user canceled
477     gsignond_signonui_data_set_query_error(data, SIGNONUI_ERROR_CANCELED);
478     gsignond_plugin_user_action_finished(plugin, data);
479     _run_mainloop ();
480
481     fail_if(result != NULL);    
482     fail_if(ui_action != NULL);
483     fail_if(error == NULL);
484     fail_unless (error->code == GSIGNOND_ERROR_SESSION_CANCELED);
485     g_error_free(error);
486     error = NULL;
487
488     // error in ui request
489     gsignond_signonui_data_set_query_error(data, SIGNONUI_ERROR_GENERAL);
490     gsignond_plugin_user_action_finished(plugin, data);
491     _run_mainloop ();
492
493     fail_if(result != NULL);    
494     fail_if(ui_action != NULL);
495     fail_if(error == NULL);
496     fail_unless (error->code == GSIGNOND_ERROR_USER_INTERACTION);
497     g_error_free(error);
498     error = NULL;
499     
500     gsignond_dictionary_unref(data);
501
502     g_object_unref(config);
503     g_object_unref(plugin);
504 }
505 END_TEST
506
507 START_TEST (test_pluginremote_refresh)
508 {
509     DBG ("");
510     GSignondPlugin *plugin = NULL;
511     const gchar *plugin_type = "password";
512
513     GSignondConfig* config = gsignond_config_new ();
514     fail_if(config == NULL);
515     
516     gchar* loader_path = g_build_filename (g_getenv("SSO_BIN_DIR"), "gsignond-plugind", NULL);
517     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(loader_path, plugin_type));
518     g_free(loader_path);
519     fail_if(plugin == NULL);
520
521     GSignondSessionData* result = NULL;
522     GError* error = NULL;
523
524     g_signal_connect(plugin, "refreshed", G_CALLBACK(response_callback),
525             &result);
526     g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
527
528     GSignondSessionData* data = gsignond_dictionary_new();
529     gsignond_plugin_refresh(plugin, data);
530     _run_mainloop ();
531
532     fail_if(result == NULL);    
533     fail_if(error != NULL);
534     gsignond_dictionary_unref(result);
535     result = NULL;
536     
537     gsignond_dictionary_unref(data);
538
539     g_object_unref(config);
540     g_object_unref(plugin);
541 }
542 END_TEST
543
544 START_TEST (test_plugind_daemon)
545 {
546     DBG ("");
547     GSignondPluginDaemon *daemon = NULL;
548     const gchar *plugin_type = "password";
549
550     const gchar *plugin_dir = g_getenv("SSO_GPLUGINS_DIR");
551     fail_if (plugin_dir == NULL);
552
553     gchar *plugin_path = g_module_build_path (plugin_dir, "nonexisting");
554     fail_if (plugin_path == NULL);
555     daemon = gsignond_plugin_daemon_new (plugin_path, "nonexisting", 0, 1);
556     g_free (plugin_path);
557     fail_if (daemon != NULL);
558
559     plugin_path = g_module_build_path (plugin_dir, plugin_type);
560     fail_if (plugin_path == NULL);
561     daemon = gsignond_plugin_daemon_new (plugin_path, plugin_type, 0, 1);
562     g_free (plugin_path);
563     fail_if (daemon == NULL);
564     g_object_unref (daemon);
565     daemon = NULL;
566 }
567 END_TEST
568
569 Suite* pluginremote_suite (void)
570 {
571     Suite *s = suite_create ("Plugin remote");
572     
573     /* Core test case */
574     TCase *tc_core = tcase_create ("RemoteTests");
575     tcase_add_checked_fixture (tc_core, _setup, _teardown);
576     tcase_add_test (tc_core, test_pluginremote_create);
577     tcase_add_test (tc_core, test_pluginremote_plugind_create);
578     tcase_add_test (tc_core, test_pluginremote_plugind_unref);
579     tcase_add_test (tc_core, test_pluginremote_plugind_kill);
580     tcase_add_test (tc_core, test_pluginremote_request);
581     tcase_add_test (tc_core, test_pluginremote_user_action_finished);
582     tcase_add_test (tc_core, test_pluginremote_refresh);
583     tcase_add_test (tc_core, test_plugind_daemon);
584
585     suite_add_tcase (s, tc_core);
586     return s;
587 }
588
589 int main (void)
590 {
591     int number_failed;
592     
593     Suite *s = pluginremote_suite();
594     SRunner *sr = srunner_create(s);
595     srunner_run_all(sr, CK_NORMAL);
596     number_failed = srunner_ntests_failed(sr);
597     srunner_free(sr);
598     return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
599 }
600