2 #include "../gvdb/gvdb-reader.h"
5 test_reader_open_error (void)
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
);
32 test_reader_empty (void)
34 const gchar
* strings
[] = { "", "value", "/value", ".", NULL
};
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);
52 names
= gvdb_table_get_names (table
, NULL
);
53 g_assert_cmpint (g_strv_length (names
), ==, 0);
56 for (i
= 0; strings
[i
]; i
++)
58 const gchar
*key
= strings
[i
];
64 sub
= gvdb_table_get_table (table
, key
);
65 g_assert (sub
== NULL
);
67 has
= gvdb_table_has_value (table
, key
);
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
);
84 verify_table (GvdbTable
*table
)
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
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");
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/");
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");
121 /* A directory is not a value */
122 has
= gvdb_table_has_value (table
, "/");
124 has
= gvdb_table_has_value (table
, "/values/");
127 has
= gvdb_table_has_value (table
, "/int32");
129 has
= gvdb_table_has_value (table
, "values/int32");
131 has
= gvdb_table_has_value (table
, "/values/int32");
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
);
170 test_reader_values (void)
172 GError
*error
= NULL
;
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
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
);
190 gvdb_table_free (table
);
194 test_reader_values_bigendian (void)
196 GError
*error
= NULL
;
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
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
);
214 gvdb_table_free (table
);
220 GError
*error
= NULL
;
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");
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");
255 has
= gvdb_table_has_value (locks
, "/first/lock");
258 has
= gvdb_table_has_value (locks
, "/second");
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).
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
283 for (i
= 0; key_names
[i
]; i
++)
285 const gchar
*key
= key_names
[i
];
291 has
= gvdb_table_has_value (table
, key
);
293 list
= gvdb_table_list (table
, key
);
294 g_assert (!has
|| list
== NULL
);
297 gchar
*joined
= g_strjoinv (",", list
);
303 value
= gvdb_table_get_value (table
, key
);
304 g_assert_cmpint (value
!= NULL
, ==, has
);
307 gchar
*printed
= g_variant_print (value
, FALSE
);
308 g_variant_unref (value
);
313 value
= gvdb_table_get_raw_value (table
, key
);
314 g_assert_cmpint (value
!= NULL
, ==, has
);
317 gchar
*printed
= g_variant_print (value
, FALSE
);
318 g_variant_unref (value
);
322 subtable
= gvdb_table_get_table (table
, key
);
323 g_assert (!has
|| subtable
== NULL
);
326 inspect_carefully (subtable
);
327 gvdb_table_free (subtable
);
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
));
340 test_corrupted (gconstpointer user_data
)
342 gint percentage
= GPOINTER_TO_INT (user_data
);
343 GError
*error
= NULL
;
346 mapped
= g_mapped_file_new (SRCDIR
"/gvdbs/nested_gvdb", FALSE
, &error
);
347 g_assert_no_error (error
);
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
++)
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);
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 */
383 inspect_carefully (table
);
384 gvdb_table_free (table
);
388 g_assert_error (error
, G_FILE_ERROR
, G_FILE_ERROR_INVAL
);
389 g_clear_error (&error
);
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
);
407 inspect_carefully (table
);
408 gvdb_table_free (table
);
411 g_mapped_file_unref (mapped
);
415 main (int argc
, char **argv
)
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
++)
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 ();