Fixes: NB#Account::verify and Account::verifyWithTokens() returns TRUE all the time...
[accounts-sso:accounts-glib.git] / tests / check_ag.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 libaccounts-glib
5  *
6  * Copyright (C) 2009-2010 Nokia Corporation.
7  *
8  * Contact: Alberto Mardegan <alberto.mardegan@nokia.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 License
12  * version 2.1 as published by the Free Software Foundation.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  */
24
25 /**
26  * @example check_ag.c
27  * Shows how to initialize the framework.
28  */
29
30 #include "libaccounts-glib/ag-manager.h"
31 #include "libaccounts-glib/ag-account.h"
32 #include "libaccounts-glib/ag-errors.h"
33 #include "libaccounts-glib/ag-internals.h"
34
35 #include <glib.h>
36 #include <glib/gstdio.h>
37 #include <check.h>
38 #include <sched.h>
39 #include <sqlite3.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <unistd.h>
46
47 #include "config.h"
48
49 #define PROVIDER    "dummyprovider"
50 #define TEST_STRING "Hey dude!"
51
52 static gchar *db_filename;
53 static GMainLoop *main_loop = NULL;
54 gboolean lock_released = FALSE;
55 static AgAccount *account = NULL;
56 static AgManager *manager = NULL;
57 static AgService *service = NULL;
58 static gboolean data_stored = FALSE;
59 static guint source_id = 0;
60 static guint idle_finish = 0;
61
62 typedef struct {
63     gboolean called;
64     gchar *service;
65     gboolean enabled;
66 } EnabledCbData;
67
68 static guint
69 time_diff(struct timespec *start_time, struct timespec *end_time)
70 {
71     struct timespec diff_time;
72     diff_time.tv_sec = end_time->tv_sec - start_time->tv_sec;
73     diff_time.tv_nsec = end_time->tv_nsec - start_time->tv_nsec;
74     return diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
75 }
76
77 static void
78 end_test ()
79 {
80     if (account)
81     {
82         g_object_unref (account);
83         account = NULL;
84     }
85     if (manager)
86     {
87         g_object_unref (manager);
88         manager = NULL;
89     }
90     if (service)
91     {
92         ag_service_unref (service);
93         service = NULL;
94     }
95
96     if (main_loop)
97     {
98         g_main_loop_quit (main_loop);
99         g_main_loop_unref (main_loop);
100         main_loop = NULL;
101     }
102
103     data_stored = FALSE;
104 }
105
106 START_TEST(test_init)
107 {
108     g_type_init ();
109     manager = ag_manager_new ();
110
111     fail_unless (AG_IS_MANAGER (manager),
112                  "Failed to initialize the AgManager.");
113
114     end_test ();
115 }
116 END_TEST
117
118 START_TEST(test_object)
119 {
120     g_type_init ();
121     manager = ag_manager_new ();
122
123     account = ag_manager_create_account (manager, NULL);
124     fail_unless (AG_IS_ACCOUNT (account),
125                  "Failed to create the AgAccount.");
126
127     end_test ();
128 }
129 END_TEST
130
131 START_TEST(test_provider)
132 {
133     const gchar *provider_name, *display_name;
134     AgProvider *provider;
135     GList *providers;
136
137     g_type_init ();
138     manager = ag_manager_new ();
139
140     account = ag_manager_create_account (manager, PROVIDER);
141     fail_unless (AG_IS_ACCOUNT (account),
142                  "Failed to create the AgAccount.");
143
144     provider_name = ag_account_get_provider_name (account);
145     fail_if (g_strcmp0 (provider_name, PROVIDER) != 0);
146
147     /* Test provider XML file loading */
148     provider = ag_manager_get_provider (manager, "MyProvider");
149     fail_unless (provider != NULL);
150
151     display_name = ag_provider_get_display_name (provider);
152     fail_unless (g_strcmp0 (display_name, "My Provider") == 0);
153
154     ag_provider_unref (provider);
155
156     /* Test provider enumeration */
157     providers = ag_manager_list_providers (manager);
158     fail_unless (providers != NULL);
159     fail_unless (g_list_length (providers) == 1);
160     provider = providers->data;
161
162     display_name = ag_provider_get_display_name (provider);
163     fail_unless (g_strcmp0 (display_name, "My Provider") == 0);
164
165     ag_provider_list_free (providers);
166
167     end_test ();
168 }
169 END_TEST
170
171 void account_store_cb (AgAccount *account, const GError *error,
172                        gpointer user_data)
173 {
174     const gchar *string = user_data;
175
176     fail_unless (AG_IS_ACCOUNT (account), "Account got disposed?");
177     if (error)
178         fail("Got error: %s", error->message);
179     fail_unless (g_strcmp0 (string, TEST_STRING) == 0, "Got wrong string");
180
181     end_test ();
182 }
183
184 START_TEST(test_store)
185 {
186     g_type_init ();
187     manager = ag_manager_new ();
188
189     account = ag_manager_create_account (manager, PROVIDER);
190
191     main_loop = g_main_loop_new (NULL, FALSE);
192     ag_account_store (account, account_store_cb, TEST_STRING);
193     if (main_loop)
194     {
195         g_debug ("Running loop");
196         g_main_loop_run (main_loop);
197     }
198     else
199         end_test ();
200 }
201 END_TEST
202
203 void account_store_locked_cb (AgAccount *account, const GError *error,
204                               gpointer user_data)
205 {
206     const gchar *string = user_data;
207
208     g_debug ("%s called", G_STRFUNC);
209     fail_unless (AG_IS_ACCOUNT (account), "Account got disposed?");
210     if (error)
211         fail("Got error: %s", error->message);
212     fail_unless (g_strcmp0 (string, TEST_STRING) == 0, "Got wrong string");
213
214     fail_unless (lock_released, "Data stored while DB locked!");
215
216     end_test ();
217 }
218
219 gboolean
220 release_lock (sqlite3 *db)
221 {
222     g_debug ("releasing lock");
223     sqlite3_exec (db, "COMMIT;", NULL, NULL, NULL);
224     lock_released = TRUE;
225     return FALSE;
226 }
227
228 START_TEST(test_store_locked)
229 {
230     sqlite3 *db;
231
232     g_type_init ();
233     manager = ag_manager_new ();
234
235     account = ag_manager_create_account (manager, PROVIDER);
236
237     /* get an exclusive lock on the DB */
238     sqlite3_open (db_filename, &db);
239     sqlite3_exec (db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
240
241     main_loop = g_main_loop_new (NULL, FALSE);
242     ag_account_store (account, account_store_locked_cb, TEST_STRING);
243     g_timeout_add (100, (GSourceFunc)release_lock, db);
244     fail_unless (main_loop != NULL, "Callback invoked too early");
245     g_debug ("Running loop");
246     g_main_loop_run (main_loop);
247 }
248 END_TEST
249
250 static void
251 account_store_locked_unref_cb (AgAccount *account, const GError *error,
252                                gpointer user_data)
253 {
254     const gchar *string = user_data;
255
256     g_debug ("%s called", G_STRFUNC);
257     fail_unless (error != NULL, "Account disposed but no error set!");
258     fail_unless (error->code == AG_ERROR_DISPOSED,
259                  "Got a different error code");
260     fail_unless (g_strcmp0 (string, TEST_STRING) == 0, "Got wrong string");
261 }
262
263 static void
264 release_lock_unref (sqlite3 *db)
265 {
266     g_debug ("releasing lock");
267     sqlite3_exec (db, "COMMIT;", NULL, NULL, NULL);
268
269     end_test ();
270 }
271
272 static gboolean
273 unref_account (gpointer user_data)
274 {
275     g_debug ("Unreferencing account %p", account);
276     fail_unless (AG_IS_ACCOUNT (account), "Account disposed?");
277     g_object_unref (account);
278     account = NULL;
279     return FALSE;
280 }
281
282 START_TEST(test_store_locked_unref)
283 {
284     sqlite3 *db;
285
286     g_type_init ();
287     manager = ag_manager_new ();
288
289     account = ag_manager_create_account (manager, PROVIDER);
290
291     /* get an exclusive lock on the DB */
292     sqlite3_open (db_filename, &db);
293     sqlite3_exec (db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
294
295     main_loop = g_main_loop_new (NULL, FALSE);
296     ag_account_store (account, account_store_locked_unref_cb, TEST_STRING);
297     g_timeout_add (10, (GSourceFunc)unref_account, NULL);
298     g_timeout_add (20, (GSourceFunc)release_lock_unref, db);
299     fail_unless (main_loop != NULL, "Callback invoked too early");
300     g_debug ("Running loop");
301     g_main_loop_run (main_loop);
302 }
303 END_TEST
304
305 void account_store_now_cb (AgAccount *account, const GError *error,
306                            gpointer user_data)
307 {
308     const gchar *string = user_data;
309
310     fail_unless (AG_IS_ACCOUNT (account), "Account got disposed?");
311     if (error)
312         fail("Got error: %s", error->message);
313     fail_unless (g_strcmp0 (string, TEST_STRING) == 0, "Got wrong string");
314
315     data_stored = TRUE;
316 }
317
318 START_TEST(test_service)
319 {
320     GValue value = { 0 };
321     AgService *service2;
322     AgAccountId account_id;
323     const gchar *provider_name, *service_type, *service_name, *icon_name;
324     const gchar *description = "This is really a beautiful account";
325     const gchar *username = "me@myhome.com";
326     const gint interval = 30;
327     const gboolean check_automatically = TRUE;
328     const gchar *display_name = "My test account";
329     AgSettingSource source;
330     GError *error = NULL;
331
332     g_type_init ();
333
334     manager = ag_manager_new ();
335     account = ag_manager_create_account (manager, PROVIDER);
336
337     g_value_init (&value, G_TYPE_STRING);
338     g_value_set_static_string (&value, description);
339     ag_account_set_value (account, "description", &value);
340     g_value_unset (&value);
341
342     service = ag_manager_get_service (manager, "MyUnexistingService");
343     fail_unless (service == NULL);
344
345     service = ag_manager_get_service (manager, "MyService");
346     fail_unless (service != NULL);
347
348     service_type = ag_service_get_service_type (service);
349     fail_unless (g_strcmp0 (service_type, "e-mail") == 0,
350                  "Wrong service type: %s", service_type);
351
352     service_name = ag_service_get_name (service);
353     fail_unless (g_strcmp0 (service_name, "MyService") == 0,
354                  "Wrong service name: %s", service_name);
355
356     service_name = ag_service_get_display_name (service);
357     fail_unless (g_strcmp0 (service_name, "My Service") == 0,
358                  "Wrong service display name: %s", service_name);
359
360     icon_name = ag_service_get_icon_name (service);
361     fail_unless (g_strcmp0 (icon_name, "general_myservice") == 0,
362                  "Wrong service icon name: %s", icon_name);
363
364     ag_account_set_enabled (account, FALSE);
365     ag_account_set_display_name (account, display_name);
366
367     ag_account_select_service (account, service);
368
369     /* test getting default setting from template */
370     g_value_init (&value, G_TYPE_INT);
371     source = ag_account_get_value (account, "parameters/port", &value);
372     fail_unless (source == AG_SETTING_SOURCE_PROFILE,
373                  "Cannot get port from profile");
374     fail_unless (g_value_get_int (&value) == 5223,
375                  "Wrong port number: %d", g_value_get_int (&value));
376     g_value_unset (&value);
377
378     /* enable the service */
379     ag_account_set_enabled (account, TRUE);
380
381     g_value_init (&value, G_TYPE_STRING);
382     g_value_set_static_string (&value, username);
383     ag_account_set_value (account, "username", &value);
384     g_value_unset (&value);
385
386     g_value_init (&value, G_TYPE_BOOLEAN);
387     g_value_set_boolean (&value, check_automatically);
388     ag_account_set_value (account, "check_automatically", &value);
389     g_value_unset (&value);
390
391     g_value_init (&value, G_TYPE_INT);
392     g_value_set_int (&value, interval);
393     ag_account_set_value (account, "interval", &value);
394     g_value_unset (&value);
395
396     service2 = ag_manager_get_service (manager, "OtherService");
397     ag_account_select_service (account, service2);
398
399     g_value_init (&value, G_TYPE_STRING);
400     g_value_set_static_string (&value, "Wednesday");
401     ag_account_set_value (account, "day", &value);
402     g_value_unset (&value);
403
404     g_value_init (&value, G_TYPE_BOOLEAN);
405     g_value_set_boolean (&value, TRUE);
406     ag_account_set_value (account, "ForReal", &value);
407     g_value_unset (&value);
408
409     ag_account_store (account, account_store_now_cb, TEST_STRING);
410     fail_unless (data_stored, "Callback not invoked immediately");
411
412     g_debug ("Service id: %d", service->id);
413     g_debug ("Service2 id: %d", service2->id);
414     g_debug ("Account id: %d", account->id);
415     account_id = account->id;
416
417     ag_service_unref (service2);
418     g_object_unref (account);
419     g_object_unref (manager);
420
421     manager = ag_manager_new ();
422
423     /* first, try to load an unexisting account */
424     account = ag_manager_load_account (manager, account_id + 2, &error);
425     fail_unless (account == NULL, "Loading a non-existing account!");
426     fail_unless (error != NULL, "Error is NULL");
427     g_clear_error (&error);
428
429     account = ag_manager_load_account (manager, account_id, &error);
430     fail_unless (AG_IS_ACCOUNT (account),
431                  "Couldn't load account %u", account_id);
432     fail_unless (error == NULL, "Error is not NULL");
433
434     provider_name = ag_account_get_provider_name (account);
435     fail_unless (g_strcmp0 (provider_name, PROVIDER) == 0,
436                  "Got provider %s, expecting %s", provider_name, PROVIDER);
437
438     /* check that the values are retained */
439     fail_unless (ag_account_get_enabled (account) == FALSE,
440                  "Account enabled!");
441     fail_unless (g_strcmp0 (ag_account_get_display_name (account),
442                          display_name) == 0,
443                  "Display name not retained!");
444
445     g_value_init (&value, G_TYPE_STRING);
446     source = ag_account_get_value (account, "description", &value);
447     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
448     fail_unless (g_strcmp0(g_value_get_string (&value), description) == 0,
449                  "Wrong value");
450     g_value_unset (&value);
451
452     ag_account_select_service (account, service);
453
454     /* we enabled the service before: check that it's still enabled */
455     fail_unless (ag_account_get_enabled (account) == TRUE,
456                  "Account service not enabled!");
457
458     g_value_init (&value, G_TYPE_STRING);
459     source = ag_account_get_value (account, "username", &value);
460     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
461     fail_unless (g_strcmp0(g_value_get_string (&value), username) == 0,
462                  "Wrong value");
463     g_value_unset (&value);
464
465     g_value_init (&value, G_TYPE_BOOLEAN);
466     source = ag_account_get_value (account, "check_automatically", &value);
467     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
468     fail_unless (g_value_get_boolean (&value) == check_automatically,
469                  "Wrong value");
470     g_value_unset (&value);
471
472     g_value_init (&value, G_TYPE_INT);
473     source = ag_account_get_value (account, "interval", &value);
474     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
475     fail_unless (g_value_get_int (&value) == interval, "Wrong value");
476     g_value_unset (&value);
477
478     /* check also value conversion */
479     g_value_init (&value, G_TYPE_CHAR);
480     source = ag_account_get_value (account, "interval", &value);
481     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
482     fail_unless (g_value_get_char (&value) == interval, "Wrong value");
483     g_value_unset (&value);
484
485     /* change a value */
486     g_value_init (&value, G_TYPE_STRING);
487     g_value_set_static_string (&value, "Friday");
488     ag_account_set_value (account, "day", &value);
489     g_value_unset (&value);
490
491     /* change global enabledness */
492     ag_account_select_service (account, NULL);
493     ag_account_set_enabled (account, TRUE);
494
495     ag_account_store (account, account_store_now_cb, TEST_STRING);
496     fail_unless (data_stored, "Callback not invoked immediately");
497
498     fail_unless (ag_account_get_enabled (account) == TRUE,
499                  "Account still disabled!");
500     end_test ();
501 }
502 END_TEST
503
504 START_TEST(test_account_services)
505 {
506     GList *services;
507     AgService *service;
508
509     g_type_init ();
510     manager = ag_manager_new ();
511
512     account = ag_manager_create_account (manager, "maemo");
513     fail_unless (AG_IS_ACCOUNT (account),
514                  "Failed to create the AgAccount.");
515
516     services = ag_account_list_services (account);
517     fail_unless (g_list_length (services) == 1);
518
519     service = services->data;
520     fail_unless (g_strcmp0 (ag_service_get_name (service), "MyService") == 0);
521
522     ag_service_list_free (services);
523
524     /* check that MyService is returned as a service supporting e-mail for
525      * this account */
526     services = ag_account_list_services_by_type (account, "e-mail");
527     fail_unless (g_list_length (services) == 1);
528
529     service = services->data;
530     fail_unless (g_strcmp0 (ag_service_get_name (service), "MyService") == 0);
531
532     ag_service_list_free (services);
533
534     /* check that the account supports the "e-mail" type (it's the type of
535      * MyService */
536     fail_unless (ag_account_supports_service (account, "e-mail") == TRUE);
537     /* and doesn't support "sharing" */
538     fail_unless (ag_account_supports_service (account, "sharing") == FALSE);
539
540     end_test ();
541 }
542 END_TEST
543
544 static void
545 set_boolean_variable (gboolean *flag)
546 {
547     *flag = TRUE;
548 }
549
550 START_TEST(test_signals)
551 {
552     const gchar *display_name = "My lovely account";
553     gboolean enabled_called = FALSE;
554     gboolean display_name_called = FALSE;
555
556     g_type_init ();
557
558     manager = ag_manager_new ();
559     account = ag_manager_create_account (manager, PROVIDER);
560
561     g_signal_connect_swapped (account, "enabled",
562                               G_CALLBACK (set_boolean_variable),
563                               &enabled_called);
564     g_signal_connect_swapped (account, "display-name-changed",
565                               G_CALLBACK (set_boolean_variable),
566                               &display_name_called);
567
568     ag_account_set_enabled (account, TRUE);
569     ag_account_set_display_name (account, display_name);
570
571
572     ag_account_store (account, account_store_now_cb, TEST_STRING);
573     fail_unless (data_stored, "Callback not invoked immediately");
574
575     fail_unless (enabled_called, "Enabled signal not emitted!");
576     fail_unless (display_name_called, "DisplayName signal not emitted!");
577
578     end_test ();
579 }
580 END_TEST
581
582 START_TEST(test_list)
583 {
584     const gchar *display_name = "New account";
585     const gchar *service_name = "OtherService";
586     const gchar *service_type;
587     GValue value = { 0 };
588     AgSettingSource source;
589     GList *list;
590
591     g_type_init ();
592
593     manager = ag_manager_new ();
594     account = ag_manager_create_account (manager, PROVIDER);
595
596     ag_account_set_enabled (account, TRUE);
597     ag_account_set_display_name (account, display_name);
598
599     ag_account_store (account, account_store_now_cb, TEST_STRING);
600     fail_unless (data_stored, "Callback not invoked immediately");
601
602     fail_unless (account->id != 0, "Account ID is still 0!");
603
604     list = ag_manager_list (manager);
605     fail_unless (list != NULL, "Empty list");
606     fail_unless (g_list_find (list, GUINT_TO_POINTER (account->id)) != NULL,
607                  "Created account not found in list");
608     g_list_free (list);
609
610     /* check that it doesn't support the service type provided by MyService */
611     service = ag_manager_get_service (manager, service_name);
612     service_type = ag_service_get_service_type (service);
613     fail_unless (service_type != NULL, "Service %s has no type", service_name);
614
615     list = ag_manager_list_by_service_type (manager, service_type);
616     fail_unless (g_list_find (list, GUINT_TO_POINTER (account->id)) == NULL,
617                  "New account supports %s service type, but shouldn't",
618                  service_type);
619     g_list_free (list);
620
621     /* Add the service to the account */
622     fail_unless (service != NULL);
623
624     ag_account_select_service (account, service);
625     ag_account_set_enabled (account, TRUE);
626
627     /* test getting default setting from template */
628     g_value_init (&value, G_TYPE_INT);
629     source = ag_account_get_value (account, "parameters/port", &value);
630     fail_unless (source == AG_SETTING_SOURCE_PROFILE,
631                  "Cannot get port from profile");
632     fail_unless (g_value_get_int (&value) == 5223,
633                  "Wrong port number: %d", g_value_get_int (&value));
634     g_value_unset (&value);
635
636     ag_account_store (account, account_store_now_cb, TEST_STRING);
637     fail_unless (data_stored, "Callback not invoked immediately");
638
639     /* check that the service is now there */
640     list = ag_manager_list_by_service_type (manager, service_type);
641     fail_unless (g_list_find (list, GUINT_TO_POINTER (account->id)) != NULL,
642                  "New account doesn't supports %s service type, but should",
643                  service_type);
644     g_list_free (list);
645
646     end_test ();
647 }
648 END_TEST
649
650 START_TEST(test_settings_iter)
651 {
652     const gchar *keys[] = {
653         "param/address",
654         "weight",
655         "param/city",
656         "age",
657         "param/country",
658         NULL,
659     };
660     const gchar *values[] = {
661         "Helsinginkatu",
662         "110",
663         "Helsinki",
664         "90",
665         "Suomi",
666         NULL,
667     };
668     const gchar *service_name = "OtherService";
669     GValue value = { 0 };
670     AgAccountSettingIter iter;
671     const gchar *key;
672     const GValue *val;
673     gint i, n_values, n_read;
674     const gint new_port_value = 432412;
675
676     g_type_init ();
677
678     manager = ag_manager_new ();
679     account = ag_manager_create_account (manager, PROVIDER);
680
681     ag_account_set_enabled (account, TRUE);
682
683     for (i = 0; keys[i] != NULL; i++)
684     {
685         g_value_init (&value, G_TYPE_STRING);
686         g_value_set_static_string (&value, values[i]);
687         ag_account_set_value (account, keys[i], &value);
688         g_value_unset (&value);
689     }
690     n_values = i;
691
692     ag_account_store (account, account_store_now_cb, TEST_STRING);
693     fail_unless (data_stored, "Callback not invoked immediately");
694
695     fail_unless (account->id != 0, "Account ID is still 0!");
696
697     /* iterate the settings */
698     n_read = 0;
699     ag_account_settings_iter_init (account, &iter, NULL);
700     while (ag_account_settings_iter_next (&iter, &key, &val))
701     {
702         gboolean found = FALSE;
703         for (i = 0; keys[i] != NULL; i++)
704         {
705             if (g_strcmp0 (key, keys[i]) == 0)
706             {
707                 const gchar *text;
708                 found = TRUE;
709                 text = g_value_get_string (val);
710                 fail_unless (g_strcmp0 (values[i], text) == 0,
711                              "Got value %s for key %s, expecting %s",
712                              text, key, values[i]);
713                 break;
714             }
715         }
716
717         fail_unless (found, "Unknown setting %s", key);
718
719         n_read++;
720     }
721
722     fail_unless (n_read == n_values,
723                  "Not all settings were retrieved (%d out of %d)",
724                  n_read, n_values);
725
726     /* iterate settings with prefix */
727     n_read = 0;
728     ag_account_settings_iter_init (account, &iter, "param/");
729     while (ag_account_settings_iter_next (&iter, &key, &val))
730     {
731         gboolean found = FALSE;
732         fail_unless (strncmp (key, "param/", 6) == 0,
733                      "Got key %s, wrong prefix", key);
734         for (i = 0; keys[i] != NULL; i++)
735         {
736             if (g_strcmp0 (key, keys[i]) == 0)
737             {
738                 const gchar *text;
739                 found = TRUE;
740                 text = g_value_get_string (val);
741                 fail_unless (g_strcmp0 (values[i], text) == 0,
742                              "Got value %s for key %s, expecting %s",
743                              text, key, values[i]);
744                 break;
745             }
746         }
747
748         fail_unless (found, "Unknown setting %s", key);
749
750         n_read++;
751     }
752
753     fail_unless (n_read == 3, "Not all settings were retrieved");
754
755     /* iterate template default settings */
756     service = ag_manager_get_service (manager, service_name);
757     ag_account_select_service (account, service);
758     n_read = 0;
759     ag_account_settings_iter_init (account, &iter, NULL);
760     while (ag_account_settings_iter_next (&iter, &key, &val))
761     {
762         g_debug ("Got key %s of type %s", key, G_VALUE_TYPE_NAME (val));
763
764         n_read++;
765     }
766     fail_unless (n_read == 4, "Not all settings were retrieved");
767
768     /* Add a setting that is also on the template, to check if it will
769      * override the one on the template */
770     g_value_init (&value, G_TYPE_INT);
771     g_value_set_int (&value, new_port_value);
772     ag_account_set_value (account, "parameters/port", &value);
773     g_value_unset (&value);
774
775     /* Add a setting */
776     g_value_init (&value, G_TYPE_STRING);
777     g_value_set_static_string (&value, "How's life?");
778     ag_account_set_value (account, "parameters/message", &value);
779     g_value_unset (&value);
780
781     /* save */
782     ag_account_store (account, account_store_now_cb, TEST_STRING);
783     fail_unless (data_stored, "Callback not invoked immediately");
784
785     /* enumerate the parameters */
786     n_read = 0;
787     ag_account_settings_iter_init (account, &iter, "parameters/");
788     while (ag_account_settings_iter_next (&iter, &key, &val))
789     {
790         fail_unless (g_str_has_prefix (key, "parameters/"),
791                      "Got key %s, wrong prefix", key);
792         g_debug ("Got key %s of type %s", key, G_VALUE_TYPE_NAME (val));
793         if (g_strcmp0 (key, "parameters/port") == 0)
794         {
795             gint port;
796
797             port = g_value_get_int (val);
798             fail_unless (port == new_port_value,
799                          "Got value %d for key %s, expecting %d",
800                          port, key, new_port_value);
801         }
802
803         n_read++;
804     }
805
806     fail_unless (n_read == 5, "Not all settings were retrieved");
807
808
809     end_test ();
810 }
811 END_TEST
812
813 START_TEST(test_list_services)
814 {
815     GList *services, *list;
816     gint n_services;
817     AgService *service;
818     const gchar *name;
819
820     g_type_init ();
821
822     manager = ag_manager_new ();
823
824     /* get all services */
825     services = ag_manager_list_services (manager);
826
827     n_services = g_list_length (services);
828     fail_unless (n_services == 2, "Got %d services, expecting 2", n_services);
829
830     for (list = services; list != NULL; list = list->next)
831     {
832         service = list->data;
833
834         name = ag_service_get_name (service);
835         g_debug ("Service name: %s", name);
836         fail_unless (g_strcmp0 (name, "MyService") == 0 ||
837                      g_strcmp0 (name, "OtherService") == 0,
838                      "Got unexpected service `%s'", name);
839     }
840     ag_service_list_free (services);
841
842     /* get services by type */
843     services = ag_manager_list_services_by_type (manager, "sharing");
844
845     n_services = g_list_length (services);
846     fail_unless (n_services == 1, "Got %d services, expecting 1", n_services);
847
848     list = services;
849     service = list->data;
850     name = ag_service_get_name (service);
851     fail_unless (g_strcmp0 (name, "OtherService") == 0,
852                  "Got unexpected service `%s'", name);
853     ag_service_list_free (services);
854
855     end_test ();
856 }
857 END_TEST
858
859 START_TEST(test_delete)
860 {
861     AgAccountId id;
862     gboolean enabled_called, deleted_called;
863
864     g_type_init ();
865
866     manager = ag_manager_new ();
867
868     /* create an account */
869     account = ag_manager_create_account (manager, PROVIDER);
870     ag_account_set_enabled (account, TRUE);
871     ag_account_store (account, account_store_now_cb, TEST_STRING);
872     fail_unless (data_stored, "Callback not invoked immediately");
873
874     fail_unless (account->id != 0, "Account ID is still 0!");
875     id = account->id;
876
877     /* monitor the account status */
878     g_signal_connect_swapped (account, "enabled",
879                               G_CALLBACK (set_boolean_variable),
880                               &enabled_called);
881     g_signal_connect_swapped (account, "deleted",
882                               G_CALLBACK (set_boolean_variable),
883                               &deleted_called);
884     enabled_called = deleted_called = FALSE;
885
886     /* delete it */
887     ag_account_delete (account);
888
889     /* until ag_account_store() is called, the signals should not have been
890      * emitted */
891     fail_unless (enabled_called == FALSE, "Accound disabled too early!");
892     fail_unless (deleted_called == FALSE, "Accound deleted too early!");
893
894     /* really delete the account */
895     ag_account_store (account, account_store_now_cb, TEST_STRING);
896     fail_unless (data_stored, "Callback not invoked immediately");
897
898     /* check that the signals are emitted */
899     fail_unless (enabled_called, "Accound enabled signal not emitted");
900     fail_unless (deleted_called, "Accound deleted signal not emitted");
901
902     g_object_unref (account);
903
904     /* load the account again: this must fail */
905     account = ag_manager_get_account (manager, id);
906     fail_unless (account == NULL, "The account still exists");
907
908     end_test ();
909 }
910 END_TEST
911
912 static void
913 key_changed_cb (AgAccount *account, const gchar *key, gboolean *invoked)
914 {
915     fail_unless (invoked != NULL);
916     fail_unless (*invoked == FALSE, "Callback invoked twice!");
917
918     fail_unless (key != NULL);
919     fail_unless (g_strcmp0 (key, "parameters/server") == 0 ||
920                  g_strcmp0 (key, "parameters/port") == 0,
921                  "Callback invoked for wrong key %s", key);
922     *invoked = TRUE;
923 }
924
925 static void
926 dir_changed_cb (AgAccount *account, const gchar *key, gboolean *invoked)
927 {
928     fail_unless (invoked != NULL);
929     fail_unless (*invoked == FALSE, "Callback invoked twice!");
930
931     fail_unless (key != NULL);
932     fail_unless (g_strcmp0 (key, "parameters/") == 0,
933                  "Callback invoked for wrong dir %s", key);
934     *invoked = TRUE;
935 }
936
937 START_TEST(test_watches)
938 {
939     gboolean server_changed = FALSE;
940     gboolean port_changed = FALSE;
941     gboolean dir_changed = FALSE;
942     AgAccountWatch w_server, w_port, w_dir;
943     GValue value = { 0 };
944
945     g_type_init ();
946
947     manager = ag_manager_new ();
948     account = ag_manager_create_account (manager, PROVIDER);
949
950     service = ag_manager_get_service (manager, "MyService");
951     fail_unless (service != NULL);
952
953     ag_account_select_service (account, service);
954
955     /* install some watches */
956     w_server = ag_account_watch_key (account, "parameters/server",
957                                      (AgAccountNotifyCb)key_changed_cb,
958                                      &server_changed);
959     fail_unless (w_server != NULL);
960
961     w_port = ag_account_watch_key (account, "parameters/port",
962                                    (AgAccountNotifyCb)key_changed_cb,
963                                    &port_changed);
964     fail_unless (w_port != NULL);
965
966     w_dir = ag_account_watch_dir (account, "parameters/",
967                                   (AgAccountNotifyCb)dir_changed_cb,
968                                   &dir_changed);
969     fail_unless (w_port != NULL);
970
971     /* change the port */
972     g_value_init (&value, G_TYPE_INT);
973     g_value_set_int (&value, 22);
974     ag_account_set_value (account, "parameters/port", &value);
975     g_value_unset (&value);
976
977     ag_account_store (account, account_store_now_cb, TEST_STRING);
978     fail_unless (data_stored, "Callback not invoked immediately");
979
980     /* if we didn't change the server, make sure the callback is not
981      * invoked */
982     fail_unless (server_changed == FALSE, "Callback for 'server' invoked");
983
984     /* make sure the port callback was called */
985     fail_unless (port_changed == TRUE, "Callback for 'port' not invoked");
986
987     /* make sure the dir callback was called */
988     fail_unless (dir_changed == TRUE, "Callback for 'parameters/' not invoked");
989
990
991     /* remove the watch for the port */
992     ag_account_remove_watch (account, w_port);
993
994     /* change two settings */
995     g_value_init (&value, G_TYPE_INT);
996     g_value_set_int (&value, 25);
997     ag_account_set_value (account, "parameters/port", &value);
998     g_value_unset (&value);
999
1000     g_value_init (&value, G_TYPE_STRING);
1001     g_value_set_static_string (&value, "warez.maemo.org");
1002     ag_account_set_value (account, "parameters/server", &value);
1003     g_value_unset (&value);
1004
1005     server_changed = FALSE;
1006     port_changed = FALSE;
1007     dir_changed = FALSE;
1008     ag_account_store (account, account_store_now_cb, TEST_STRING);
1009     fail_unless (data_stored, "Callback not invoked immediately");
1010
1011     /* make sure the callback for the server is invoked */
1012     fail_unless (server_changed == TRUE, "Callback for 'server' not invoked");
1013
1014     /* make sure the port callback was not called (we removed the watch) */
1015     fail_unless (port_changed == FALSE, "Callback for 'port' invoked");
1016
1017     /* make sure the dir callback was called */
1018     fail_unless (dir_changed == TRUE, "Callback for 'parameters/' not invoked");
1019
1020     end_test ();
1021 }
1022 END_TEST
1023
1024 static void
1025 on_account_created (AgManager *manager, AgAccountId account_id,
1026                     AgAccountId *id)
1027 {
1028     g_debug ("%s called (%u)", G_STRFUNC, account_id);
1029
1030     *id = account_id;
1031     g_main_loop_quit (main_loop);
1032 }
1033
1034 static void
1035 on_account_deleted (AgManager *manager, AgAccountId account_id,
1036                     AgAccountId *id)
1037 {
1038     g_debug ("%s called (%u)", G_STRFUNC, account_id);
1039
1040     fail_unless (account_id == *id, "Deletion of unexpected account");
1041     *id = 0;
1042     g_main_loop_quit (main_loop);
1043 }
1044
1045 static void
1046 changed_cb (AgAccount *account, const gchar *key, gboolean *invoked)
1047 {
1048     fail_unless (invoked != NULL);
1049     fail_unless (*invoked == FALSE, "Callback invoked twice!");
1050
1051     fail_unless (key != NULL);
1052     *invoked = TRUE;
1053     if (idle_finish == 0)
1054         idle_finish = g_idle_add ((GSourceFunc)g_main_loop_quit, main_loop);
1055 }
1056
1057 static gboolean
1058 concurrency_test_failed (gpointer userdata)
1059 {
1060     g_debug ("Timeout");
1061     g_main_loop_quit (main_loop);
1062     source_id = 0;
1063     return FALSE;
1064 }
1065
1066 static void
1067 on_enabled (AgAccount *account, const gchar *service, gboolean enabled,
1068             EnabledCbData *ecd)
1069 {
1070     ecd->called = TRUE;
1071     ecd->service = g_strdup (service);
1072     ecd->enabled = ( ag_account_get_enabled (account) == enabled );
1073 }
1074
1075 START_TEST(test_concurrency)
1076 {
1077     AgAccountId account_id;
1078     const gchar *provider_name, *display_name;
1079     gchar command[512];
1080     GValue value = { 0 };
1081     gboolean character_changed, string_changed, boolean_changed;
1082     gboolean unsigned_changed;
1083     AgSettingSource source;
1084     EnabledCbData ecd;
1085
1086     g_type_init ();
1087
1088     manager = ag_manager_new ();
1089
1090     g_signal_connect (manager, "account-created",
1091                       G_CALLBACK (on_account_created), &account_id);
1092
1093     account_id = 0;
1094     system ("test-process create myprovider MyAccountName");
1095
1096     main_loop = g_main_loop_new (NULL, FALSE);
1097     source_id = g_timeout_add_seconds (2, concurrency_test_failed, NULL);
1098     g_debug ("Running loop");
1099     g_main_loop_run (main_loop);
1100
1101     fail_unless (source_id != 0, "Timeout happened");
1102     g_source_remove (source_id);
1103
1104     fail_unless (account_id != 0, "Account ID still 0");
1105
1106     account = ag_manager_get_account (manager, account_id);
1107     fail_unless (AG_IS_ACCOUNT (account), "Got invalid account");
1108
1109     provider_name = ag_account_get_provider_name (account);
1110     fail_unless (g_strcmp0 (provider_name, "myprovider") == 0,
1111                  "Wrong provider name '%s'", provider_name);
1112
1113     display_name = ag_account_get_display_name (account);
1114     fail_unless (g_strcmp0 (display_name, "MyAccountName") == 0,
1115                  "Wrong display name '%s'", display_name);
1116
1117     /* check deletion */
1118     g_signal_connect (manager, "account-deleted",
1119                       G_CALLBACK (on_account_deleted), &account_id);
1120     sprintf (command, "test-process delete %d", account_id);
1121     system (command);
1122
1123     source_id = g_timeout_add_seconds (2, concurrency_test_failed, NULL);
1124     g_main_loop_run (main_loop);
1125     fail_unless (source_id != 0, "Timeout happened");
1126     g_source_remove (source_id);
1127
1128     fail_unless (account_id == 0, "Account still alive");
1129
1130     /* check a more complex creation */
1131     system ("test-process create2 myprovider MyAccountName");
1132
1133     source_id = g_timeout_add_seconds (2, concurrency_test_failed, NULL);
1134     g_main_loop_run (main_loop);
1135     fail_unless (source_id != 0, "Timeout happened");
1136     g_source_remove (source_id);
1137
1138     fail_unless (account_id != 0, "Account ID still 0");
1139
1140     account = ag_manager_get_account (manager, account_id);
1141     fail_unless (AG_IS_ACCOUNT (account), "Got invalid account");
1142
1143     fail_unless (ag_account_get_enabled (account) == TRUE);
1144
1145     g_value_init (&value, G_TYPE_INT);
1146     ag_account_get_value (account, "integer", &value);
1147     fail_unless (g_value_get_int (&value) == -12345);
1148     g_value_unset (&value);
1149
1150     g_value_init (&value, G_TYPE_STRING);
1151     ag_account_get_value (account, "string", &value);
1152     fail_unless (g_strcmp0 (g_value_get_string (&value), "a string") == 0);
1153     g_value_unset (&value);
1154
1155     /* we expect more keys in MyService */
1156     service = ag_manager_get_service (manager, "MyService");
1157     fail_unless (service != NULL, "Cannot get service");
1158
1159     ag_account_select_service (account, service);
1160
1161     g_value_init (&value, G_TYPE_UINT);
1162     ag_account_get_value (account, "unsigned", &value);
1163     fail_unless (g_value_get_uint (&value) == 54321);
1164     g_value_unset (&value);
1165
1166     g_value_init (&value, G_TYPE_CHAR);
1167     ag_account_get_value (account, "character", &value);
1168     fail_unless (g_value_get_char (&value) == 'z');
1169     g_value_unset (&value);
1170
1171     g_value_init (&value, G_TYPE_BOOLEAN);
1172     ag_account_get_value (account, "boolean", &value);
1173     fail_unless (g_value_get_boolean (&value) == TRUE);
1174     g_value_unset (&value);
1175
1176     fail_unless (ag_account_get_enabled (account) == FALSE);
1177
1178     /* watch some key changes/deletions */
1179     ag_account_watch_key (account, "character",
1180                           (AgAccountNotifyCb)changed_cb,
1181                           &character_changed);
1182
1183     ag_account_watch_key (account, "boolean",
1184                           (AgAccountNotifyCb)changed_cb,
1185                           &boolean_changed);
1186
1187     ag_account_watch_key (account, "unsigned",
1188                           (AgAccountNotifyCb)changed_cb,
1189                           &unsigned_changed);
1190
1191     ag_account_select_service (account, NULL);
1192     ag_account_watch_key (account, "string",
1193                           (AgAccountNotifyCb)changed_cb,
1194                           &string_changed);
1195     /* watch account enabledness */
1196     g_signal_connect (account, "enabled",
1197                       G_CALLBACK (on_enabled), &ecd);
1198
1199     character_changed = boolean_changed = string_changed =
1200         unsigned_changed = FALSE;
1201     memset (&ecd, 0, sizeof (ecd));
1202
1203     /* make changes remotely */
1204     sprintf (command, "test-process change %d", account_id);
1205     system (command);
1206
1207     source_id = g_timeout_add_seconds (2, concurrency_test_failed, NULL);
1208     g_main_loop_run (main_loop);
1209     fail_unless (source_id != 0, "Timeout happened");
1210     g_source_remove (source_id);
1211
1212     fail_unless (character_changed == TRUE);
1213     fail_unless (boolean_changed == TRUE);
1214     fail_unless (string_changed == TRUE);
1215     fail_unless (unsigned_changed == FALSE);
1216
1217     g_value_init (&value, G_TYPE_STRING);
1218     ag_account_get_value (account, "string", &value);
1219     fail_unless (g_strcmp0 (g_value_get_string (&value),
1220                             "another string") == 0);
1221     g_value_unset (&value);
1222
1223     ag_account_select_service (account, service);
1224
1225     g_value_init (&value, G_TYPE_CHAR);
1226     source = ag_account_get_value (account, "character", &value);
1227     fail_unless (source == AG_SETTING_SOURCE_NONE);
1228     g_value_unset (&value);
1229
1230     g_value_init (&value, G_TYPE_BOOLEAN);
1231     ag_account_get_value (account, "boolean", &value);
1232     fail_unless (g_value_get_boolean (&value) == FALSE);
1233     g_value_unset (&value);
1234
1235     fail_unless (ag_account_get_enabled (account) == TRUE);
1236
1237     /* verify that the signal has been emitted correctly */
1238     fail_unless (ecd.called == TRUE);
1239     fail_unless (ecd.enabled == TRUE);
1240     fail_unless (g_strcmp0 (ecd.service, "MyService") == 0);
1241
1242     end_test ();
1243 }
1244 END_TEST
1245
1246 START_TEST(test_service_regression)
1247 {
1248     GValue value = { 0 };
1249     AgAccountId account_id;
1250     const gchar *provider_name;
1251     const gchar *username = "me@myhome.com";
1252     const gint interval = 30;
1253     const gboolean check_automatically = TRUE;
1254     const gchar *display_name = "My test account";
1255     AgSettingSource source;
1256
1257     /* This test is to catch a bug that happened when creating a new
1258      * account and settings some service values before setting the display
1259      * name. The store operation would fail with error "column name is not
1260      * unique" because for some reason the same service ended up being
1261      * written twice into the DB.
1262      */
1263
1264     /* delete the database: this is essential because the bug was
1265      * reproducible only when the service was not yet in DB */
1266     g_unlink (db_filename);
1267
1268     g_type_init ();
1269
1270     manager = ag_manager_new ();
1271     account = ag_manager_create_account (manager, PROVIDER);
1272
1273     service = ag_manager_get_service (manager, "MyService");
1274     fail_unless (service != NULL);
1275
1276     ag_account_select_service (account, service);
1277
1278     /* enable the service */
1279     ag_account_set_enabled (account, TRUE);
1280
1281     g_value_init (&value, G_TYPE_STRING);
1282     g_value_set_static_string (&value, username);
1283     ag_account_set_value (account, "username", &value);
1284     g_value_unset (&value);
1285
1286     /* Change the display name (this is on the base account) */
1287     ag_account_set_display_name (account, display_name);
1288
1289     /* and some more service settings */
1290     g_value_init (&value, G_TYPE_BOOLEAN);
1291     g_value_set_boolean (&value, check_automatically);
1292     ag_account_set_value (account, "check_automatically", &value);
1293     g_value_unset (&value);
1294
1295     g_value_init (&value, G_TYPE_INT);
1296     g_value_set_int (&value, interval);
1297     ag_account_set_value (account, "interval", &value);
1298     g_value_unset (&value);
1299
1300     ag_account_store (account, account_store_now_cb, TEST_STRING);
1301     fail_unless (data_stored, "Callback not invoked immediately");
1302
1303     g_debug ("Service id: %d", service->id);
1304     g_debug ("Account id: %d", account->id);
1305     account_id = account->id;
1306
1307     g_object_unref (account);
1308     g_object_unref (manager);
1309
1310     manager = ag_manager_new ();
1311     account = ag_manager_get_account (manager, account_id);
1312     fail_unless (AG_IS_ACCOUNT (account),
1313                  "Couldn't load account %u", account_id);
1314
1315     provider_name = ag_account_get_provider_name (account);
1316     fail_unless (g_strcmp0 (provider_name, PROVIDER) == 0,
1317                  "Got provider %s, expecting %s", provider_name, PROVIDER);
1318
1319     /* check that the values are retained */
1320     fail_unless (g_strcmp0 (ag_account_get_display_name (account),
1321                          display_name) == 0,
1322                  "Display name not retained!");
1323
1324     ag_account_select_service (account, service);
1325
1326     /* we enabled the service before: check that it's still enabled */
1327     fail_unless (ag_account_get_enabled (account) == TRUE,
1328                  "Account service not enabled!");
1329
1330     g_value_init (&value, G_TYPE_STRING);
1331     source = ag_account_get_value (account, "username", &value);
1332     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
1333     fail_unless (g_strcmp0(g_value_get_string (&value), username) == 0,
1334                  "Wrong value");
1335     g_value_unset (&value);
1336
1337     g_value_init (&value, G_TYPE_BOOLEAN);
1338     source = ag_account_get_value (account, "check_automatically", &value);
1339     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
1340     fail_unless (g_value_get_boolean (&value) == check_automatically,
1341                  "Wrong value");
1342     g_value_unset (&value);
1343
1344     g_value_init (&value, G_TYPE_INT);
1345     source = ag_account_get_value (account, "interval", &value);
1346     fail_unless (source == AG_SETTING_SOURCE_ACCOUNT, "Wrong source");
1347     fail_unless (g_value_get_int (&value) == interval, "Wrong value");
1348     g_value_unset (&value);
1349
1350     end_test ();
1351 }
1352 END_TEST
1353
1354 START_TEST(test_blocking)
1355 {
1356     const gchar *display_name, *lock_filename;
1357     gchar command[512];
1358     gint timeout_ms, block_ms;
1359     GError *error = NULL;
1360     gboolean ok;
1361     struct timespec start_time, end_time;
1362     gint fd;
1363
1364     g_type_init ();
1365
1366     /* create an account */
1367     manager = ag_manager_new ();
1368     account = ag_manager_create_account (manager, PROVIDER);
1369     fail_unless (account != NULL);
1370     ag_account_set_display_name (account, "Blocked account");
1371     ok = ag_account_store_blocking (account, &error);
1372     fail_unless (ok, "Got error %s", error ? error->message : "No error set");
1373     fail_unless (account->id != 0);
1374
1375     display_name = ag_account_get_display_name (account);
1376     fail_unless (g_strcmp0 (display_name, "Blocked account") == 0,
1377                  "Wrong display name '%s'", display_name);
1378
1379     /* Now change the display name and make sure it's not updated
1380      * without storing :-) */
1381     ag_account_set_display_name (account, "Want to change");
1382     display_name = ag_account_get_display_name (account);
1383     fail_unless (g_strcmp0 (display_name, "Blocked account") == 0);
1384
1385
1386     /* Now start a process in the background to lock the DB for some time */
1387
1388     /* first, create a lock file to synchronize the test */
1389     lock_filename = "/tmp/check_ag.lock";
1390     fd = open (lock_filename, O_CREAT | O_RDWR, 0666);
1391
1392     timeout_ms = MAX_SQLITE_BUSY_LOOP_TIME_MS;
1393
1394     sprintf (command, "test-process lock_db %d %s &",
1395              timeout_ms, lock_filename);
1396     system (command);
1397
1398     /* wait till the file is locked */
1399     while (lockf(fd, F_TEST, 0) == 0)
1400         sched_yield();
1401
1402     clock_gettime (CLOCK_MONOTONIC, &start_time);
1403     ok = ag_account_store_blocking (account, &error);
1404     clock_gettime (CLOCK_MONOTONIC, &end_time);
1405
1406     /* the operation completed successfully */
1407     fail_unless (ok, "Got error %s", error ? error->message : "No error set");
1408
1409     /* make sure the display name changed */
1410     display_name = ag_account_get_display_name (account);
1411     fail_unless (g_strcmp0 (display_name, "Want to change") == 0);
1412
1413     /* make sure that we have been waiting for a reasonable time */
1414     block_ms = time_diff(&start_time, &end_time);
1415     g_debug ("Been blocking for %u ms", block_ms);
1416
1417     /* With WAL journaling, the DB might be locked for a much shorter time
1418      * than what we expect. The following line would fail in that case:
1419      *
1420      * fail_unless (block_ms > timeout_ms - 100);
1421      *
1422      * Instead, let's just check that we haven't been locking for too long:
1423      */
1424     fail_unless (block_ms < timeout_ms + 500);
1425
1426     end_test ();
1427 }
1428 END_TEST
1429
1430 #ifdef HAVE_AEGISCRYPTO
1431 START_TEST(test_sign_verify_key)
1432 {
1433     const gchar *key1 = "test_key/key1";
1434     const gchar *key2 = "test_key/key2";
1435     const gchar *list_of_tokens[] = { 
1436         "libaccounts-glib0::dummy", 
1437         "libaccounts-glib0::toodummy", 
1438         "libaccounts-glib0::accounts-glib-access", NULL };
1439     const gchar *token = "libaccounts-glib0::accounts-glib-access";
1440     const gchar *reply_token;
1441     const gchar *data = "some value 1";
1442     const gchar *data2 = "some value 2";
1443     gboolean ok;
1444     GValue value = { 0 };
1445     
1446     /* delete the database */
1447     g_unlink (db_filename);
1448
1449     g_type_init ();
1450     
1451     manager = ag_manager_new ();
1452     account = ag_manager_create_account (manager, PROVIDER);
1453
1454     AgService *service;
1455     service = ag_manager_get_service(manager, "MyService");
1456
1457     ag_account_set_enabled (account, TRUE);
1458
1459     g_value_init (&value, G_TYPE_STRING);
1460     g_value_set_static_string (&value, data);
1461     ag_account_set_value (account, key1, &value);
1462     g_value_unset (&value);
1463
1464     g_value_init (&value, G_TYPE_STRING);
1465     g_value_set_static_string (&value, data2);
1466     ag_account_set_value (account, key2, &value);
1467     g_value_unset (&value);
1468
1469     ag_account_store (account, account_store_now_cb, TEST_STRING);
1470     ok = ag_account_verify (account, key1, &reply_token);
1471     fail_unless (!ok);
1472
1473     ok = ag_account_verify_with_tokens (account, key2, list_of_tokens);
1474     fail_unless (!ok);
1475
1476     ag_account_sign (account, key1, token);
1477     ag_account_sign (account, key2, token);
1478
1479     ag_account_store (account, account_store_now_cb, TEST_STRING);
1480     fail_unless (data_stored, "Callback not invoked immediately");
1481
1482     fail_unless (account->id != 0, "Account ID is still 0!");
1483         
1484     ok = ag_account_verify (account, key1, &reply_token);
1485     fail_unless (ok);
1486
1487     ok = ag_account_verify_with_tokens (account, key2, list_of_tokens);
1488     fail_unless (ok);
1489
1490     /* testing with other service */
1491     AgService *service2;
1492     service2 = ag_manager_get_service(manager, "OtherService");
1493     ag_account_select_service (account, service2);
1494
1495     g_value_init (&value, G_TYPE_STRING);
1496     g_value_set_static_string (&value, data);
1497     ag_account_set_value (account, key1, &value);
1498     g_value_unset (&value);
1499
1500     g_value_init (&value, G_TYPE_STRING);
1501     g_value_set_static_string (&value, data2);
1502     ag_account_set_value (account, key2, &value);
1503     g_value_unset (&value);
1504
1505     ag_account_store (account, account_store_now_cb, TEST_STRING);
1506
1507     ok = ag_account_verify (account, key1, &reply_token);
1508     fail_unless (!ok);
1509
1510     ok = ag_account_verify_with_tokens (account, key2, list_of_tokens);
1511     fail_unless (!ok);
1512
1513     ag_account_sign (account, key1, token);
1514     ag_account_sign (account, key2, token);
1515
1516     ag_account_store (account, account_store_now_cb, TEST_STRING);
1517     fail_unless (data_stored, "Callback not invoked immediately");
1518
1519     fail_unless (account->id != 0, "Account ID is still 0!");
1520
1521     ok = ag_account_verify (account, key1, &reply_token);
1522     fail_unless (ok);
1523
1524     ok = ag_account_verify_with_tokens (account, key2, list_of_tokens);
1525
1526     fail_unless (ok);
1527     
1528     end_test ();
1529 }
1530 END_TEST
1531 #endif
1532
1533 START_TEST(test_cache_regression)
1534 {
1535     AgAccountId account_id1, account_id2;
1536     const gchar *provider1 = "first_provider";
1537     const gchar *provider2 = "second_provider";
1538     const gchar *display_name1 = "first_displayname";
1539     const gchar *display_name2 = "second_displayname";
1540
1541     /* This test is to catch a bug that happened when deleting the account
1542      * with the highest ID without letting the object die, and creating a
1543      * new account: the account manager would still return the old account!
1544      */
1545
1546     /* delete the database */
1547     g_unlink (db_filename);
1548
1549     g_type_init ();
1550
1551     manager = ag_manager_new ();
1552     account = ag_manager_create_account (manager, provider1);
1553     fail_unless (account != NULL);
1554
1555     ag_account_set_display_name (account, display_name1);
1556
1557     ag_account_store (account, account_store_now_cb, TEST_STRING);
1558     fail_unless (data_stored, "Callback not invoked immediately");
1559
1560     account_id1 = account->id;
1561
1562     /* now remove the account, but don't destroy the object */
1563     ag_account_delete (account);
1564
1565     ag_account_store (account, account_store_now_cb, TEST_STRING);
1566     fail_unless (data_stored, "Callback not invoked immediately");
1567
1568     /* after deleting the account, we shouldn't get it anymore, even if we
1569      * didn't release our reference */
1570     account = ag_manager_get_account (manager, account_id1);
1571     fail_unless (account == NULL);
1572
1573     /* create another account */
1574     account = ag_manager_create_account (manager, provider2);
1575     fail_unless (account != NULL);
1576
1577     ag_account_set_display_name (account, display_name2);
1578
1579     ag_account_store (account, account_store_now_cb, TEST_STRING);
1580     fail_unless (data_stored, "Callback not invoked immediately");
1581
1582     account_id2 = account->id;
1583
1584     /* check that the values are the correct ones */
1585     fail_unless (g_strcmp0 (ag_account_get_display_name (account),
1586                          display_name2) == 0);
1587
1588     fail_unless (g_strcmp0 (ag_account_get_provider_name (account),
1589                          provider2) == 0);
1590
1591     end_test ();
1592 }
1593 END_TEST
1594
1595 START_TEST(test_serviceid_regression)
1596 {
1597     AgAccount *account1, *account2;
1598     AgManager *manager1, *manager2;
1599     AgService *service1, *service2;
1600     const gchar *provider = "first_provider";
1601
1602     /* This test is to catch a bug that happened when creating two accounts
1603      * having the same service, from two different instances of the
1604      * manager: the creation of the second account would fail.
1605      * Precondition: empty DB.
1606      */
1607
1608     /* delete the database */
1609     g_unlink (db_filename);
1610
1611     g_type_init ();
1612
1613     manager1 = ag_manager_new ();
1614     manager2 = ag_manager_new ();
1615
1616     account1 = ag_manager_create_account (manager1, provider);
1617     fail_unless (account1 != NULL);
1618     account2 = ag_manager_create_account (manager2, provider);
1619     fail_unless (account2 != NULL);
1620
1621     service1 = ag_manager_get_service (manager1, "MyService");
1622     fail_unless (service1 != NULL);
1623     service2 = ag_manager_get_service (manager2, "MyService");
1624     fail_unless (service2 != NULL);
1625
1626     ag_account_select_service (account1, service1);
1627     ag_account_set_enabled (account1, TRUE);
1628     ag_account_select_service (account2, service2);
1629     ag_account_set_enabled (account2, FALSE);
1630
1631     ag_account_store (account1, account_store_now_cb, TEST_STRING);
1632     fail_unless (data_stored, "Callback not invoked immediately");
1633
1634     ag_account_store (account2, account_store_now_cb, TEST_STRING);
1635     fail_unless (data_stored, "Callback not invoked immediately");
1636
1637     fail_unless (account1->id != 0);
1638     fail_unless (account2->id != 0);
1639
1640     /* clear up */
1641     ag_service_unref (service1);
1642     ag_service_unref (service2);
1643     g_object_unref (account1);
1644     g_object_unref (account2);
1645     g_object_unref (manager1);
1646     g_object_unref (manager2);
1647
1648     end_test ();
1649 }
1650 END_TEST
1651
1652 static void
1653 check_enabled (AgAccount *account, const gchar *service, gboolean enabled,
1654                gboolean *check)
1655 {
1656     *check = ( ag_account_get_enabled(account) == enabled );
1657 }
1658
1659 START_TEST(test_enabled_regression)
1660 {
1661     gboolean check = FALSE;
1662
1663     g_type_init();
1664
1665     manager = ag_manager_new ();
1666     account = ag_manager_create_account (manager, PROVIDER);
1667
1668     fail_unless (account != NULL);
1669
1670     g_signal_connect (account, "enabled",
1671                       G_CALLBACK (check_enabled),
1672                       &check);
1673
1674     ag_account_set_enabled (account, TRUE);
1675     ag_account_store (account, NULL, TEST_STRING);
1676
1677     fail_unless (check, "Settings are not updated!");
1678
1679     ag_account_set_enabled (account, FALSE);
1680     ag_account_store (account, NULL, TEST_STRING);
1681
1682     fail_unless (check, "Settings are not updated!");
1683
1684     end_test ();
1685 }
1686 END_TEST
1687
1688 START_TEST(test_manager_new_for_service_type)
1689 {
1690     AgAccount *account1, *account2;
1691     AgService *service1, *service2;
1692     AgManager *manager2;
1693     const gchar *provider = "first_provider";
1694     GList *list;
1695
1696     /* delete the database */
1697     g_unlink (db_filename);
1698
1699     g_type_init ();
1700
1701     manager2 = ag_manager_new();
1702     manager = ag_manager_new_for_service_type ("e-mail");
1703     fail_unless (g_strcmp0 (ag_manager_get_service_type (manager),
1704                          "e-mail") == 0);
1705
1706     account1 = ag_manager_create_account (manager, provider);
1707     fail_unless (account1 != NULL);
1708     account2 = ag_manager_create_account (manager, provider);
1709     fail_unless (account2 != NULL);
1710
1711     service1 = ag_manager_get_service (manager, "MyService");
1712     fail_unless (service1 != NULL);
1713     service2 = ag_manager_get_service (manager, "OtherService");
1714     fail_unless (service2 != NULL);
1715
1716     ag_account_set_enabled (account1, TRUE);
1717     ag_account_select_service (account1, service1);
1718     ag_account_set_enabled (account1, TRUE);
1719     ag_account_set_enabled (account2, TRUE);
1720     ag_account_select_service (account2, service2);
1721     ag_account_set_enabled (account2, FALSE);
1722
1723     ag_account_store (account1, account_store_now_cb, TEST_STRING);
1724     fail_unless (data_stored, "Callback not invoked immediately");
1725     ag_account_store (account2, account_store_now_cb, TEST_STRING);
1726     fail_unless (data_stored, "Callback not invoked immediately");
1727
1728     fail_unless (account1->id != 0);
1729     fail_unless (account2->id != 0);
1730
1731     list = ag_manager_list_enabled_by_service_type (manager, "e-mail");
1732     fail_unless (g_list_length (list) == 1);
1733     fail_unless (account1->id == GPOINTER_TO_INT(list->data));
1734
1735     /* clear up */
1736     ag_service_unref (service1);
1737     ag_service_unref (service2);
1738     g_object_unref (account1);
1739     g_object_unref (account2);
1740     ag_manager_list_free (list);
1741
1742     end_test ();
1743 }
1744 END_TEST
1745
1746 static void
1747 on_enabled_event (AgManager *manager, AgAccountId account_id,
1748                   AgAccountId *id)
1749 {
1750     g_debug ("%s called (%u)", G_STRFUNC, account_id);
1751     AgAccount *acc;
1752     AgService *service;
1753
1754     acc = ag_manager_get_account (manager, account_id);
1755     fail_unless (acc != NULL);
1756     fail_unless (ag_account_get_enabled (acc));
1757
1758     service = ag_manager_get_service (manager, "MyService");
1759     fail_unless (service != NULL);
1760     ag_account_select_service (acc, service);
1761     fail_unless (ag_account_get_enabled (acc));
1762
1763     *id = account_id;
1764
1765     g_main_loop_quit (main_loop);
1766 }
1767
1768 static gboolean
1769 enabled_event_test_failed (gpointer userdata)
1770 {
1771     g_debug ("Timeout");
1772     g_main_loop_quit (main_loop);
1773     source_id = 0;
1774     return FALSE;
1775 }
1776
1777 START_TEST(test_manager_enabled_event)
1778 {
1779     g_type_init();
1780
1781     /* delete the database */
1782     g_unlink (db_filename);
1783
1784     /* watch account enabledness */
1785     gchar command[512];
1786     AgAccountId source_id;
1787     AgAccountId account_id = 0;
1788
1789     manager = ag_manager_new_for_service_type ("e-mail");
1790     fail_unless (manager != NULL);
1791     account = ag_manager_create_account (manager, "maemo");
1792     fail_unless (account != NULL);
1793
1794     ag_account_set_enabled (account, TRUE);
1795     ag_account_store (account, account_store_now_cb, TEST_STRING);
1796     fail_unless (data_stored, "Callback not invoked immediately");
1797
1798     main_loop = g_main_loop_new (NULL, FALSE);
1799
1800     g_signal_connect (manager, "enabled-event",
1801                       G_CALLBACK (on_enabled_event), &account_id);
1802
1803     /* this command will enable MyService (which is of type e-mail) */
1804     sprintf (command, "test-process enabled_event %d", account->id);
1805     system (command);
1806
1807     source_id = g_timeout_add_seconds (2, enabled_event_test_failed, NULL);
1808     g_main_loop_run (main_loop);
1809     fail_unless (source_id != 0, "Timeout happened");
1810     g_source_remove (source_id);
1811
1812     fail_unless (account_id == account->id);
1813
1814     account_id = 0;
1815
1816     /* now disable the account. This also should trigger the enabled-event. */
1817     sprintf (command, "test-process enabled_event2 %d", account->id);
1818     system (command);
1819
1820     source_id = g_timeout_add_seconds (2, enabled_event_test_failed, NULL);
1821     g_main_loop_run (main_loop);
1822     fail_unless (source_id != 0, "Timeout happened");
1823     g_source_remove (source_id);
1824
1825     fail_unless (account_id == account->id);
1826
1827     end_test ();
1828 }
1829 END_TEST
1830
1831 START_TEST(test_list_enabled_account)
1832 {
1833     GList *list = NULL;
1834     AgAccount *account1 = NULL;
1835     AgAccount *account2 = NULL;
1836     GList *iter = NULL;
1837     gboolean found = FALSE;
1838     AgAccount *account3 = NULL;
1839     const gchar *name = NULL;
1840
1841     g_type_init ();
1842     manager = ag_manager_new ();
1843     fail_unless (manager != NULL, "Manager should not be NULL");
1844
1845     account1 = ag_manager_create_account (manager, "MyProvider");
1846     fail_unless (AG_IS_ACCOUNT (account1),
1847                  "Failed to create the AgAccount.");
1848     ag_account_set_display_name (account1, "EnabledAccount");
1849     ag_account_set_enabled (account1, TRUE);
1850     ag_account_store (account1, account_store_now_cb, TEST_STRING);
1851
1852     account2 = ag_manager_create_account (manager, "MyProvider");
1853     fail_unless (AG_IS_ACCOUNT (account2),
1854                  "Failed to create the AgAccount.");
1855     ag_account_set_display_name (account2, "DisabledAccount");
1856     ag_account_set_enabled (account2, FALSE);
1857     ag_account_store (account2, account_store_now_cb, TEST_STRING);
1858
1859
1860     list = ag_manager_list_enabled (manager);
1861     fail_unless (g_list_length (list) > 0,
1862                  "No enabled accounts?");
1863
1864     for (iter = list; iter != NULL; iter = g_list_next (iter))
1865     {
1866         account3 = ag_manager_get_account (manager,
1867                                            GPOINTER_TO_UINT (iter->data));
1868
1869         name = ag_account_get_display_name (account3);
1870         if (strcmp (name, "EnabledAccount") == 0)
1871         {
1872             found = TRUE;
1873             break;
1874         }
1875         g_object_unref (account3);
1876         account3 = NULL;
1877     }
1878
1879     fail_unless (found == TRUE, "Required account not enabled");
1880
1881     if (account3)
1882         g_object_unref (account3);
1883     if (account2)
1884         g_object_unref (account2);
1885     if (account1)
1886         g_object_unref (account1);
1887
1888     ag_manager_list_free (list);
1889
1890     end_test ();
1891 }
1892 END_TEST
1893
1894 START_TEST(test_account_list_enabled_services)
1895 {
1896     GList *services;
1897     gint n_services;
1898     AgService *service1, *service2;
1899
1900     /*
1901      * Two additional managers:
1902      * manager2 : e-mail type
1903      * manager3 : sharing type
1904      * */
1905     AgManager *manager2, *manager3;
1906
1907     /*
1908      * Same instances of account:
1909      * account2: from e-mail type manager
1910      * account3: from sharing manager
1911      * */
1912     AgAccount *account2, *account3;
1913
1914     /*
1915      * new account for the same manager
1916      * */
1917     AgAccount *account4;
1918
1919     g_type_init ();
1920
1921     /* delete the database */
1922     g_unlink (db_filename);
1923
1924     manager = ag_manager_new ();
1925     fail_unless (manager != NULL);
1926
1927     manager2 = ag_manager_new_for_service_type ("e-mail");
1928     fail_unless (manager2 != NULL);
1929
1930     manager3 = ag_manager_new_for_service_type ("sharing");
1931     fail_unless (manager3 != NULL);
1932
1933     account = ag_manager_create_account (manager, "maemo");
1934     fail_unless (account != NULL);
1935
1936     service1 = ag_manager_get_service (manager, "MyService");
1937     fail_unless (service1 != NULL);
1938     service2 = ag_manager_get_service (manager, "OtherService");
1939     fail_unless (service2 != NULL);
1940
1941     /* 2 services, 1 enabled  */
1942     ag_account_select_service (account, service1);
1943     ag_account_set_enabled (account, TRUE);
1944     ag_account_store (account, account_store_now_cb, TEST_STRING);
1945
1946     ag_account_select_service (account, service2);
1947     ag_account_set_enabled (account, FALSE);
1948     ag_account_store (account, account_store_now_cb, TEST_STRING);
1949
1950     services = ag_account_list_enabled_services (account);
1951     n_services = g_list_length (services);
1952     fail_unless (n_services == 1, "Got %d services, expecting 1", n_services);
1953     ag_manager_list_free (services);
1954
1955     /* 2 services, 2 enabled  */
1956     ag_account_select_service (account, service2);
1957     ag_account_set_enabled (account, TRUE);
1958     ag_account_store (account, account_store_now_cb, TEST_STRING);
1959
1960     services = ag_account_list_enabled_services (account);
1961
1962     n_services = g_list_length (services);
1963     fail_unless (n_services == 2, "Got %d services, expecting 2", n_services);
1964     ag_manager_list_free (services);
1965
1966     account2 = ag_manager_get_account (manager2, account->id);
1967     fail_unless (account2 != NULL);
1968
1969     account3 = ag_manager_get_account (manager3, account->id);
1970     fail_unless (account3 != NULL);
1971
1972     services = ag_account_list_enabled_services (account2);
1973
1974     n_services = g_list_length (services);
1975     fail_unless (n_services == 1, "Got %d services, expecting 1", n_services);
1976     ag_manager_list_free (services);
1977
1978     services = ag_account_list_enabled_services (account3);
1979
1980     n_services = g_list_length (services);
1981     fail_unless (n_services == 1, "Got %d services, expecting 1", n_services);
1982     ag_manager_list_free (services);
1983
1984     /* 2 services, 0 enabled  */
1985     account4 = ag_manager_create_account (manager, "maemo");
1986     fail_unless (account4 != NULL);
1987
1988     ag_account_select_service (account, service1);
1989     ag_account_set_enabled (account, FALSE);
1990
1991     ag_account_select_service (account, service2);
1992     ag_account_set_enabled (account, FALSE);
1993
1994     ag_account_store (account, account_store_now_cb, TEST_STRING);
1995
1996     ag_account_select_service (account4, service2);
1997     ag_account_set_enabled (account4, TRUE);
1998     ag_account_store (account4, account_store_now_cb, TEST_STRING);
1999
2000     services = ag_account_list_enabled_services (account);
2001
2002     n_services = g_list_length (services);
2003     fail_unless (n_services == 0, "Got %d services, expecting 0", n_services);
2004     services = ag_account_list_enabled_services (account);
2005     /* clear up */
2006     ag_service_unref (service1);
2007     ag_service_unref (service2);
2008     ag_manager_list_free (services);
2009
2010     g_object_unref (account2);
2011     g_object_unref (account3);
2012     g_object_unref (account4);
2013     g_object_unref (manager2);
2014     g_object_unref (manager3);
2015
2016     end_test ();
2017 }
2018 END_TEST
2019
2020 START_TEST(test_service_type)
2021 {
2022     const gchar *string;
2023     AgServiceType *service_type;
2024
2025     g_type_init ();
2026
2027     manager = ag_manager_new ();
2028
2029     service_type = ag_manager_load_service_type (manager, "I don't exist");
2030     fail_unless (service_type == NULL);
2031
2032     service_type = ag_manager_load_service_type (manager, "e-mail");
2033     fail_unless (service_type != NULL);
2034
2035     string = ag_service_type_get_name (service_type);
2036     fail_unless (g_strcmp0 (string, "e-mail") == 0,
2037                  "Wrong service type name: %s", string);
2038
2039     string = ag_service_type_get_display_name (service_type);
2040     fail_unless (g_strcmp0 (string, "Electronic mail") == 0,
2041                  "Wrong service type display name: %s", string);
2042
2043     string = ag_service_type_get_icon_name (service_type);
2044     fail_unless (g_strcmp0 (string, "email_icon") == 0,
2045                  "Wrong service type icon name: %s", string);
2046
2047     string = ag_service_type_get_i18n_domain (service_type);
2048     fail_unless (g_strcmp0 (string, "translation_file") == 0,
2049                  "Wrong service type i18n name: %s", string);
2050
2051     end_test ();
2052 }
2053 END_TEST
2054
2055 static void
2056 on_account_created_with_db_locked (AgManager *manager, AgAccountId account_id)
2057 {
2058     AgAccount *account;
2059     AgService *service;
2060     const gchar *name;
2061     GList *list;
2062
2063     g_debug ("%s called (%u)", G_STRFUNC, account_id);
2064
2065     account = ag_manager_get_account (manager, account_id);
2066     fail_unless (account != NULL);
2067
2068     g_debug ("account loaded");
2069     list = ag_account_list_enabled_services (account);
2070     fail_unless (list != NULL);
2071     fail_unless (g_list_length (list) == 1);
2072
2073     service = list->data;
2074     fail_unless (service != NULL);
2075     fail_unless (service->id != 0);
2076
2077     name = ag_service_get_name (service);
2078     fail_unless (strcmp (name, "MyService") == 0);
2079
2080     ag_service_list_free (list);
2081     g_main_loop_quit (main_loop);
2082 }
2083
2084 START_TEST(test_db_access)
2085 {
2086     const gchar *lock_filename;
2087     gchar command[512];
2088     gint timeout_ms;
2089     gint fd;
2090
2091     /* This test is for making sure that no DB accesses occur while certain
2092      * events occur.
2093      *
2094      * Checked scenarios:
2095      *
2096      * - when another process creates an account and we get the
2097      *   account-created signal and call
2098      *   ag_account_list_enabled_services(), we shouldn't be blocked.
2099      */
2100     g_type_init ();
2101
2102     /* first, create a lock file to synchronize the test */
2103     lock_filename = "/tmp/check_ag.lock";
2104     fd = open (lock_filename, O_CREAT | O_RDWR, 0666);
2105
2106     timeout_ms = 2000; /* two seconds */
2107
2108     manager = ag_manager_new ();
2109     ag_manager_set_db_timeout (manager, 0);
2110     ag_manager_set_abort_on_db_timeout (manager, TRUE);
2111     g_signal_connect (manager, "account-created",
2112                       G_CALLBACK (on_account_created_with_db_locked), NULL);
2113
2114     /* create an account with the e-mail service type enabled */
2115     system ("test-process create3 myprovider MyAccountName");
2116
2117     /* lock the DB for the specified timeout */
2118     sprintf (command, "test-process lock_db %d %s &",
2119              timeout_ms, lock_filename);
2120     system (command);
2121
2122     /* wait till the file is locked */
2123     while (lockf (fd, F_TEST, 0) == 0)
2124         sched_yield ();
2125
2126     /* now the DB is locked; we iterate the main loop to get the signals
2127      * about the account creation and do some operations with the account.
2128      * We expect to never get any error because of the locked DB, as the
2129      * methods we are calling should not access it */
2130
2131     main_loop = g_main_loop_new (NULL, FALSE);
2132     source_id = g_timeout_add_seconds (timeout_ms / 1000,
2133                                        concurrency_test_failed, NULL);
2134     g_debug ("Running loop");
2135     g_main_loop_run (main_loop);
2136
2137     fail_unless (source_id != 0, "Timeout happened");
2138     g_source_remove (source_id);
2139
2140     end_test ();
2141 }
2142 END_TEST
2143
2144 Suite *
2145 ag_suite(const char *test_case)
2146 {
2147     Suite *s = suite_create ("accounts-glib");
2148
2149 #define IF_TEST_CASE_ENABLED(test_name) \
2150     if (test_case == NULL || strcmp (test_name, test_case) == 0)
2151
2152     TCase *tc;
2153
2154     tc = tcase_create("Core");
2155     tcase_add_test (tc, test_init);
2156     IF_TEST_CASE_ENABLED("Core")
2157         suite_add_tcase (s, tc);
2158
2159     tc = tcase_create("Create");
2160     tcase_add_test (tc, test_object);
2161     tcase_add_test (tc, test_provider);
2162     IF_TEST_CASE_ENABLED("Create")
2163         suite_add_tcase (s, tc);
2164
2165     tc = tcase_create("Store");
2166     tcase_add_test (tc, test_store);
2167     tcase_add_test (tc, test_store_locked);
2168     tcase_add_test (tc, test_store_locked_unref);
2169     IF_TEST_CASE_ENABLED("Store")
2170         suite_add_tcase (s, tc);
2171
2172     tc = tcase_create("Service");
2173     tcase_add_test (tc, test_service);
2174     tcase_add_test (tc, test_account_services);
2175     tcase_add_test (tc, test_settings_iter);
2176     tcase_add_test (tc, test_service_type);
2177     IF_TEST_CASE_ENABLED("Service")
2178         suite_add_tcase (s, tc);
2179
2180     tc = tcase_create("List");
2181     tcase_add_test (tc, test_list);
2182     tcase_add_test (tc, test_list_enabled_account);
2183     tcase_add_test (tc, test_list_services);
2184     tcase_add_test (tc, test_account_list_enabled_services);
2185     IF_TEST_CASE_ENABLED("List")
2186         suite_add_tcase (s, tc);
2187
2188     tc = tcase_create("Signalling");
2189     tcase_add_test (tc, test_signals);
2190     tcase_add_test (tc, test_delete);
2191     tcase_add_test (tc, test_watches);
2192     IF_TEST_CASE_ENABLED("Signalling")
2193         suite_add_tcase (s, tc);
2194
2195     tc = tcase_create("Concurrency");
2196     tcase_add_test (tc, test_concurrency);
2197     tcase_add_test (tc, test_blocking);
2198 #ifdef HAVE_AEGISCRYPTO
2199     tcase_add_test (tc, test_sign_verify_key);
2200 #endif
2201     tcase_add_test (tc, test_manager_new_for_service_type);
2202     tcase_add_test (tc, test_manager_enabled_event);
2203     /* Tests for ensuring that opening and reading from a locked DB was
2204      * delayed have been removed since WAL journaling has been introduced:
2205      * they were failing, because with WAL journaling a writer does not
2206      * block readers.
2207      * Should we even need those tests back, they can be found in the git
2208      * history.
2209      */
2210     tcase_set_timeout (tc, 10);
2211     IF_TEST_CASE_ENABLED("Concurrency")
2212         suite_add_tcase (s, tc);
2213
2214     tc = tcase_create("Regression");
2215     tcase_add_test (tc, test_service_regression);
2216     tcase_add_test (tc, test_cache_regression);
2217     tcase_add_test (tc, test_serviceid_regression);
2218     tcase_add_test (tc, test_enabled_regression);
2219     IF_TEST_CASE_ENABLED("Regression")
2220         suite_add_tcase (s, tc);
2221
2222     tc = tcase_create("Caching");
2223     tcase_add_test (tc, test_db_access);
2224     tcase_set_timeout (tc, 10);
2225     IF_TEST_CASE_ENABLED("Caching")
2226         suite_add_tcase (s, tc);
2227
2228     return s;
2229 }
2230
2231 int main(int argc, char **argv)
2232 {
2233     int number_failed;
2234     const char *test_case = NULL;
2235
2236     if (argc > 1)
2237         test_case = argv[1];
2238
2239     Suite * s = ag_suite(test_case);
2240     SRunner * sr = srunner_create(s);
2241
2242     db_filename = g_build_filename (g_getenv ("ACCOUNTS"), "accounts.db",
2243                                     NULL);
2244
2245     srunner_set_xml(sr, "/tmp/result.xml");
2246     srunner_run_all(sr, CK_NORMAL);
2247     number_failed = srunner_ntests_failed(sr);
2248     srunner_free (sr);
2249
2250     g_free (db_filename);
2251
2252     return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
2253 }
2254
2255 /* vim: set ai et tw=75 ts=4 sw=4: */
2256