update for beta universally
[framework/base/gconf-dbus.git] / dbus-tests / test-stale-value-bug.c
1 /* Tests for a bug that made blablabla... FIXME: summary */
2
3 #include <math.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <gconf/gconf-client.h>
7
8 #define KEY_ROOT      "/foo"
9 #define KEY_UNCACHED  KEY_ROOT "/baz_primitive"
10 #define KEY_PRIMITIVE KEY_ROOT "/bar/baz_primitive"
11 #define KEY_PAIR      KEY_ROOT "/bar/baz_pair"
12 #define KEY_LIST      KEY_ROOT "/bar/baz_list"
13
14 #define DELTA         0.0001
15
16 static GConfClient *client;
17 static GMainLoop   *loop;
18
19 static gboolean
20 check_string (const gchar *key, const gchar *expected)
21 {
22         gchar    *str;
23         GError   *error = NULL;
24         gboolean  ret;
25
26         str = gconf_client_get_string (client, key, &error);
27         if (error) {
28                 g_error_free (error);
29                 return FALSE;
30         } 
31
32         if (!str) {
33                 g_warning ("String value is NULL\n");
34                 return FALSE;
35         }
36         
37         ret = strcmp (str, expected) == 0;
38
39         g_free (str);
40
41         return ret;
42 }
43
44 static gboolean
45 check_int (const gchar *key, gint expected)
46 {
47         gint    i;
48         GError *error = NULL;
49
50         i = gconf_client_get_int (client, key, &error);
51
52         if (error) {
53                 g_error_free (error);
54                 i = 0;
55         }
56
57         return i == expected;
58 }
59
60 static gboolean
61 check_float (const gchar *key, gdouble expected)
62 {
63         gdouble  f;
64         GError  *error = NULL;
65
66         f = gconf_client_get_float (client, key, &error);
67         if (error) {
68                 g_error_free (error);
69                 f = 0;
70         }
71
72         return fabs (f - expected) < DELTA;
73 }
74
75 static gboolean
76 check_pair (const gchar *key, gint expected_i, gdouble expected_f)
77 {
78         gint    i;
79         gdouble  f;
80         GError *error = NULL;
81
82         gconf_client_get_pair (client, key,
83                                GCONF_VALUE_INT, GCONF_VALUE_FLOAT,
84                                &i, &f, &error);
85         if (error) {
86                 g_error_free (error);
87                 i = 0;
88                 f = 0;
89         }
90
91         return (i == expected_i && fabs (f - expected_f) < DELTA);
92 }
93
94 static gboolean
95 check_list (const gchar *key, gint expected_1, gint expected_2, gint expected_3)
96 {
97         gint    i1, i2, i3;
98         GError *error = NULL;
99         GSList *list;
100
101         list = gconf_client_get_list (client, key, GCONF_VALUE_INT, &error);
102         if (error) {
103                 g_error_free (error);
104                 i1 = i2 = i3 = 0;
105         } else {
106                 if (g_slist_length (list) != 3) {
107                         return FALSE;
108                 }
109
110                 /* ye ye, efficiency ;) */
111                 i1 = GPOINTER_TO_INT (g_slist_nth_data (list, 0));
112                 i2 = GPOINTER_TO_INT (g_slist_nth_data (list, 1));
113                 i3 = GPOINTER_TO_INT (g_slist_nth_data (list, 2));
114         }
115
116         g_slist_free (list);
117         
118         return (i1 == expected_1 && i2 == expected_2 && i3 == expected_3);
119 }
120
121 /* Checks that everything below "key" is gone. */
122 static gboolean
123 check_recursive_unset (void)
124 {
125         GError     *error = NULL;
126         gboolean    exists;
127         GConfValue *value;
128
129         exists = gconf_client_dir_exists (client, KEY_ROOT, &error);
130         if (error) {
131                 g_print ("Error when checking if root exists: %s\n", error->message);
132                 g_error_free (error);
133                 return FALSE;
134         }
135         if (exists) {
136                 /* Note that this might exist or might not. Upstream behaves
137                  * like this too for directories. The values are unset but the
138                  * directory structure still exists, until the next time the
139                  * database is synced to disk.
140                  */
141                 /*g_print ("Root exists: %s\n", KEY_ROOT);
142                   return FALSE;*/
143         }
144
145         exists = gconf_client_dir_exists (client, KEY_ROOT "/bar", &error);
146         if (error) {
147                 g_print ("Error when checking if dir exists: %s\n", error->message);
148                 g_error_free (error);
149                 return FALSE;
150         }
151         if (exists) {
152                 /* Same as above. */
153                 /*g_print ("Subdirectory exists: %s\n", KEY_ROOT "/bar");
154                   return FALSE;*/
155         }
156
157         value = gconf_client_get (client, KEY_PRIMITIVE, &error);
158         if (error) {
159                 g_print ("Error when checking primitie key: %s\n", error->message);
160                 g_error_free (error);
161                 return FALSE;
162         }
163         if (value) {
164                 g_print ("Primitive key exists: %s\n", gconf_value_to_string (value));
165                 gconf_value_free (value);
166                 return FALSE;
167         }
168         
169         value = gconf_client_get (client, KEY_PAIR, &error);
170         if (error) {
171                 g_print ("Error when checking pair key: %s\n", error->message);
172                 g_error_free (error);
173                 return FALSE;
174         }
175         if (value) {
176                 g_print ("Pair key exists: %s\n", gconf_value_to_string (value));
177                 gconf_value_free (value);
178                 return FALSE;
179         }
180         
181         value = gconf_client_get (client, KEY_LIST, &error);
182         if (error) {
183                 g_print ("Error when checking list key: %s\n", error->message);
184                 g_error_free (error);
185                 return FALSE;
186         }
187         if (value) {
188                 g_print ("List key exists: %s\n", gconf_value_to_string (value));
189                 gconf_value_free (value);
190                 return FALSE;
191         }
192         
193         return TRUE;
194 }
195
196 static gboolean
197 change_timeout_func (gpointer data)
198 {
199         static gint  count = 0;
200         gchar       *s;
201         gint         i, i1, i2, i3;
202         gdouble      f;
203         GSList      *list;
204
205         /* String, uncached. */
206         s = g_strdup_printf ("test-%d", g_random_int_range (1, 100));
207         gconf_client_set_string (client, KEY_UNCACHED, s, NULL);
208         if (!check_string (KEY_UNCACHED, s)) {
209                 g_print ("Uncached string FAILED\n");
210                 exit (1);
211         }
212         g_free (s);
213         
214         /* String. */
215         s = g_strdup_printf ("test-%d", g_random_int_range (1, 100));
216         gconf_client_set_string (client, KEY_PRIMITIVE, s, NULL);
217         if (!check_string (KEY_PRIMITIVE, s)) {
218                 g_print ("String FAILED\n");
219                 exit (1);
220         }
221         g_free (s);
222         
223         /* Int. */
224         i = g_random_int_range (1, 100);
225         gconf_client_set_int (client, KEY_PRIMITIVE, i, NULL);
226         if (!check_int (KEY_PRIMITIVE, i)) {
227                 g_print ("Int FAILED\n");
228                 exit (1);
229         }
230         
231         /* Float. */
232         f = g_random_int_range (1, 1000) / 10.0;
233         gconf_client_set_float (client, KEY_PRIMITIVE, f, NULL);
234         if (!check_float (KEY_PRIMITIVE, f)) {
235                 g_print ("Float FAILED\n");
236                 exit (1);
237         }
238         
239         /* Pair (int, float). */
240         i = g_random_int_range (1, 1000);
241         f = g_random_int_range (1, 10000) / 37.2;
242
243         gconf_client_set_pair (client, KEY_PAIR,
244                                GCONF_VALUE_INT,
245                                GCONF_VALUE_FLOAT,
246                                &i, &f, NULL);
247         if (!check_pair (KEY_PAIR, i, f)) {
248                 g_print ("Pair FAILED\n");
249                 exit (1);
250         }
251
252         /* List of ints. */
253         i1 = g_random_int_range (1, 1000);
254         i2 = g_random_int_range (1, 1000);
255         i3 = g_random_int_range (1, 1000);
256
257         list = g_slist_append (NULL, GINT_TO_POINTER (i1));
258         list = g_slist_append (list, GINT_TO_POINTER (i2));
259         list = g_slist_append (list, GINT_TO_POINTER (i3));
260         gconf_client_set_list (client, KEY_LIST,
261                                GCONF_VALUE_INT,
262                                list, NULL);
263         if (!check_list (KEY_LIST, i1, i2, i3)) {
264                 g_print ("List FAILED\n");
265                 exit (1);
266         }
267
268         g_slist_free (list);
269         
270         /* Unset int. */
271         i = g_random_int_range (1, 100);
272         gconf_client_set_int (client, KEY_PRIMITIVE, i, NULL);
273         if (!check_int (KEY_PRIMITIVE, i)) {
274                 g_print ("Unset FAILED\n");
275                 exit (1);
276         }
277         gconf_client_unset (client, KEY_PRIMITIVE, NULL);
278         if (!check_int (KEY_PRIMITIVE, 0)) { /* We get 0 as unset... */
279                 g_print ("Unset FAILED\n");
280                 exit (1);
281         }
282         
283         /* Recursive unset. Unset the entire subtree and check that all the keys
284          * are non-existing.
285          */
286         g_assert (gconf_client_recursive_unset (client, KEY_ROOT, 0, NULL) == TRUE);
287         if (!check_recursive_unset ()) {
288                 g_print ("Recursive unset FAILED\n");
289                 exit (1);
290         }
291
292         g_print ("Run %d completed.\n", ++count);
293         
294         if (count == 3 || count == 6 || count == 9) {
295                 g_main_loop_quit (loop);
296                 return FALSE;
297         }
298         
299         return TRUE;
300 }
301
302 int
303 main (int argc, char **argv)
304 {
305         g_type_init ();
306
307         client = gconf_client_get_default ();
308
309         /* Start out clean in case anything is left from earlier runs. */
310         gconf_client_recursive_unset (client, KEY_ROOT, 0, NULL);
311                 
312         /* We add "/foo/bar" so that "/foo" is uncached to test both those
313          * cases.
314          */
315         gconf_client_add_dir (client,
316                               "/foo/bar",
317                               GCONF_CLIENT_PRELOAD_RECURSIVE,
318                               NULL);
319
320         loop = g_main_loop_new (NULL, FALSE);
321         
322         g_idle_add (change_timeout_func, NULL);
323         g_main_loop_run (loop);
324
325         g_timeout_add (500, change_timeout_func, NULL);
326         g_main_loop_run (loop);
327
328         g_idle_add (change_timeout_func, NULL);
329         g_main_loop_run (loop);
330
331         g_object_unref (client);
332         
333         return 0;
334 }