Release 0.0.3
[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 "plugind/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     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(config, plugin_type));
227     g_object_unref (config);
228
229     check_plugin (plugin);
230     g_object_unref (plugin);
231 }
232 END_TEST
233
234 START_TEST (test_pluginremote_plugind_create)
235 {
236     DBG ("");
237     GSignondPlugin *plugin = NULL;
238     const gchar *plugin_type = "password";
239     GSignondPluginRemotePrivate* priv = NULL;
240
241     GSignondConfig* config = gsignond_config_new ();
242     fail_if (config == NULL);
243
244     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(config, plugin_type));
245     g_object_unref (config);
246
247     fail_if (plugin == NULL);
248     priv = (GSignondPluginRemotePrivate *)GSIGNOND_PLUGIN_REMOTE (plugin)->priv;
249
250     fail_unless (priv->cpid > 0);
251     fail_unless (kill (priv->cpid, 0) == 0);
252
253     check_plugin (plugin);
254
255     g_object_unref (plugin);
256 }
257 END_TEST
258
259 START_TEST (test_pluginremote_plugind_unref)
260 {
261     DBG ("");
262     GSignondPlugin *plugin = NULL;
263     const gchar *plugin_type = "password";
264     GSignondPluginRemotePrivate* priv = NULL;
265     gint cpid = 0;
266
267     GSignondConfig* config = gsignond_config_new ();
268     fail_if (config == NULL);
269
270     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(config, plugin_type));
271     fail_if (plugin == NULL);
272     priv = (GSignondPluginRemotePrivate *)GSIGNOND_PLUGIN_REMOTE (plugin)->priv;
273
274     fail_unless (priv->cpid > 0);
275     fail_unless (kill (priv->cpid, 0) == 0);
276     cpid = priv->cpid;
277
278     g_object_unref (plugin);
279     g_object_unref (config);
280
281     fail_unless (kill (cpid, 0) != 0);
282 }
283 END_TEST
284
285 START_TEST (test_pluginremote_plugind_kill)
286 {
287     DBG ("");
288     GSignondPlugin *plugin = NULL;
289     const gchar *plugin_type = "password";
290     GSignondPluginRemotePrivate* priv = NULL;
291     gint cpid = 0;
292
293     GSignondConfig* config = gsignond_config_new ();
294     fail_if (config == NULL);
295
296     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(config, plugin_type));
297     fail_if (plugin == NULL);
298     priv = (GSignondPluginRemotePrivate *)GSIGNOND_PLUGIN_REMOTE (plugin)->priv;
299
300     fail_unless (priv->cpid > 0);
301     fail_unless (kill (priv->cpid, 0) == 0);
302     cpid = priv->cpid;
303     check_plugin (plugin);
304
305     kill (priv->cpid, SIGTERM);
306
307     _run_loop_with_timeout (1);
308
309     fail_unless (kill (cpid, 0) != 0);
310
311     g_object_unref (plugin);
312     g_object_unref (config);
313 }
314 END_TEST
315
316 START_TEST (test_pluginremote_request)
317 {
318     DBG ("");
319     GSignondPlugin *plugin = NULL;
320     const gchar *plugin_type = "password";
321
322     GSignondConfig* config = gsignond_config_new ();
323     fail_if(config == NULL);
324     
325     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(config, plugin_type));
326     fail_if(plugin == NULL);
327
328     GSignondSessionData* result = NULL;
329     GSignondSignonuiData* ui_action = NULL;
330     GError* error = NULL;
331     gboolean bool_res;
332
333     g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback),
334             &result);
335     g_signal_connect(plugin, "user-action-required", 
336                      G_CALLBACK(user_action_required_callback), &ui_action);
337     g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
338
339     GSignondSessionData* data = gsignond_dictionary_new ();
340
341     // username empty, password not empty
342     gsignond_session_data_set_secret(data, "megapassword");
343     gsignond_plugin_request_initial(plugin, data, NULL, "password");
344     _run_mainloop ();
345
346     fail_if(result == NULL);    
347     fail_if(ui_action != NULL);
348     fail_if(error != NULL);
349     fail_if(gsignond_session_data_get_username(result) != NULL);
350     fail_if(g_strcmp0(
351         gsignond_session_data_get_secret(result), "megapassword") != 0);
352     gsignond_dictionary_unref(result);
353     result = NULL;
354     
355     // username and password not empty
356     gsignond_session_data_set_username(data, "megauser");
357     gsignond_plugin_request_initial(plugin, data, NULL, "password");
358     _run_mainloop ();
359
360     fail_if(result == NULL);    
361     fail_if(ui_action != NULL);
362     fail_if(error != NULL);
363     fail_if(g_strcmp0(
364         gsignond_session_data_get_username(result), "megauser") != 0);
365     fail_if(g_strcmp0(
366         gsignond_session_data_get_secret(result), "megapassword") != 0);
367     gsignond_dictionary_unref(result);
368     result = NULL;
369     
370     //username and password empty
371     gsignond_dictionary_unref(data);
372     data = gsignond_dictionary_new();
373     gsignond_plugin_request_initial(plugin, data, NULL, "password");
374     _run_mainloop ();
375
376     fail_if(result != NULL);    
377     fail_if(ui_action == NULL);
378     fail_if(error != NULL);
379     fail_if(gsignond_signonui_data_get_query_username(ui_action, &bool_res)
380             == FALSE);
381     fail_if(bool_res == FALSE);
382     fail_if(gsignond_signonui_data_get_query_password(ui_action, &bool_res)
383             == FALSE);
384     fail_if(bool_res == FALSE);    
385     gsignond_dictionary_unref(ui_action);
386     ui_action = NULL;
387     
388     //username not empty, password empty
389     gsignond_session_data_set_username(data, "megauser");
390     gsignond_plugin_request_initial(plugin, data, NULL, "password");
391     _run_mainloop ();
392
393     fail_if(result != NULL);    
394     fail_if(ui_action == NULL);
395     fail_if(error != NULL);
396     fail_if(gsignond_signonui_data_get_query_username(ui_action, &bool_res)
397             == FALSE);
398     fail_if(bool_res == TRUE);
399     fail_if(gsignond_signonui_data_get_query_password(ui_action, &bool_res)
400             == FALSE);
401     fail_if(bool_res == FALSE);    
402     gsignond_dictionary_unref(ui_action);
403     ui_action = NULL;
404     
405     gsignond_dictionary_unref(data);
406
407     g_object_unref(config);
408     g_object_unref(plugin);
409 }
410 END_TEST
411
412 START_TEST (test_pluginremote_user_action_finished)
413 {
414     DBG ("");
415     GSignondPlugin *plugin = NULL;
416     const gchar *plugin_type = "password";
417
418     GSignondConfig* config = gsignond_config_new ();
419     fail_if(config == NULL);
420     
421     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(config, plugin_type));
422     fail_if(plugin == NULL);
423
424     GSignondSessionData* result = NULL;
425     GSignondSignonuiData* ui_action = NULL;
426     GError* error = NULL;
427
428     g_signal_connect(plugin, "response-final", G_CALLBACK(response_callback),
429             &result);
430     g_signal_connect(plugin, "user-action-required", 
431                      G_CALLBACK(user_action_required_callback), &ui_action);
432     g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
433
434     GSignondSignonuiData* data = gsignond_dictionary_new();
435     
436     //empty data
437     gsignond_plugin_user_action_finished(plugin, data);
438     _run_mainloop ();
439
440     fail_if(result != NULL);    
441     fail_if(ui_action != NULL);
442     fail_if(error == NULL);
443     fail_unless (error->code == GSIGNOND_ERROR_USER_INTERACTION);
444     g_error_free(error);
445     error = NULL;
446     
447     // correct values
448     gsignond_signonui_data_set_username(data, "megauser");
449     gsignond_signonui_data_set_password(data, "megapassword");
450     gsignond_signonui_data_set_query_error(data, SIGNONUI_ERROR_NONE);
451     gsignond_plugin_user_action_finished(plugin, data);
452     _run_mainloop ();
453
454     fail_if(result == NULL);    
455     fail_if(ui_action != NULL);
456     fail_if(error != NULL);
457     fail_if(g_strcmp0(
458         gsignond_session_data_get_username(result), "megauser") != 0);
459     fail_if(g_strcmp0(
460         gsignond_session_data_get_secret(result), "megapassword") != 0);
461     gsignond_dictionary_unref(result);
462     result = NULL;
463
464     // user canceled
465     gsignond_signonui_data_set_query_error(data, SIGNONUI_ERROR_CANCELED);
466     gsignond_plugin_user_action_finished(plugin, data);
467     _run_mainloop ();
468
469     fail_if(result != NULL);    
470     fail_if(ui_action != NULL);
471     fail_if(error == NULL);
472     fail_unless (error->code == GSIGNOND_ERROR_SESSION_CANCELED);
473     g_error_free(error);
474     error = NULL;
475
476     // error in ui request
477     gsignond_signonui_data_set_query_error(data, SIGNONUI_ERROR_GENERAL);
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_USER_INTERACTION);
485     g_error_free(error);
486     error = NULL;
487     
488     gsignond_dictionary_unref(data);
489
490     g_object_unref(config);
491     g_object_unref(plugin);
492 }
493 END_TEST
494
495 START_TEST (test_pluginremote_refresh)
496 {
497     DBG ("");
498     GSignondPlugin *plugin = NULL;
499     const gchar *plugin_type = "password";
500
501     GSignondConfig* config = gsignond_config_new ();
502     fail_if(config == NULL);
503     
504     plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new(config, plugin_type));
505     fail_if(plugin == NULL);
506
507     GSignondSessionData* result = NULL;
508     GError* error = NULL;
509
510     g_signal_connect(plugin, "refreshed", G_CALLBACK(response_callback),
511             &result);
512     g_signal_connect(plugin, "error", G_CALLBACK(error_callback), &error);
513
514     GSignondSessionData* data = gsignond_dictionary_new();
515     gsignond_plugin_refresh(plugin, data);
516     _run_mainloop ();
517
518     fail_if(result == NULL);    
519     fail_if(error != NULL);
520     gsignond_dictionary_unref(result);
521     result = NULL;
522     
523     gsignond_dictionary_unref(data);
524
525     g_object_unref(config);
526     g_object_unref(plugin);
527 }
528 END_TEST
529
530 START_TEST (test_plugind_daemon)
531 {
532     DBG ("");
533     GSignondPluginDaemon *daemon = NULL;
534     const gchar *plugin_type = "password";
535
536     GSignondConfig* config = gsignond_config_new ();
537     fail_if(config == NULL);
538
539     gchar *plugin_path = g_module_build_path (gsignond_config_get_string (
540                 config, GSIGNOND_CONFIG_GENERAL_PLUGINS_DIR), "nonexisting");
541     fail_if (plugin_path == NULL);
542     daemon = gsignond_plugin_daemon_new (plugin_path, "nonexisting", 0, 1);
543     g_free (plugin_path);
544     fail_if (daemon != NULL);
545
546     plugin_path = g_module_build_path (gsignond_config_get_string (
547             config, GSIGNOND_CONFIG_GENERAL_PLUGINS_DIR), plugin_type);
548     fail_if (plugin_path == NULL);
549     daemon = gsignond_plugin_daemon_new (plugin_path, plugin_type, 0, 1);
550     g_free (plugin_path);
551     fail_if (daemon == NULL);
552     g_object_unref (daemon);
553     daemon = NULL;
554     g_object_unref(config);
555 }
556 END_TEST
557
558 Suite* pluginremote_suite (void)
559 {
560     Suite *s = suite_create ("Plugin remote");
561     
562     /* Core test case */
563     TCase *tc_core = tcase_create ("RemoteTests");
564     tcase_add_checked_fixture (tc_core, _setup, _teardown);
565     tcase_add_test (tc_core, test_pluginremote_create);
566     tcase_add_test (tc_core, test_pluginremote_plugind_create);
567     tcase_add_test (tc_core, test_pluginremote_plugind_unref);
568     tcase_add_test (tc_core, test_pluginremote_plugind_kill);
569     tcase_add_test (tc_core, test_pluginremote_request);
570     tcase_add_test (tc_core, test_pluginremote_user_action_finished);
571     tcase_add_test (tc_core, test_pluginremote_refresh);
572     tcase_add_test (tc_core, test_plugind_daemon);
573
574     suite_add_tcase (s, tc_core);
575     return s;
576 }
577
578 int main (void)
579 {
580     int number_failed;
581     
582     Suite *s = pluginremote_suite();
583     SRunner *sr = srunner_create(s);
584     srunner_run_all(sr, CK_NORMAL);
585     number_failed = srunner_ntests_failed(sr);
586     srunner_free(sr);
587     return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
588 }
589