2 * Unit tests for parsing of KEY=VALUE,... strings
4 * Copyright (C) 2017 Red Hat Inc.
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 "test-qapi-visit.h"
18 #include "qemu/cutils.h"
19 #include "qemu/option.h"
21 static void test_keyval_parse(void)
24 QDict *qdict, *sub_qdict;
29 qdict = keyval_parse("", NULL, &error_abort);
30 g_assert_cmpuint(qdict_size(qdict), ==, 0);
33 /* Empty key (qemu_opts_parse() accepts this) */
34 qdict = keyval_parse("=val", NULL, &err);
35 error_free_or_abort(&err);
38 /* Empty key fragment */
39 qdict = keyval_parse(".", NULL, &err);
40 error_free_or_abort(&err);
42 qdict = keyval_parse("key.", NULL, &err);
43 error_free_or_abort(&err);
46 /* Invalid non-empty key (qemu_opts_parse() doesn't care) */
47 qdict = keyval_parse("7up=val", NULL, &err);
48 error_free_or_abort(&err);
52 memset(long_key, 'a', 127);
55 params = g_strdup_printf("k.%s=v", long_key);
56 qdict = keyval_parse(params + 2, NULL, &err);
57 error_free_or_abort(&err);
60 /* Overlong key fragment */
61 qdict = keyval_parse(params, NULL, &err);
62 error_free_or_abort(&err);
66 /* Long key (qemu_opts_parse() accepts and truncates silently) */
67 params = g_strdup_printf("k.%s=v", long_key + 1);
68 qdict = keyval_parse(params + 2, NULL, &error_abort);
69 g_assert_cmpuint(qdict_size(qdict), ==, 1);
70 g_assert_cmpstr(qdict_get_try_str(qdict, long_key + 1), ==, "v");
73 /* Long key fragment */
74 qdict = keyval_parse(params, NULL, &error_abort);
75 g_assert_cmpuint(qdict_size(qdict), ==, 1);
76 sub_qdict = qdict_get_qdict(qdict, "k");
78 g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
79 g_assert_cmpstr(qdict_get_try_str(sub_qdict, long_key + 1), ==, "v");
83 /* Crap after valid key */
84 qdict = keyval_parse("key[0]=val", NULL, &err);
85 error_free_or_abort(&err);
88 /* Multiple keys, last one wins */
89 qdict = keyval_parse("a=1,b=2,,x,a=3", NULL, &error_abort);
90 g_assert_cmpuint(qdict_size(qdict), ==, 2);
91 g_assert_cmpstr(qdict_get_try_str(qdict, "a"), ==, "3");
92 g_assert_cmpstr(qdict_get_try_str(qdict, "b"), ==, "2,x");
95 /* Even when it doesn't in qemu_opts_parse() */
96 qdict = keyval_parse("id=foo,id=bar", NULL, &error_abort);
97 g_assert_cmpuint(qdict_size(qdict), ==, 1);
98 g_assert_cmpstr(qdict_get_try_str(qdict, "id"), ==, "bar");
102 qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, &error_abort);
103 g_assert_cmpuint(qdict_size(qdict), ==, 2);
104 sub_qdict = qdict_get_qdict(qdict, "a");
106 g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
107 sub_qdict = qdict_get_qdict(sub_qdict, "b");
109 g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
110 g_assert_cmpstr(qdict_get_try_str(sub_qdict, "c"), ==, "2");
111 g_assert_cmpstr(qdict_get_try_str(qdict, "d"), ==, "3");
114 /* Inconsistent dotted keys */
115 qdict = keyval_parse("a.b=1,a=2", NULL, &err);
116 error_free_or_abort(&err);
118 qdict = keyval_parse("a.b=1,a.b.c=2", NULL, &err);
119 error_free_or_abort(&err);
122 /* Trailing comma is ignored */
123 qdict = keyval_parse("x=y,", NULL, &error_abort);
124 g_assert_cmpuint(qdict_size(qdict), ==, 1);
125 g_assert_cmpstr(qdict_get_try_str(qdict, "x"), ==, "y");
128 /* Except when it isn't */
129 qdict = keyval_parse(",", NULL, &err);
130 error_free_or_abort(&err);
133 /* Value containing ,id= not misinterpreted as qemu_opts_parse() does */
134 qdict = keyval_parse("x=,,id=bar", NULL, &error_abort);
135 g_assert_cmpuint(qdict_size(qdict), ==, 1);
136 g_assert_cmpstr(qdict_get_try_str(qdict, "x"), ==, ",id=bar");
139 /* Anti-social ID is left to caller (qemu_opts_parse() rejects it) */
140 qdict = keyval_parse("id=666", NULL, &error_abort);
141 g_assert_cmpuint(qdict_size(qdict), ==, 1);
142 g_assert_cmpstr(qdict_get_try_str(qdict, "id"), ==, "666");
145 /* Implied value not supported (unlike qemu_opts_parse()) */
146 qdict = keyval_parse("an,noaus,noaus=", NULL, &err);
147 error_free_or_abort(&err);
150 /* Implied value, key "no" (qemu_opts_parse(): negated empty key) */
151 qdict = keyval_parse("no", NULL, &err);
152 error_free_or_abort(&err);
156 qdict = keyval_parse("an,aus=off,noaus=", "implied", &error_abort);
157 g_assert_cmpuint(qdict_size(qdict), ==, 3);
158 g_assert_cmpstr(qdict_get_try_str(qdict, "implied"), ==, "an");
159 g_assert_cmpstr(qdict_get_try_str(qdict, "aus"), ==, "off");
160 g_assert_cmpstr(qdict_get_try_str(qdict, "noaus"), ==, "");
163 /* Implied dotted key */
164 qdict = keyval_parse("val", "eins.zwei", &error_abort);
165 g_assert_cmpuint(qdict_size(qdict), ==, 1);
166 sub_qdict = qdict_get_qdict(qdict, "eins");
168 g_assert_cmpuint(qdict_size(sub_qdict), ==, 1);
169 g_assert_cmpstr(qdict_get_try_str(sub_qdict, "zwei"), ==, "val");
172 /* Implied key with empty value (qemu_opts_parse() accepts this) */
173 qdict = keyval_parse(",", "implied", &err);
174 error_free_or_abort(&err);
177 /* Likewise (qemu_opts_parse(): implied key with comma value) */
178 qdict = keyval_parse(",,,a=1", "implied", &err);
179 error_free_or_abort(&err);
182 /* Empty key is not an implied key */
183 qdict = keyval_parse("=val", "implied", &err);
184 error_free_or_abort(&err);
188 static void check_list012(QList *qlist)
190 static const char *expected[] = { "null", "eins", "zwei" };
195 for (i = 0; i < ARRAY_SIZE(expected); i++) {
196 qstr = qobject_to_qstring(qlist_pop(qlist));
198 g_assert_cmpstr(qstring_get_str(qstr), ==, expected[i]);
201 g_assert(qlist_empty(qlist));
204 static void test_keyval_parse_list(void)
207 QDict *qdict, *sub_qdict;
209 /* Root can't be a list */
210 qdict = keyval_parse("0=1", NULL, &err);
211 error_free_or_abort(&err);
214 /* List elements need not be in order */
215 qdict = keyval_parse("list.0=null,list.2=zwei,list.1=eins",
217 g_assert_cmpint(qdict_size(qdict), ==, 1);
218 check_list012(qdict_get_qlist(qdict, "list"));
221 /* Multiple indexes, last one wins */
222 qdict = keyval_parse("list.1=goner,list.0=null,list.01=eins,list.2=zwei",
224 g_assert_cmpint(qdict_size(qdict), ==, 1);
225 check_list012(qdict_get_qlist(qdict, "list"));
228 /* List at deeper nesting */
229 qdict = keyval_parse("a.list.1=eins,a.list.00=null,a.list.2=zwei",
231 g_assert_cmpint(qdict_size(qdict), ==, 1);
232 sub_qdict = qdict_get_qdict(qdict, "a");
233 g_assert_cmpint(qdict_size(sub_qdict), ==, 1);
234 check_list012(qdict_get_qlist(sub_qdict, "list"));
237 /* Inconsistent dotted keys: both list and dictionary */
238 qdict = keyval_parse("a.b.c=1,a.b.0=2", NULL, &err);
239 error_free_or_abort(&err);
241 qdict = keyval_parse("a.0.c=1,a.b.c=2", NULL, &err);
242 error_free_or_abort(&err);
245 /* Missing list indexes */
246 qdict = keyval_parse("list.1=lonely", NULL, &err);
247 error_free_or_abort(&err);
249 qdict = keyval_parse("list.0=null,list.2=eins,list.02=zwei", NULL, &err);
250 error_free_or_abort(&err);
254 static void test_keyval_visit_bool(void)
261 qdict = keyval_parse("bool1=on,bool2=off", NULL, &error_abort);
262 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
264 visit_start_struct(v, NULL, NULL, 0, &error_abort);
265 visit_type_bool(v, "bool1", &b, &error_abort);
267 visit_type_bool(v, "bool2", &b, &error_abort);
269 visit_check_struct(v, &error_abort);
270 visit_end_struct(v, NULL);
273 qdict = keyval_parse("bool1=offer", NULL, &error_abort);
274 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
276 visit_start_struct(v, NULL, NULL, 0, &error_abort);
277 visit_type_bool(v, "bool1", &b, &err);
278 error_free_or_abort(&err);
279 visit_end_struct(v, NULL);
283 static void test_keyval_visit_number(void)
290 /* Lower limit zero */
291 qdict = keyval_parse("number1=0", NULL, &error_abort);
292 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
294 visit_start_struct(v, NULL, NULL, 0, &error_abort);
295 visit_type_uint64(v, "number1", &u, &error_abort);
296 g_assert_cmpuint(u, ==, 0);
297 visit_check_struct(v, &error_abort);
298 visit_end_struct(v, NULL);
301 /* Upper limit 2^64-1 */
302 qdict = keyval_parse("number1=18446744073709551615,number2=-1",
304 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
306 visit_start_struct(v, NULL, NULL, 0, &error_abort);
307 visit_type_uint64(v, "number1", &u, &error_abort);
308 g_assert_cmphex(u, ==, UINT64_MAX);
309 visit_type_uint64(v, "number2", &u, &error_abort);
310 g_assert_cmphex(u, ==, UINT64_MAX);
311 visit_check_struct(v, &error_abort);
312 visit_end_struct(v, NULL);
315 /* Above upper limit */
316 qdict = keyval_parse("number1=18446744073709551616",
318 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
320 visit_start_struct(v, NULL, NULL, 0, &error_abort);
321 visit_type_uint64(v, "number1", &u, &err);
322 error_free_or_abort(&err);
323 visit_end_struct(v, NULL);
326 /* Below lower limit */
327 qdict = keyval_parse("number1=-18446744073709551616",
329 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
331 visit_start_struct(v, NULL, NULL, 0, &error_abort);
332 visit_type_uint64(v, "number1", &u, &err);
333 error_free_or_abort(&err);
334 visit_end_struct(v, NULL);
338 qdict = keyval_parse("number1=0x2a,number2=052",
340 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
342 visit_start_struct(v, NULL, NULL, 0, &error_abort);
343 visit_type_uint64(v, "number1", &u, &error_abort);
344 g_assert_cmpuint(u, ==, 42);
345 visit_type_uint64(v, "number2", &u, &error_abort);
346 g_assert_cmpuint(u, ==, 42);
347 visit_check_struct(v, &error_abort);
348 visit_end_struct(v, NULL);
352 qdict = keyval_parse("number1=3.14,number2=08",
354 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
356 visit_start_struct(v, NULL, NULL, 0, &error_abort);
357 visit_type_uint64(v, "number1", &u, &err);
358 error_free_or_abort(&err);
359 visit_type_uint64(v, "number2", &u, &err);
360 error_free_or_abort(&err);
361 visit_end_struct(v, NULL);
365 static void test_keyval_visit_size(void)
372 /* Lower limit zero */
373 qdict = keyval_parse("sz1=0", NULL, &error_abort);
374 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
376 visit_start_struct(v, NULL, NULL, 0, &error_abort);
377 visit_type_size(v, "sz1", &sz, &error_abort);
378 g_assert_cmpuint(sz, ==, 0);
379 visit_check_struct(v, &error_abort);
380 visit_end_struct(v, NULL);
383 /* Note: precision is 53 bits since we're parsing with strtod() */
385 /* Around limit of precision: 2^53-1, 2^53, 2^53+1 */
386 qdict = keyval_parse("sz1=9007199254740991,"
387 "sz2=9007199254740992,"
388 "sz3=9007199254740993",
390 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
392 visit_start_struct(v, NULL, NULL, 0, &error_abort);
393 visit_type_size(v, "sz1", &sz, &error_abort);
394 g_assert_cmphex(sz, ==, 0x1fffffffffffff);
395 visit_type_size(v, "sz2", &sz, &error_abort);
396 g_assert_cmphex(sz, ==, 0x20000000000000);
397 visit_type_size(v, "sz3", &sz, &error_abort);
398 g_assert_cmphex(sz, ==, 0x20000000000000);
399 visit_check_struct(v, &error_abort);
400 visit_end_struct(v, NULL);
403 /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */
404 qdict = keyval_parse("sz1=9223372036854774784," /* 7ffffffffffffc00 */
405 "sz2=9223372036854775295", /* 7ffffffffffffdff */
407 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
409 visit_start_struct(v, NULL, NULL, 0, &error_abort);
410 visit_type_size(v, "sz1", &sz, &error_abort);
411 g_assert_cmphex(sz, ==, 0x7ffffffffffffc00);
412 visit_type_size(v, "sz2", &sz, &error_abort);
413 g_assert_cmphex(sz, ==, 0x7ffffffffffffc00);
414 visit_check_struct(v, &error_abort);
415 visit_end_struct(v, NULL);
418 /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */
419 qdict = keyval_parse("sz1=18446744073709549568," /* fffffffffffff800 */
420 "sz2=18446744073709550591", /* fffffffffffffbff */
422 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
424 visit_start_struct(v, NULL, NULL, 0, &error_abort);
425 visit_type_size(v, "sz1", &sz, &error_abort);
426 g_assert_cmphex(sz, ==, 0xfffffffffffff800);
427 visit_type_size(v, "sz2", &sz, &error_abort);
428 g_assert_cmphex(sz, ==, 0xfffffffffffff800);
429 visit_check_struct(v, &error_abort);
430 visit_end_struct(v, NULL);
434 qdict = keyval_parse("sz1=-1,"
435 "sz2=18446744073709550592", /* fffffffffffffc00 */
437 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
439 visit_start_struct(v, NULL, NULL, 0, &error_abort);
440 visit_type_size(v, "sz1", &sz, &err);
441 error_free_or_abort(&err);
442 visit_type_size(v, "sz2", &sz, &err);
443 error_free_or_abort(&err);
444 visit_end_struct(v, NULL);
448 qdict = keyval_parse("sz1=8b,sz2=1.5k,sz3=2M,sz4=0.1G,sz5=16777215T",
450 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
452 visit_start_struct(v, NULL, NULL, 0, &error_abort);
453 visit_type_size(v, "sz1", &sz, &error_abort);
454 g_assert_cmpuint(sz, ==, 8);
455 visit_type_size(v, "sz2", &sz, &error_abort);
456 g_assert_cmpuint(sz, ==, 1536);
457 visit_type_size(v, "sz3", &sz, &error_abort);
458 g_assert_cmphex(sz, ==, 2 * M_BYTE);
459 visit_type_size(v, "sz4", &sz, &error_abort);
460 g_assert_cmphex(sz, ==, G_BYTE / 10);
461 visit_type_size(v, "sz5", &sz, &error_abort);
462 g_assert_cmphex(sz, ==, 16777215 * T_BYTE);
463 visit_check_struct(v, &error_abort);
464 visit_end_struct(v, NULL);
467 /* Beyond limit with suffix */
468 qdict = keyval_parse("sz1=16777216T", NULL, &error_abort);
469 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
471 visit_start_struct(v, NULL, NULL, 0, &error_abort);
472 visit_type_size(v, "sz1", &sz, &err);
473 error_free_or_abort(&err);
474 visit_end_struct(v, NULL);
478 qdict = keyval_parse("sz1=16E,sz2=16Gi", NULL, &error_abort);
479 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
481 visit_start_struct(v, NULL, NULL, 0, &error_abort);
482 visit_type_size(v, "sz1", &sz, &err);
483 error_free_or_abort(&err);
484 visit_type_size(v, "sz2", &sz, &err);
485 error_free_or_abort(&err);
486 visit_end_struct(v, NULL);
490 static void test_keyval_visit_dict(void)
497 qdict = keyval_parse("a.b.c=1,a.b.c=2,d=3", NULL, &error_abort);
498 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
500 visit_start_struct(v, NULL, NULL, 0, &error_abort);
501 visit_start_struct(v, "a", NULL, 0, &error_abort);
502 visit_start_struct(v, "b", NULL, 0, &error_abort);
503 visit_type_int(v, "c", &i, &error_abort);
504 g_assert_cmpint(i, ==, 2);
505 visit_check_struct(v, &error_abort);
506 visit_end_struct(v, NULL);
507 visit_check_struct(v, &error_abort);
508 visit_end_struct(v, NULL);
509 visit_type_int(v, "d", &i, &error_abort);
510 g_assert_cmpint(i, ==, 3);
511 visit_check_struct(v, &error_abort);
512 visit_end_struct(v, NULL);
515 qdict = keyval_parse("a.b=", NULL, &error_abort);
516 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
518 visit_start_struct(v, NULL, NULL, 0, &error_abort);
519 visit_start_struct(v, "a", NULL, 0, &error_abort);
520 visit_type_int(v, "c", &i, &err); /* a.c missing */
521 error_free_or_abort(&err);
522 visit_check_struct(v, &err);
523 error_free_or_abort(&err); /* a.b unexpected */
524 visit_end_struct(v, NULL);
525 visit_check_struct(v, &error_abort);
526 visit_end_struct(v, NULL);
530 static void test_keyval_visit_list(void)
537 qdict = keyval_parse("a.0=,a.1=I,a.2.0=II", NULL, &error_abort);
538 /* TODO empty list */
539 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
541 visit_start_struct(v, NULL, NULL, 0, &error_abort);
542 visit_start_list(v, "a", NULL, 0, &error_abort);
543 visit_type_str(v, NULL, &s, &error_abort);
544 g_assert_cmpstr(s, ==, "");
546 visit_type_str(v, NULL, &s, &error_abort);
547 g_assert_cmpstr(s, ==, "I");
549 visit_start_list(v, NULL, NULL, 0, &error_abort);
550 visit_type_str(v, NULL, &s, &error_abort);
551 g_assert_cmpstr(s, ==, "II");
553 visit_check_list(v, &error_abort);
554 visit_end_list(v, NULL);
555 visit_check_list(v, &error_abort);
556 visit_end_list(v, NULL);
557 visit_check_struct(v, &error_abort);
558 visit_end_struct(v, NULL);
561 qdict = keyval_parse("a.0=,b.0.0=head", NULL, &error_abort);
562 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
564 visit_start_struct(v, NULL, NULL, 0, &error_abort);
565 visit_start_list(v, "a", NULL, 0, &error_abort);
566 visit_check_list(v, &err); /* a[0] unexpected */
567 error_free_or_abort(&err);
568 visit_end_list(v, NULL);
569 visit_start_list(v, "b", NULL, 0, &error_abort);
570 visit_start_list(v, NULL, NULL, 0, &error_abort);
571 visit_type_str(v, NULL, &s, &error_abort);
572 g_assert_cmpstr(s, ==, "head");
574 visit_type_str(v, NULL, &s, &err); /* b[0][1] missing */
575 error_free_or_abort(&err);
576 visit_end_list(v, NULL);
577 visit_end_list(v, NULL);
578 visit_check_struct(v, &error_abort);
579 visit_end_struct(v, NULL);
583 static void test_keyval_visit_optional(void)
590 qdict = keyval_parse("a.b=1", NULL, &error_abort);
591 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
593 visit_start_struct(v, NULL, NULL, 0, &error_abort);
594 visit_optional(v, "b", &present);
595 g_assert(!present); /* b missing */
596 visit_optional(v, "a", &present);
597 g_assert(present); /* a present */
598 visit_start_struct(v, "a", NULL, 0, &error_abort);
599 visit_optional(v, "b", &present);
600 g_assert(present); /* a.b present */
601 visit_type_int(v, "b", &i, &error_abort);
602 g_assert_cmpint(i, ==, 1);
603 visit_optional(v, "a", &present);
604 g_assert(!present); /* a.a missing */
605 visit_check_struct(v, &error_abort);
606 visit_end_struct(v, NULL);
607 visit_check_struct(v, &error_abort);
608 visit_end_struct(v, NULL);
612 static void test_keyval_visit_alternate(void)
622 * Can't do scalar alternate variants other than string. You get
623 * the string variant if there is one, else an error.
624 * TODO make it work for unambiguous cases like AltEnumBool below
626 qdict = keyval_parse("a=1,b=2,c=on", NULL, &error_abort);
627 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
629 visit_start_struct(v, NULL, NULL, 0, &error_abort);
630 visit_type_AltStrObj(v, "a", &aso, &error_abort);
631 g_assert_cmpint(aso->type, ==, QTYPE_QSTRING);
632 g_assert_cmpstr(aso->u.s, ==, "1");
633 qapi_free_AltStrObj(aso);
634 visit_type_AltNumEnum(v, "b", &ane, &err);
635 error_free_or_abort(&err);
636 visit_type_AltEnumBool(v, "c", &aeb, &err);
637 error_free_or_abort(&err);
638 visit_end_struct(v, NULL);
642 static void test_keyval_visit_any(void)
650 qdict = keyval_parse("a.0=null,a.1=1", NULL, &error_abort);
651 v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
653 visit_start_struct(v, NULL, NULL, 0, &error_abort);
654 visit_type_any(v, "a", &any, &error_abort);
655 qlist = qobject_to_qlist(any);
657 qstr = qobject_to_qstring(qlist_pop(qlist));
658 g_assert_cmpstr(qstring_get_str(qstr), ==, "null");
660 qstr = qobject_to_qstring(qlist_pop(qlist));
661 g_assert_cmpstr(qstring_get_str(qstr), ==, "1");
662 g_assert(qlist_empty(qlist));
665 visit_check_struct(v, &error_abort);
666 visit_end_struct(v, NULL);
670 int main(int argc, char *argv[])
672 g_test_init(&argc, &argv, NULL);
673 g_test_add_func("/keyval/keyval_parse", test_keyval_parse);
674 g_test_add_func("/keyval/keyval_parse/list", test_keyval_parse_list);
675 g_test_add_func("/keyval/visit/bool", test_keyval_visit_bool);
676 g_test_add_func("/keyval/visit/number", test_keyval_visit_number);
677 g_test_add_func("/keyval/visit/size", test_keyval_visit_size);
678 g_test_add_func("/keyval/visit/dict", test_keyval_visit_dict);
679 g_test_add_func("/keyval/visit/list", test_keyval_visit_list);
680 g_test_add_func("/keyval/visit/optional", test_keyval_visit_optional);
681 g_test_add_func("/keyval/visit/alternate", test_keyval_visit_alternate);
682 g_test_add_func("/keyval/visit/any", test_keyval_visit_any);