tests: add testcase for dconf_engine_sync()
[dconf.git] / tests / gvdb.c
blob084b422bcb47c944e8e890309a6e1f281819577d
1 #include <glib.h>
2 #include "../gvdb/gvdb-reader.h"
4 static void
5 test_reader_open_error (void)
7 GError *error = NULL;
8 GvdbTable *table;
10 table = gvdb_table_new (SRCDIR "/gvdbs/does_not_exist", TRUE, &error);
11 g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
12 g_assert (table == NULL);
13 g_clear_error (&error);
15 table = gvdb_table_new (SRCDIR "/gvdbs/file_empty", TRUE, &error);
16 g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
17 g_assert (table == NULL);
18 g_clear_error (&error);
20 table = gvdb_table_new (SRCDIR "/gvdbs/invalid_header", TRUE, &error);
21 g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
22 g_assert (table == NULL);
23 g_clear_error (&error);
25 table = gvdb_table_new (SRCDIR "/gvdbs/file_too_small", TRUE, &error);
26 g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
27 g_assert (table == NULL);
28 g_clear_error (&error);
31 static void
32 test_reader_empty (void)
34 const gchar * strings[] = { "", "value", "/value", ".", NULL};
35 GError *error = NULL;
36 GvdbTable *table;
37 gchar **names;
38 gint n_names;
39 gint i;
41 table = gvdb_table_new (SRCDIR "/gvdbs/empty_gvdb", TRUE, &error);
42 g_assert_no_error (error);
43 g_assert (table != NULL);
45 g_assert (gvdb_table_is_valid (table));
47 names = gvdb_table_get_names (table, &n_names);
48 g_assert_cmpint (n_names, ==, 0);
49 g_assert_cmpint (g_strv_length (names), ==, 0);
50 g_strfreev (names);
52 names = gvdb_table_get_names (table, NULL);
53 g_assert_cmpint (g_strv_length (names), ==, 0);
54 g_strfreev (names);
56 for (i = 0; strings[i]; i++)
58 const gchar *key = strings[i];
59 GvdbTable *sub;
60 GVariant *val;
61 gboolean has;
62 gchar **list;
64 sub = gvdb_table_get_table (table, key);
65 g_assert (sub == NULL);
67 has = gvdb_table_has_value (table, key);
68 g_assert (!has);
70 val = gvdb_table_get_value (table, key);
71 g_assert (val == NULL);
73 val = gvdb_table_get_raw_value (table, key);
74 g_assert (val == NULL);
76 list = gvdb_table_list (table, key);
77 g_assert (list == NULL);
80 gvdb_table_free (table);
83 static void
84 verify_table (GvdbTable *table)
86 GVariant *value;
87 gchar **list;
88 gint n_names;
89 gboolean has;
91 /* We could not normally expect these to be in a particular order but
92 * we are using a specific test file that we know to be layed out this
93 * way...
95 * It's pure luck that they happened to be layed out in this nice way.
97 list = gvdb_table_get_names (table, &n_names);
98 g_assert_cmpint (n_names, ==, g_strv_length (list));
99 g_assert_cmpint (n_names, ==, 5);
100 g_assert_cmpstr (list[0], ==, "/");
101 g_assert_cmpstr (list[1], ==, "/values/");
102 g_assert_cmpstr (list[2], ==, "/values/boolean");
103 g_assert_cmpstr (list[3], ==, "/values/string");
104 g_assert_cmpstr (list[4], ==, "/values/int32");
105 g_strfreev (list);
107 list = gvdb_table_list (table, "/");
108 g_assert (list != NULL);
109 g_assert_cmpint (g_strv_length (list), ==, 1);
110 g_assert_cmpstr (list[0], ==, "values/");
111 g_strfreev (list);
113 list = gvdb_table_list (table, "/values/");
114 g_assert (list != NULL);
115 g_assert_cmpint (g_strv_length (list), ==, 3);
116 g_assert_cmpstr (list[0], ==, "boolean");
117 g_assert_cmpstr (list[1], ==, "int32");
118 g_assert_cmpstr (list[2], ==, "string");
119 g_strfreev (list);
121 /* A directory is not a value */
122 has = gvdb_table_has_value (table, "/");
123 g_assert (!has);
124 has = gvdb_table_has_value (table, "/values/");
125 g_assert (!has);
127 has = gvdb_table_has_value (table, "/int32");
128 g_assert (!has);
129 has = gvdb_table_has_value (table, "values/int32");
130 g_assert (!has);
131 has = gvdb_table_has_value (table, "/values/int32");
132 g_assert (has);
134 value = gvdb_table_get_value (table, "/");
135 g_assert (value == NULL);
136 value = gvdb_table_get_value (table, "/values/");
137 g_assert (value == NULL);
138 value = gvdb_table_get_value (table, "/int32");
139 g_assert (value == NULL);
140 value = gvdb_table_get_value (table, "values/int32");
141 g_assert (value == NULL);
143 value = gvdb_table_get_value (table, "/values/boolean");
144 g_assert (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN));
145 g_assert (g_variant_get_boolean (value));
146 g_variant_unref (value);
148 value = gvdb_table_get_raw_value (table, "/values/boolean");
149 g_assert (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN));
150 g_assert (g_variant_get_boolean (value));
151 g_variant_unref (value);
153 value = gvdb_table_get_value (table, "/values/int32");
154 g_assert (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_INT32));
155 g_assert_cmpint (g_variant_get_int32 (value), ==, 0x44332211);
156 g_variant_unref (value);
158 value = gvdb_table_get_value (table, "/values/string");
159 g_assert (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING));
160 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "a string");
161 g_variant_unref (value);
163 value = gvdb_table_get_raw_value (table, "/values/string");
164 g_assert (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING));
165 g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "a string");
166 g_variant_unref (value);
169 static void
170 test_reader_values (void)
172 GError *error = NULL;
173 GvdbTable *table;
175 table = gvdb_table_new (SRCDIR "/gvdbs/example_gvdb", TRUE, &error);
176 g_assert_no_error (error);
177 verify_table (table);
179 #if G_BYTE_ORDER == G_BIG_ENDIAN
181 GVariant *value;
183 value = gvdb_table_get_raw_value (table, "/values/int32");
184 g_assert (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_INT32));
185 g_assert_cmpint (g_variant_get_int32 (value), ==, 0x11223344);
186 g_variant_unref (value);
188 #endif
190 gvdb_table_free (table);
193 static void
194 test_reader_values_bigendian (void)
196 GError *error = NULL;
197 GvdbTable *table;
199 table = gvdb_table_new (SRCDIR "/gvdbs/example_gvdb.big-endian", TRUE, &error);
200 g_assert_no_error (error);
201 verify_table (table);
203 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
205 GVariant *value;
207 value = gvdb_table_get_raw_value (table, "/values/int32");
208 g_assert (value != NULL && g_variant_is_of_type (value, G_VARIANT_TYPE_INT32));
209 g_assert_cmpint (g_variant_get_int32 (value), ==, 0x11223344);
210 g_variant_unref (value);
212 #endif
214 gvdb_table_free (table);
217 static void
218 test_nested (void)
220 GError *error = NULL;
221 GvdbTable *table;
222 GvdbTable *locks;
223 gchar **names;
224 gint n_names;
225 gboolean has;
227 table = gvdb_table_new (SRCDIR "/gvdbs/nested_gvdb", TRUE, &error);
228 g_assert_no_error (error);
230 /* Note the more-random ordering here compared with above. */
231 names = gvdb_table_get_names (table, &n_names);
232 g_assert_cmpint (n_names, ==, g_strv_length (names));
233 g_assert_cmpint (n_names, ==, 6);
234 g_assert_cmpstr (names[0], ==, "/values/boolean");
235 g_assert_cmpstr (names[1], ==, "/");
236 g_assert_cmpstr (names[2], ==, "/values/int32");
237 g_assert_cmpstr (names[3], ==, ".locks");
238 g_assert_cmpstr (names[4], ==, "/values/");
239 g_assert_cmpstr (names[5], ==, "/values/string");
240 g_strfreev (names);
242 locks = gvdb_table_get_table (table, "/");
243 g_assert (locks == NULL);
244 locks = gvdb_table_get_table (table, "/values/");
245 g_assert (locks == NULL);
246 locks = gvdb_table_get_table (table, "/values/int32");
247 g_assert (locks == NULL);
249 locks = gvdb_table_get_table (table, ".locks");
250 g_assert (locks != NULL);
252 has = gvdb_table_has_value (locks, "/first/lck");
253 g_assert (!has);
255 has = gvdb_table_has_value (locks, "/first/lock");
256 g_assert (has);
258 has = gvdb_table_has_value (locks, "/second");
259 g_assert (has);
261 gvdb_table_free (table);
262 gvdb_table_free (locks);
265 /* This function exercises the API against @table but does not do any
266 * asserts on unexpected values (although it will assert on inconsistent
267 * values returned by the API).
269 static void
270 inspect_carefully (GvdbTable *table)
272 const gchar * key_names[] = {
273 "/", "/values/", "/int32", "values/int32",
274 "/values/int32", "/values/boolean", "/values/string",
275 ".locks", "/first/lock", "/second", NULL
277 gint found_items;
278 gchar **names;
279 gint n_names;
280 gint i;
282 found_items = 0;
283 for (i = 0; key_names[i]; i++)
285 const gchar *key = key_names[i];
286 GvdbTable *subtable;
287 GVariant *value;
288 gchar **list;
289 gboolean has;
291 has = gvdb_table_has_value (table, key);
293 list = gvdb_table_list (table, key);
294 g_assert (!has || list == NULL);
295 if (list)
297 gchar *joined = g_strjoinv (",", list);
298 g_strfreev (list);
299 g_free (joined);
300 found_items++;
303 value = gvdb_table_get_value (table, key);
304 g_assert_cmpint (value != NULL, ==, has);
305 if (value)
307 gchar *printed = g_variant_print (value, FALSE);
308 g_variant_unref (value);
309 g_free (printed);
310 found_items++;
313 value = gvdb_table_get_raw_value (table, key);
314 g_assert_cmpint (value != NULL, ==, has);
315 if (value)
317 gchar *printed = g_variant_print (value, FALSE);
318 g_variant_unref (value);
319 g_free (printed);
322 subtable = gvdb_table_get_table (table, key);
323 g_assert (!has || subtable == NULL);
324 if (subtable)
326 inspect_carefully (subtable);
327 gvdb_table_free (subtable);
328 found_items++;
332 names = gvdb_table_get_names (table, &n_names);
333 g_assert_cmpint (n_names, ==, g_strv_length (names));
334 g_assert_cmpint (found_items, <=, n_names);
335 g_free (g_strjoinv (" ", names));
336 g_strfreev (names);
339 static void
340 test_corrupted (gconstpointer user_data)
342 gint percentage = GPOINTER_TO_INT (user_data);
343 GError *error = NULL;
344 GMappedFile *mapped;
346 mapped = g_mapped_file_new (SRCDIR "/gvdbs/nested_gvdb", FALSE, &error);
347 g_assert_no_error (error);
348 g_assert (mapped);
350 if (percentage)
352 GvdbTable *table;
353 const gchar *orig;
354 gsize length;
355 gchar *copy;
356 gint i;
358 orig = g_mapped_file_get_contents (mapped);
359 length = g_mapped_file_get_length (mapped);
360 copy = g_memdup (orig, length);
362 for (i = 0; i < 10000; i++)
364 GBytes *bytes;
365 gint j;
367 /* Make a broken copy, but leave the signature intact so that
368 * we don't get too many boring trivial failures.
370 for (j = 8; j < length; j++)
371 if (g_test_rand_int_range (0, 100) < percentage)
372 copy[j] = g_test_rand_int_range (0, 256);
373 else
374 copy[j] = orig[j];
376 bytes = g_bytes_new_static (copy, length);
377 table = gvdb_table_new_from_bytes (bytes, FALSE, &error);
378 g_bytes_unref (bytes);
380 /* If we damaged the header, it may not open */
381 if (table)
383 inspect_carefully (table);
384 gvdb_table_free (table);
386 else
388 g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
389 g_clear_error (&error);
393 g_free (copy);
395 else
397 GvdbTable *table;
398 GBytes *bytes;
400 bytes = g_mapped_file_get_bytes (mapped);
401 table = gvdb_table_new_from_bytes (bytes, FALSE, &error);
402 g_bytes_unref (bytes);
404 g_assert_no_error (error);
405 g_assert (table);
407 inspect_carefully (table);
408 gvdb_table_free (table);
411 g_mapped_file_unref (mapped);
415 main (int argc, char **argv)
417 gint i;
419 g_test_init (&argc, &argv, NULL);
421 g_test_add_func ("/gvdb/reader/open-error", test_reader_open_error);
422 g_test_add_func ("/gvdb/reader/empty", test_reader_empty);
423 g_test_add_func ("/gvdb/reader/values", test_reader_values);
424 g_test_add_func ("/gvdb/reader/values/big-endian", test_reader_values_bigendian);
425 g_test_add_func ("/gvdb/reader/nested", test_nested);
426 for (i = 0; i < 20; i++)
428 gchar test_name[80];
429 g_snprintf (test_name, sizeof test_name, "/gvdb/reader/corrupted/%d%%", i);
430 g_test_add_data_func (test_name, GINT_TO_POINTER (i), test_corrupted);
433 return g_test_run ();