2 * Copyright © 2010 Canonical Limited
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the licence, or (at
7 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * Author: Ryan Lortie <desrt@desrt.ca>
20 #define G_SETTINGS_ENABLE_BACKEND
21 #include <gio/gsettingsbackend.h>
27 static GSettingsBackend
*backend
;
30 free_variant (gpointer data
)
33 g_variant_unref (data
);
37 do_read (const gchar
*key
)
39 return G_SETTINGS_BACKEND_GET_CLASS (backend
)
40 ->read (backend
, key
, NULL
, FALSE
);
44 do_write (const gchar
*key
,
47 return G_SETTINGS_BACKEND_GET_CLASS (backend
)
48 ->write (backend
, key
, value
, do_write
);
52 do_write_tree (GTree
*tree
)
54 return G_SETTINGS_BACKEND_GET_CLASS (backend
)
55 ->write_tree (backend
, tree
, do_write
);
61 return G_SETTINGS_BACKEND_GET_CLASS (backend
)
65 #define RANDOM_ELEMENT(array) \
66 array[g_test_rand_int_range(0, G_N_ELEMENTS(array))]
71 const gchar
* const words
[] = {
72 "alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "golf",
73 "hotel", "india", "juliet", "kilo", "lima", "mike", "november",
74 "oscar", "papa", "quebec", "romeo", "sierra", "tango", "uniform",
75 "victor", "whiskey", "xray", "yankee", "zulu"
77 const gchar
*parts
[8];
80 n
= g_test_rand_int_range (2, 8);
82 for (i
= 1; i
< n
; i
++)
83 parts
[i
] = RANDOM_ELEMENT (words
);
86 return g_strjoinv ("/", (gchar
**) parts
);
92 switch (g_test_rand_int_range (0, 3))
95 return g_variant_new_int32 (g_test_rand_int ());
98 return g_variant_new_boolean (g_test_rand_bit ());
102 gint length
= g_test_rand_int_range (0, 24);
106 for (i
= 0; i
< length
; i
++)
107 buffer
[i
] = 'a' + g_test_rand_int_range (0, 26);
110 return g_variant_new_string (buffer
);
114 g_assert_not_reached ();
124 tree
= g_tree_new_full ((GCompareDataFunc
) strcmp
, NULL
,
125 g_free
, free_variant
);
126 n
= g_test_rand_int_range (1, 20);
129 g_tree_insert (tree
, random_key (), g_variant_ref_sink (random_value ()));
135 apply_change (GHashTable
*table
,
140 g_hash_table_insert (table
, g_strdup (key
), g_variant_ref_sink (value
));
142 g_hash_table_insert (table
, g_strdup (key
), NULL
);
146 apply_one_change (gpointer key
,
150 apply_change (user_data
, key
, value
);
155 apply_change_tree (GHashTable
*table
,
158 g_tree_foreach (tree
, apply_one_change
, table
);
161 static GHashTable
*implicit
;
162 static GHashTable
*explicit;
166 g_settings_backend_changed (GSettingsBackend
*backend_
,
172 /* ensure that we see no dupes from the bus */
173 g_assert (origin_tag
== do_write
);
174 g_assert (backend
== backend_
);
176 value
= do_read (key
);
177 apply_change (implicit
, key
, value
);
178 g_variant_unref (value
);
183 g_settings_backend_keys_changed (GSettingsBackend
*backend_
,
185 const gchar
* const *items
,
190 /* ensure that we see no dupes from the bus */
191 g_assert (origin_tag
== do_write
);
192 g_assert (backend
== backend_
);
194 for (i
= 0; items
[i
]; i
++)
199 key
= g_strconcat (path
, items
[i
], NULL
);
200 value
= do_read (key
);
202 apply_change (implicit
, key
, value
);
204 g_variant_unref (value
);
211 g_settings_backend_changed_tree (GSettingsBackend
*backend_
,
218 g_settings_backend_flatten_tree (tree
, &path
, &keys
, NULL
);
219 g_settings_backend_keys_changed (backend_
, path
, keys
, origin_tag
);
225 extern void _g_io_modules_ensure_loaded (void);
226 GIOExtensionPoint
*point
;
227 GIOExtension
*extension
;
228 GType extension_type
;
231 file
= g_build_filename (g_get_user_config_dir (),
236 g_setenv ("DCONF_PROFILE", "test", false);
240 /* Cause GIO modules to be loaded... */
241 g_object_unref (g_file_new_for_path ("."));
243 point
= g_io_extension_point_lookup ("gsettings-backend");
244 extension
= g_io_extension_point_get_extension_by_name (point
, "dconf");
245 extension_type
= g_io_extension_get_type (extension
);
246 backend
= g_object_new (extension_type
, NULL
);
248 G_SETTINGS_BACKEND_GET_CLASS (backend
)
249 ->subscribe (backend
, "/");
251 implicit
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
252 g_free
, free_variant
);
253 explicit = g_hash_table_new_full (g_str_hash
, g_str_equal
,
254 g_free
, free_variant
);
260 make_random_change (void)
262 if (g_test_rand_bit ())
268 value
= random_value ();
269 apply_change (explicit, key
, value
);
270 do_write (key
, value
);
278 tree
= random_tree ();
279 apply_change_tree (explicit, tree
);
280 do_write_tree (tree
);
292 verify_consistency (void)
300 g_print ("(%d)", g_hash_table_size (implicit
));
302 g_assert (g_hash_table_size (explicit) == g_hash_table_size (implicit
));
303 g_hash_table_iter_init (&iter
, explicit);
304 while (g_hash_table_iter_next (&iter
, &key
, &value
))
310 ghash_time
-= g_get_monotonic_time ();
311 other
= g_hash_table_lookup (implicit
, key
);
312 ghash_time
+= g_get_monotonic_time ();
313 g_assert (g_variant_equal (value
, other
));
315 dconf_time
-= g_get_monotonic_time ();
316 other
= do_read (key
);
317 dconf_time
+= g_get_monotonic_time ();
318 g_assert (g_variant_equal (value
, other
));
319 g_variant_unref (other
);
323 g_assert (g_hash_table_lookup (implicit
, key
) == NULL
);
324 g_assert (do_read (key
) == NULL
);
339 g_hash_table_iter_init (&iter
, explicit);
340 while (g_hash_table_iter_next (&iter
, &key
, &value
))
346 printed
= g_variant_print (value
, FALSE
);
348 printed
= g_strdup ("None");
350 g_print ("'%s': %s, ", (gchar
*) key
, printed
);
362 g_print ("Testing dconf...");
363 for (i
= 0; i
< 1000; i
++)
366 make_random_change ();
367 verify_consistency ();
371 g_print ("GSettings lookup time: %f µs/lookup\n",
372 ((double) dconf_time
/ lookups
));
373 g_print ("GHashTable lookup time: %f µs/lookup\n",
374 ((double) ghash_time
/ lookups
));
380 g_print ("\nWaiting for dconf-service to catch up...");
382 g_print (" done.\n");
384 g_print ("Measuring dconf read performance...");
386 for (i
= 0; i
< 1000; i
++)
387 verify_consistency ();
390 g_print ("dconf lookup time: %f µs/lookup\n",
391 ((double) dconf_time
/ lookups
));
392 g_print ("GHashTable lookup time: %f µs/lookup\n",
393 ((double) ghash_time
/ lookups
));
395 g_hash_table_unref (explicit);
396 g_hash_table_unref (implicit
);
400 main (int argc
, char **argv
)
402 g_test_init (&argc
, &argv
, NULL
);
408 return g_test_run ();