Declare libdconf_service as a dependency
[dconf.git] / tests / gvdb.c
blobd0540679ae83d3ac08dbbc02d9374c2311364f97
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,
271 gint level)
273 const gchar * key_names[] = {
274 "/", "/values/", "/int32", "values/int32",
275 "/values/int32", "/values/boolean", "/values/string",
276 ".locks", "/first/lock", "/second", NULL
278 gint found_items;
279 gchar **names;
280 gint n_names;
281 gint i;
283 if (level > 100)
284 return;
286 found_items = 0;
287 for (i = 0; key_names[i]; i++)
289 const gchar *key = key_names[i];
290 GvdbTable *subtable;
291 GVariant *value;
292 gchar **list;
293 gboolean has;
295 has = gvdb_table_has_value (table, key);
297 list = gvdb_table_list (table, key);
298 g_assert (!has || list == NULL);
299 if (list)
301 gchar *joined = g_strjoinv (",", list);
302 g_strfreev (list);
303 g_free (joined);
304 found_items++;
307 value = gvdb_table_get_value (table, key);
308 g_assert_cmpint (value != NULL, ==, has);
309 if (value)
311 gchar *printed = g_variant_print (value, FALSE);
312 g_variant_unref (value);
313 g_free (printed);
314 found_items++;
317 value = gvdb_table_get_raw_value (table, key);
318 g_assert_cmpint (value != NULL, ==, has);
319 if (value)
321 gchar *printed = g_variant_print (value, FALSE);
322 g_variant_unref (value);
323 g_free (printed);
326 subtable = gvdb_table_get_table (table, key);
327 g_assert (!has || subtable == NULL);
328 if (subtable)
330 inspect_carefully (subtable, level + 1);
331 gvdb_table_free (subtable);
332 found_items++;
336 names = gvdb_table_get_names (table, &n_names);
337 g_assert_cmpint (n_names, ==, g_strv_length (names));
338 g_assert_cmpint (found_items, <=, n_names);
339 g_free (g_strjoinv (" ", names));
340 g_strfreev (names);
343 static void
344 test_corrupted (gconstpointer user_data)
346 gint percentage = GPOINTER_TO_INT (user_data);
347 GError *error = NULL;
348 GMappedFile *mapped;
350 mapped = g_mapped_file_new (SRCDIR "/gvdbs/nested_gvdb", FALSE, &error);
351 g_assert_no_error (error);
352 g_assert (mapped);
354 if (percentage)
356 GvdbTable *table;
357 const gchar *orig;
358 gsize length;
359 gchar *copy;
360 gint i;
362 orig = g_mapped_file_get_contents (mapped);
363 length = g_mapped_file_get_length (mapped);
364 copy = g_memdup (orig, length);
366 for (i = 0; i < 10000; i++)
368 GBytes *bytes;
369 gint j;
371 /* Make a broken copy, but leave the signature intact so that
372 * we don't get too many boring trivial failures.
374 for (j = 8; j < length; j++)
375 if (g_test_rand_int_range (0, 100) < percentage)
376 copy[j] = g_test_rand_int_range (0, 256);
377 else
378 copy[j] = orig[j];
380 bytes = g_bytes_new_static (copy, length);
381 table = gvdb_table_new_from_bytes (bytes, FALSE, &error);
382 g_bytes_unref (bytes);
384 /* If we damaged the header, it may not open */
385 if (table)
387 inspect_carefully (table, 0);
388 gvdb_table_free (table);
390 else
392 g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
393 g_clear_error (&error);
397 g_free (copy);
399 else
401 GvdbTable *table;
402 GBytes *bytes;
404 bytes = g_mapped_file_get_bytes (mapped);
405 table = gvdb_table_new_from_bytes (bytes, FALSE, &error);
406 g_bytes_unref (bytes);
408 g_assert_no_error (error);
409 g_assert (table);
411 inspect_carefully (table, 0);
412 gvdb_table_free (table);
415 g_mapped_file_unref (mapped);
419 main (int argc, char **argv)
421 gint i;
423 g_test_init (&argc, &argv, NULL);
425 g_test_add_func ("/gvdb/reader/open-error", test_reader_open_error);
426 g_test_add_func ("/gvdb/reader/empty", test_reader_empty);
427 g_test_add_func ("/gvdb/reader/values", test_reader_values);
428 g_test_add_func ("/gvdb/reader/values/big-endian", test_reader_values_bigendian);
429 g_test_add_func ("/gvdb/reader/nested", test_nested);
430 for (i = 0; i < 20; i++)
432 gchar test_name[80];
433 g_snprintf (test_name, sizeof test_name, "/gvdb/reader/corrupted/%d%%", i);
434 g_test_add_data_func (test_name, GINT_TO_POINTER (i), test_corrupted);
437 return g_test_run ();