2 * Unit tests for parsing of KEY=VALUE,... strings
4 * Copyright (C) 2017 Red Hat Inc.
7 * Markus Armbruster <armbru@redhat.com>,
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "qapi/qmp/qstring.h"
16 #include "qapi/qobject-input-visitor.h"
17 #include "qemu/cutils.h"
18 #include "qemu/option.h"
20 static void test_keyval_parse(void)
23 QDict
*qdict
, *sub_qdict
;
28 qdict
= keyval_parse("", NULL
, &error_abort
);
29 g_assert_cmpuint(qdict_size(qdict
), ==, 0);
32 /* Empty key (qemu_opts_parse() accepts this) */
33 qdict
= keyval_parse("=val", NULL
, &err
);
34 error_free_or_abort(&err
);
37 /* Empty key fragment */
38 qdict
= keyval_parse(".", NULL
, &err
);
39 error_free_or_abort(&err
);
41 qdict
= keyval_parse("key.", NULL
, &err
);
42 error_free_or_abort(&err
);
45 /* Invalid non-empty key (qemu_opts_parse() doesn't care) */
46 qdict
= keyval_parse("7up=val", NULL
, &err
);
47 error_free_or_abort(&err
);
51 memset(long_key
, 'a', 127);
54 params
= g_strdup_printf("k.%s=v", long_key
);
55 qdict
= keyval_parse(params
+ 2, NULL
, &err
);
56 error_free_or_abort(&err
);
59 /* Overlong key fragment */
60 qdict
= keyval_parse(params
, NULL
, &err
);
61 error_free_or_abort(&err
);
65 /* Long key (qemu_opts_parse() accepts and truncates silently) */
66 params
= g_strdup_printf("k.%s=v", long_key
+ 1);
67 qdict
= keyval_parse(params
+ 2, NULL
, &error_abort
);
68 g_assert_cmpuint(qdict_size(qdict
), ==, 1);
69 g_assert_cmpstr(qdict_get_try_str(qdict
, long_key
+ 1), ==, "v");
72 /* Long key fragment */
73 qdict
= keyval_parse(params
, NULL
, &error_abort
);
74 g_assert_cmpuint(qdict_size(qdict
), ==, 1);
75 sub_qdict
= qdict_get_qdict(qdict
, "k");
77 g_assert_cmpuint(qdict_size(sub_qdict
), ==, 1);
78 g_assert_cmpstr(qdict_get_try_str(sub_qdict
, long_key
+ 1), ==, "v");
82 /* Crap after valid key */
83 qdict
= keyval_parse("key[0]=val", NULL
, &err
);
84 error_free_or_abort(&err
);
87 /* Multiple keys, last one wins */
88 qdict
= keyval_parse("a=1,b=2,,x,a=3", NULL
, &error_abort
);
89 g_assert_cmpuint(qdict_size(qdict
), ==, 2);
90 g_assert_cmpstr(qdict_get_try_str(qdict
, "a"), ==, "3");
91 g_assert_cmpstr(qdict_get_try_str(qdict
, "b"), ==, "2,x");
94 /* Even when it doesn't in qemu_opts_parse() */
95 qdict
= keyval_parse("id=foo,id=bar", NULL
, &error_abort
);
96 g_assert_cmpuint(qdict_size(qdict
), ==, 1);
97 g_assert_cmpstr(qdict_get_try_str(qdict
, "id"), ==, "bar");
101 qdict
= keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL
, &error_abort
);
102 g_assert_cmpuint(qdict_size(qdict
), ==, 2);
103 sub_qdict
= qdict_get_qdict(qdict
, "a");
105 g_assert_cmpuint(qdict_size(sub_qdict
), ==, 1);
106 sub_qdict
= qdict_get_qdict(sub_qdict
, "b");
108 g_assert_cmpuint(qdict_size(sub_qdict
), ==, 1);
109 g_assert_cmpstr(qdict_get_try_str(sub_qdict
, "c"), ==, "2");
110 g_assert_cmpstr(qdict_get_try_str(qdict
, "d"), ==, "3");
113 /* Inconsistent dotted keys */
114 qdict
= keyval_parse("a.b=1,a=2", NULL
, &err
);
115 error_free_or_abort(&err
);
117 qdict
= keyval_parse("a.b=1,a.b.c=2", NULL
, &err
);
118 error_free_or_abort(&err
);
121 /* Trailing comma is ignored */
122 qdict
= keyval_parse("x=y,", NULL
, &error_abort
);
123 g_assert_cmpuint(qdict_size(qdict
), ==, 1);
124 g_assert_cmpstr(qdict_get_try_str(qdict
, "x"), ==, "y");
127 /* Except when it isn't */
128 qdict
= keyval_parse(",", NULL
, &err
);
129 error_free_or_abort(&err
);
132 /* Value containing ,id= not misinterpreted as qemu_opts_parse() does */
133 qdict
= keyval_parse("x=,,id=bar", NULL
, &error_abort
);
134 g_assert_cmpuint(qdict_size(qdict
), ==, 1);
135 g_assert_cmpstr(qdict_get_try_str(qdict
, "x"), ==, ",id=bar");
138 /* Anti-social ID is left to caller (qemu_opts_parse() rejects it) */
139 qdict
= keyval_parse("id=666", NULL
, &error_abort
);
140 g_assert_cmpuint(qdict_size(qdict
), ==, 1);
141 g_assert_cmpstr(qdict_get_try_str(qdict
, "id"), ==, "666");
144 /* Implied value not supported (unlike qemu_opts_parse()) */
145 qdict
= keyval_parse("an,noaus,noaus=", NULL
, &err
);
146 error_free_or_abort(&err
);
149 /* Implied value, key "no" (qemu_opts_parse(): negated empty key) */
150 qdict
= keyval_parse("no", NULL
, &err
);
151 error_free_or_abort(&err
);
155 qdict
= keyval_parse("an,aus=off,noaus=", "implied", &error_abort
);
156 g_assert_cmpuint(qdict_size(qdict
), ==, 3);
157 g_assert_cmpstr(qdict_get_try_str(qdict
, "implied"), ==, "an");
158 g_assert_cmpstr(qdict_get_try_str(qdict
, "aus"), ==, "off");
159 g_assert_cmpstr(qdict_get_try_str(qdict
, "noaus"), ==, "");
162 /* Implied dotted key */
163 qdict
= keyval_parse("val", "eins.zwei", &error_abort
);
164 g_assert_cmpuint(qdict_size(qdict
), ==, 1);
165 sub_qdict
= qdict_get_qdict(qdict
, "eins");
167 g_assert_cmpuint(qdict_size(sub_qdict
), ==, 1);
168 g_assert_cmpstr(qdict_get_try_str(sub_qdict
, "zwei"), ==, "val");
171 /* Implied key with empty value (qemu_opts_parse() accepts this) */
172 qdict
= keyval_parse(",", "implied", &err
);
173 error_free_or_abort(&err
);
176 /* Likewise (qemu_opts_parse(): implied key with comma value) */
177 qdict
= keyval_parse(",,,a=1", "implied", &err
);
178 error_free_or_abort(&err
);
181 /* Empty key is not an implied key */
182 qdict
= keyval_parse("=val", "implied", &err
);
183 error_free_or_abort(&err
);
187 static void check_list012(QList
*qlist
)
189 static const char *expected
[] = { "null", "eins", "zwei" };
194 for (i
= 0; i
< ARRAY_SIZE(expected
); i
++) {
195 qstr
= qobject_to_qstring(qlist_pop(qlist
));
197 g_assert_cmpstr(qstring_get_str(qstr
), ==, expected
[i
]);
200 g_assert(qlist_empty(qlist
));
203 static void test_keyval_parse_list(void)
206 QDict
*qdict
, *sub_qdict
;
208 /* Root can't be a list */
209 qdict
= keyval_parse("0=1", NULL
, &err
);
210 error_free_or_abort(&err
);
213 /* List elements need not be in order */
214 qdict
= keyval_parse("list.0=null,list.2=zwei,list.1=eins",
216 g_assert_cmpint(qdict_size(qdict
), ==, 1);
217 check_list012(qdict_get_qlist(qdict
, "list"));
220 /* Multiple indexes, last one wins */
221 qdict
= keyval_parse("list.1=goner,list.0=null,list.1=eins,list.2=zwei",
223 g_assert_cmpint(qdict_size(qdict
), ==, 1);
224 check_list012(qdict_get_qlist(qdict
, "list"));
227 /* List at deeper nesting */
228 qdict
= keyval_parse("a.list.1=eins,a.list.0=null,a.list.2=zwei",
230 g_assert_cmpint(qdict_size(qdict
), ==, 1);
231 sub_qdict
= qdict_get_qdict(qdict
, "a");
232 g_assert_cmpint(qdict_size(sub_qdict
), ==, 1);
233 check_list012(qdict_get_qlist(sub_qdict
, "list"));
236 /* Inconsistent dotted keys: both list and dictionary */
237 qdict
= keyval_parse("a.b.c=1,a.b.0=2", NULL
, &err
);
238 error_free_or_abort(&err
);
240 qdict
= keyval_parse("a.0.c=1,a.b.c=2", NULL
, &err
);
241 error_free_or_abort(&err
);
244 /* Missing list indexes */
245 qdict
= keyval_parse("list.2=lonely", NULL
, &err
);
246 error_free_or_abort(&err
);
248 qdict
= keyval_parse("list.0=null,list.2=eins,list.02=zwei", NULL
, &err
);
249 error_free_or_abort(&err
);
253 static void test_keyval_visit_bool(void)
260 qdict
= keyval_parse("bool1=on,bool2=off", NULL
, &error_abort
);
261 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
263 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
264 visit_type_bool(v
, "bool1", &b
, &error_abort
);
266 visit_type_bool(v
, "bool2", &b
, &error_abort
);
268 visit_check_struct(v
, &error_abort
);
269 visit_end_struct(v
, NULL
);
272 qdict
= keyval_parse("bool1=offer", NULL
, &error_abort
);
273 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
275 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
276 visit_type_bool(v
, "bool1", &b
, &err
);
277 error_free_or_abort(&err
);
278 visit_end_struct(v
, NULL
);
282 static void test_keyval_visit_number(void)
289 /* Lower limit zero */
290 qdict
= keyval_parse("number1=0", NULL
, &error_abort
);
291 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
293 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
294 visit_type_uint64(v
, "number1", &u
, &error_abort
);
295 g_assert_cmpuint(u
, ==, 0);
296 visit_check_struct(v
, &error_abort
);
297 visit_end_struct(v
, NULL
);
300 /* Upper limit 2^64-1 */
301 qdict
= keyval_parse("number1=18446744073709551615,number2=-1",
303 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
305 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
306 visit_type_uint64(v
, "number1", &u
, &error_abort
);
307 g_assert_cmphex(u
, ==, UINT64_MAX
);
308 visit_type_uint64(v
, "number2", &u
, &error_abort
);
309 g_assert_cmphex(u
, ==, UINT64_MAX
);
310 visit_check_struct(v
, &error_abort
);
311 visit_end_struct(v
, NULL
);
314 /* Above upper limit */
315 qdict
= keyval_parse("number1=18446744073709551616",
317 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
319 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
320 visit_type_uint64(v
, "number1", &u
, &err
);
321 error_free_or_abort(&err
);
322 visit_end_struct(v
, NULL
);
325 /* Below lower limit */
326 qdict
= keyval_parse("number1=-18446744073709551616",
328 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
330 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
331 visit_type_uint64(v
, "number1", &u
, &err
);
332 error_free_or_abort(&err
);
333 visit_end_struct(v
, NULL
);
337 qdict
= keyval_parse("number1=0x2a,number2=052",
339 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
341 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
342 visit_type_uint64(v
, "number1", &u
, &error_abort
);
343 g_assert_cmpuint(u
, ==, 42);
344 visit_type_uint64(v
, "number2", &u
, &error_abort
);
345 g_assert_cmpuint(u
, ==, 42);
346 visit_check_struct(v
, &error_abort
);
347 visit_end_struct(v
, NULL
);
351 qdict
= keyval_parse("number1=3.14,number2=08",
353 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
355 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
356 visit_type_uint64(v
, "number1", &u
, &err
);
357 error_free_or_abort(&err
);
358 visit_type_uint64(v
, "number2", &u
, &err
);
359 error_free_or_abort(&err
);
360 visit_end_struct(v
, NULL
);
364 static void test_keyval_visit_size(void)
371 /* Lower limit zero */
372 qdict
= keyval_parse("sz1=0", NULL
, &error_abort
);
373 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
375 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
376 visit_type_size(v
, "sz1", &sz
, &error_abort
);
377 g_assert_cmpuint(sz
, ==, 0);
378 visit_check_struct(v
, &error_abort
);
379 visit_end_struct(v
, NULL
);
382 /* Note: precision is 53 bits since we're parsing with strtod() */
384 /* Around limit of precision: 2^53-1, 2^53, 2^53+1 */
385 qdict
= keyval_parse("sz1=9007199254740991,"
386 "sz2=9007199254740992,"
387 "sz3=9007199254740993",
389 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
391 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
392 visit_type_size(v
, "sz1", &sz
, &error_abort
);
393 g_assert_cmphex(sz
, ==, 0x1fffffffffffff);
394 visit_type_size(v
, "sz2", &sz
, &error_abort
);
395 g_assert_cmphex(sz
, ==, 0x20000000000000);
396 visit_type_size(v
, "sz3", &sz
, &error_abort
);
397 g_assert_cmphex(sz
, ==, 0x20000000000000);
398 visit_check_struct(v
, &error_abort
);
399 visit_end_struct(v
, NULL
);
402 /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */
403 qdict
= keyval_parse("sz1=9223372036854774784," /* 7ffffffffffffc00 */
404 "sz2=9223372036854775295", /* 7ffffffffffffdff */
406 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
408 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
409 visit_type_size(v
, "sz1", &sz
, &error_abort
);
410 g_assert_cmphex(sz
, ==, 0x7ffffffffffffc00);
411 visit_type_size(v
, "sz2", &sz
, &error_abort
);
412 g_assert_cmphex(sz
, ==, 0x7ffffffffffffc00);
413 visit_check_struct(v
, &error_abort
);
414 visit_end_struct(v
, NULL
);
417 /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
418 qdict
= keyval_parse("sz1=18446744073709549568," /* fffffffffffff800 */
419 "sz2=18446744073709550591", /* fffffffffffffbff */
421 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
423 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
424 visit_type_size(v
, "sz1", &sz
, &error_abort
);
425 g_assert_cmphex(sz
, ==, 0xfffffffffffff800);
426 visit_type_size(v
, "sz2", &sz
, &error_abort
);
427 g_assert_cmphex(sz
, ==, 0xfffffffffffff800);
428 visit_check_struct(v
, &error_abort
);
429 visit_end_struct(v
, NULL
);
433 qdict
= keyval_parse("sz1=-1,"
434 "sz2=18446744073709550592", /* fffffffffffffc00 */
436 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
438 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
439 visit_type_size(v
, "sz1", &sz
, &err
);
440 error_free_or_abort(&err
);
441 visit_type_size(v
, "sz2", &sz
, &err
);
442 error_free_or_abort(&err
);
443 visit_end_struct(v
, NULL
);
447 qdict
= keyval_parse("sz1=8b,sz2=1.5k,sz3=2M,sz4=0.1G,sz5=16777215T",
449 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
451 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
452 visit_type_size(v
, "sz1", &sz
, &error_abort
);
453 g_assert_cmpuint(sz
, ==, 8);
454 visit_type_size(v
, "sz2", &sz
, &error_abort
);
455 g_assert_cmpuint(sz
, ==, 1536);
456 visit_type_size(v
, "sz3", &sz
, &error_abort
);
457 g_assert_cmphex(sz
, ==, 2 * M_BYTE
);
458 visit_type_size(v
, "sz4", &sz
, &error_abort
);
459 g_assert_cmphex(sz
, ==, G_BYTE
/ 10);
460 visit_type_size(v
, "sz5", &sz
, &error_abort
);
461 g_assert_cmphex(sz
, ==, 16777215 * T_BYTE
);
462 visit_check_struct(v
, &error_abort
);
463 visit_end_struct(v
, NULL
);
466 /* Beyond limit with suffix */
467 qdict
= keyval_parse("sz1=16777216T", NULL
, &error_abort
);
468 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
470 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
471 visit_type_size(v
, "sz1", &sz
, &err
);
472 error_free_or_abort(&err
);
473 visit_end_struct(v
, NULL
);
477 qdict
= keyval_parse("sz1=16E,sz2=16Gi", NULL
, &error_abort
);
478 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
480 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
481 visit_type_size(v
, "sz1", &sz
, &err
);
482 error_free_or_abort(&err
);
483 visit_type_size(v
, "sz2", &sz
, &err
);
484 error_free_or_abort(&err
);
485 visit_end_struct(v
, NULL
);
489 static void test_keyval_visit_dict(void)
496 qdict
= keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL
, &error_abort
);
497 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
499 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
500 visit_start_struct(v
, "a", NULL
, 0, &error_abort
);
501 visit_start_struct(v
, "b", NULL
, 0, &error_abort
);
502 visit_type_int(v
, "c", &i
, &error_abort
);
503 g_assert_cmpint(i
, ==, 2);
504 visit_check_struct(v
, &error_abort
);
505 visit_end_struct(v
, NULL
);
506 visit_check_struct(v
, &error_abort
);
507 visit_end_struct(v
, NULL
);
508 visit_type_int(v
, "d", &i
, &error_abort
);
509 g_assert_cmpint(i
, ==, 3);
510 visit_check_struct(v
, &error_abort
);
511 visit_end_struct(v
, NULL
);
514 qdict
= keyval_parse("a.b=", NULL
, &error_abort
);
515 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
517 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
518 visit_start_struct(v
, "a", NULL
, 0, &error_abort
);
519 visit_type_int(v
, "c", &i
, &err
); /* a.c missing */
520 error_free_or_abort(&err
);
521 visit_check_struct(v
, &err
);
522 error_free_or_abort(&err
); /* a.b unexpected */
523 visit_end_struct(v
, NULL
);
524 visit_check_struct(v
, &error_abort
);
525 visit_end_struct(v
, NULL
);
529 static void test_keyval_visit_list(void)
536 qdict
= keyval_parse("a.0=,a.1=I,a.2.0=II", NULL
, &error_abort
);
537 /* TODO empty list */
538 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
540 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
541 visit_start_list(v
, "a", NULL
, 0, &error_abort
);
542 visit_type_str(v
, NULL
, &s
, &error_abort
);
543 g_assert_cmpstr(s
, ==, "");
545 visit_type_str(v
, NULL
, &s
, &error_abort
);
546 g_assert_cmpstr(s
, ==, "I");
548 visit_start_list(v
, NULL
, NULL
, 0, &error_abort
);
549 visit_type_str(v
, NULL
, &s
, &error_abort
);
550 g_assert_cmpstr(s
, ==, "II");
552 visit_check_list(v
, &error_abort
);
553 visit_end_list(v
, NULL
);
554 visit_check_list(v
, &error_abort
);
555 visit_end_list(v
, NULL
);
556 visit_check_struct(v
, &error_abort
);
557 visit_end_struct(v
, NULL
);
560 qdict
= keyval_parse("a.0=,b.0.0=head", NULL
, &error_abort
);
561 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
563 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
564 visit_start_list(v
, "a", NULL
, 0, &error_abort
);
565 visit_check_list(v
, &err
); /* a[0] unexpected */
566 error_free_or_abort(&err
);
567 visit_end_list(v
, NULL
);
568 visit_start_list(v
, "b", NULL
, 0, &error_abort
);
569 visit_start_list(v
, NULL
, NULL
, 0, &error_abort
);
570 visit_type_str(v
, NULL
, &s
, &error_abort
);
571 g_assert_cmpstr(s
, ==, "head");
573 visit_type_str(v
, NULL
, &s
, &err
); /* b[0][1] missing */
574 error_free_or_abort(&err
);
575 visit_end_list(v
, NULL
);
576 visit_end_list(v
, NULL
);
577 visit_check_struct(v
, &error_abort
);
578 visit_end_struct(v
, NULL
);
582 static void test_keyval_visit_optional(void)
589 qdict
= keyval_parse("a.b=1", NULL
, &error_abort
);
590 v
= qobject_input_visitor_new_keyval(QOBJECT(qdict
));
592 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
593 visit_optional(v
, "b", &present
);
594 g_assert(!present
); /* b missing */
595 visit_optional(v
, "a", &present
);
596 g_assert(present
); /* a present */
597 visit_start_struct(v
, "a", NULL
, 0, &error_abort
);
598 visit_optional(v
, "b", &present
);
599 g_assert(present
); /* a.b present */
600 visit_type_int(v
, "b", &i
, &error_abort
);
601 g_assert_cmpint(i
, ==, 1);
602 visit_optional(v
, "a", &present
);
603 g_assert(!present
); /* a.a missing */
604 visit_check_struct(v
, &error_abort
);
605 visit_end_struct(v
, NULL
);
606 visit_check_struct(v
, &error_abort
);
607 visit_end_struct(v
, NULL
);
611 int main(int argc
, char *argv
[])
613 g_test_init(&argc
, &argv
, NULL
);
614 g_test_add_func("/keyval/keyval_parse", test_keyval_parse
);
615 g_test_add_func("/keyval/keyval_parse/list", test_keyval_parse_list
);
616 g_test_add_func("/keyval/visit/bool", test_keyval_visit_bool
);
617 g_test_add_func("/keyval/visit/number", test_keyval_visit_number
);
618 g_test_add_func("/keyval/visit/size", test_keyval_visit_size
);
619 g_test_add_func("/keyval/visit/dict", test_keyval_visit_dict
);
620 g_test_add_func("/keyval/visit/list", test_keyval_visit_list
);
621 g_test_add_func("/keyval/visit/optional", test_keyval_visit_optional
);