1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "block/qdict.h"
12#include "qapi/qmp/qlist.h"
13#include "qapi/qmp/qnum.h"
14#include "qapi/error.h"
15
16static void qdict_defaults_test(void)
17{
18 QDict *dict, *copy;
19
20 dict = qdict_new();
21 copy = qdict_new();
22
23 qdict_set_default_str(dict, "foo", "abc");
24 qdict_set_default_str(dict, "foo", "def");
25 g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "abc");
26 qdict_set_default_str(dict, "bar", "ghi");
27
28 qdict_copy_default(copy, dict, "foo");
29 g_assert_cmpstr(qdict_get_str(copy, "foo"), ==, "abc");
30 qdict_set_default_str(copy, "bar", "xyz");
31 qdict_copy_default(copy, dict, "bar");
32 g_assert_cmpstr(qdict_get_str(copy, "bar"), ==, "xyz");
33
34 qobject_unref(copy);
35 qobject_unref(dict);
36}
37
38static void qdict_flatten_test(void)
39{
40 QList *e_1 = qlist_new();
41 QList *e = qlist_new();
42 QDict *e_1_2 = qdict_new();
43 QDict *f = qdict_new();
44 QList *y = qlist_new();
45 QDict *z = qdict_new();
46 QDict *root = qdict_new();
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 qdict_put_int(e_1_2, "a", 0);
89 qdict_put_int(e_1_2, "b", 1);
90
91 qlist_append_int(e_1, 23);
92 qlist_append_int(e_1, 66);
93 qlist_append(e_1, e_1_2);
94 qlist_append_int(e, 42);
95 qlist_append(e, e_1);
96
97 qdict_put_int(f, "c", 2);
98 qdict_put_int(f, "d", 3);
99
100 qlist_append(y, qdict_new());
101
102 qdict_put(z, "a", qlist_new());
103
104 qdict_put(root, "e", e);
105 qdict_put(root, "f", f);
106 qdict_put_int(root, "g", 4);
107 qdict_put(root, "y", y);
108 qdict_put(root, "z", z);
109
110 qdict_flatten(root);
111
112 g_assert(qdict_get_int(root, "e.0") == 42);
113 g_assert(qdict_get_int(root, "e.1.0") == 23);
114 g_assert(qdict_get_int(root, "e.1.1") == 66);
115 g_assert(qdict_get_int(root, "e.1.2.a") == 0);
116 g_assert(qdict_get_int(root, "e.1.2.b") == 1);
117 g_assert(qdict_get_int(root, "f.c") == 2);
118 g_assert(qdict_get_int(root, "f.d") == 3);
119 g_assert(qdict_get_int(root, "g") == 4);
120 g_assert(!qdict_size(qdict_get_qdict(root, "y.0")));
121 g_assert(qlist_empty(qdict_get_qlist(root, "z.a")));
122
123 g_assert(qdict_size(root) == 10);
124
125 qobject_unref(root);
126}
127
128static void qdict_clone_flatten_test(void)
129{
130 QDict *dict1 = qdict_new();
131 QDict *dict2 = qdict_new();
132 QDict *cloned_dict1;
133
134
135
136
137
138
139
140 qdict_put_int(dict2, "b", 42);
141 qdict_put(dict1, "a", dict2);
142
143 cloned_dict1 = qdict_clone_shallow(dict1);
144
145 qdict_flatten(dict1);
146
147 g_assert(qdict_size(dict1) == 1);
148 g_assert(qdict_get_int(dict1, "a.b") == 42);
149
150 g_assert(qdict_size(cloned_dict1) == 1);
151 g_assert(qdict_get_qdict(cloned_dict1, "a") == dict2);
152
153 g_assert(qdict_size(dict2) == 1);
154 g_assert(qdict_get_int(dict2, "b") == 42);
155
156 qobject_unref(dict1);
157 qobject_unref(cloned_dict1);
158}
159
160static void qdict_array_split_test(void)
161{
162 QDict *test_dict = qdict_new();
163 QDict *dict1, *dict2;
164 QNum *int1;
165 QList *test_list;
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 qdict_put_int(test_dict, "1.x", 0);
205 qdict_put_int(test_dict, "4.y", 1);
206 qdict_put_int(test_dict, "0.a", 42);
207 qdict_put_int(test_dict, "o.o", 7);
208 qdict_put_int(test_dict, "0.b", 23);
209 qdict_put_int(test_dict, "2", 66);
210
211 qdict_array_split(test_dict, &test_list);
212
213 dict1 = qobject_to(QDict, qlist_pop(test_list));
214 dict2 = qobject_to(QDict, qlist_pop(test_list));
215 int1 = qobject_to(QNum, qlist_pop(test_list));
216
217 g_assert(dict1);
218 g_assert(dict2);
219 g_assert(int1);
220 g_assert(qlist_empty(test_list));
221
222 qobject_unref(test_list);
223
224 g_assert(qdict_get_int(dict1, "a") == 42);
225 g_assert(qdict_get_int(dict1, "b") == 23);
226
227 g_assert(qdict_size(dict1) == 2);
228
229 qobject_unref(dict1);
230
231 g_assert(qdict_get_int(dict2, "x") == 0);
232
233 g_assert(qdict_size(dict2) == 1);
234
235 qobject_unref(dict2);
236
237 g_assert_cmpint(qnum_get_int(int1), ==, 66);
238
239 qobject_unref(int1);
240
241 g_assert(qdict_get_int(test_dict, "4.y") == 1);
242 g_assert(qdict_get_int(test_dict, "o.o") == 7);
243
244 g_assert(qdict_size(test_dict) == 2);
245
246 qobject_unref(test_dict);
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 test_dict = qdict_new();
275
276 qdict_put_int(test_dict, "0", 42);
277 qdict_put_int(test_dict, "1", 23);
278 qdict_put_int(test_dict, "1.x", 84);
279
280 qdict_array_split(test_dict, &test_list);
281
282 int1 = qobject_to(QNum, qlist_pop(test_list));
283
284 g_assert(int1);
285 g_assert(qlist_empty(test_list));
286
287 qobject_unref(test_list);
288
289 g_assert_cmpint(qnum_get_int(int1), ==, 42);
290
291 qobject_unref(int1);
292
293 g_assert(qdict_get_int(test_dict, "1") == 23);
294 g_assert(qdict_get_int(test_dict, "1.x") == 84);
295
296 g_assert(qdict_size(test_dict) == 2);
297
298 qobject_unref(test_dict);
299}
300
301static void qdict_array_entries_test(void)
302{
303 QDict *dict = qdict_new();
304
305 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
306
307 qdict_put_int(dict, "bar", 0);
308 qdict_put_int(dict, "baz.0", 0);
309 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
310
311 qdict_put_int(dict, "foo.1", 0);
312 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
313 qdict_put_int(dict, "foo.0", 0);
314 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 2);
315 qdict_put_int(dict, "foo.bar", 0);
316 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
317 qdict_del(dict, "foo.bar");
318
319 qdict_put_int(dict, "foo.2.a", 0);
320 qdict_put_int(dict, "foo.2.b", 0);
321 qdict_put_int(dict, "foo.2.c", 0);
322 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 3);
323 g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
324
325 qobject_unref(dict);
326
327 dict = qdict_new();
328 qdict_put_int(dict, "1", 0);
329 g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
330 qdict_put_int(dict, "0", 0);
331 g_assert_cmpint(qdict_array_entries(dict, ""), ==, 2);
332 qdict_put_int(dict, "bar", 0);
333 g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
334 qdict_del(dict, "bar");
335
336 qdict_put_int(dict, "2.a", 0);
337 qdict_put_int(dict, "2.b", 0);
338 qdict_put_int(dict, "2.c", 0);
339 g_assert_cmpint(qdict_array_entries(dict, ""), ==, 3);
340
341 qobject_unref(dict);
342}
343
344static void qdict_join_test(void)
345{
346 QDict *dict1, *dict2;
347 bool overwrite = false;
348 int i;
349
350 dict1 = qdict_new();
351 dict2 = qdict_new();
352
353
354 do {
355
356 qdict_join(dict1, dict2, overwrite);
357
358 g_assert(qdict_size(dict1) == 0);
359 g_assert(qdict_size(dict2) == 0);
360
361
362
363 qdict_put_int(dict2, "foo", 42);
364
365 for (i = 0; i < 2; i++) {
366 qdict_join(dict1, dict2, overwrite);
367
368 g_assert(qdict_size(dict1) == 1);
369 g_assert(qdict_size(dict2) == 0);
370
371 g_assert(qdict_get_int(dict1, "foo") == 42);
372 }
373
374
375 qdict_put_int(dict2, "bar", 23);
376
377 qdict_join(dict1, dict2, overwrite);
378
379 g_assert(qdict_size(dict1) == 2);
380 g_assert(qdict_size(dict2) == 0);
381
382 g_assert(qdict_get_int(dict1, "foo") == 42);
383 g_assert(qdict_get_int(dict1, "bar") == 23);
384
385
386 qdict_put_int(dict2, "foo", 84);
387
388 qdict_join(dict1, dict2, overwrite);
389
390 g_assert(qdict_size(dict1) == 2);
391 g_assert(qdict_size(dict2) == !overwrite);
392
393 g_assert(qdict_get_int(dict1, "foo") == (overwrite ? 84 : 42));
394 g_assert(qdict_get_int(dict1, "bar") == 23);
395
396 if (!overwrite) {
397 g_assert(qdict_get_int(dict2, "foo") == 84);
398 }
399
400
401 g_assert(qdict_get(dict1, "foo")->base.refcnt == 1);
402 g_assert(qdict_get(dict1, "bar")->base.refcnt == 1);
403
404 if (!overwrite) {
405 g_assert(qdict_get(dict2, "foo")->base.refcnt == 1);
406 }
407
408
409 qdict_del(dict1, "foo");
410 qdict_del(dict1, "bar");
411
412 if (!overwrite) {
413 qdict_del(dict2, "foo");
414 }
415 } while (overwrite ^= true);
416
417 qobject_unref(dict1);
418 qobject_unref(dict2);
419}
420
421static void qdict_crumple_test_recursive(void)
422{
423 QDict *src, *dst, *rule, *vnc, *acl, *listen;
424 QDict *empty, *empty_dict, *empty_list_0;
425 QList *rules, *empty_list, *empty_dict_a;
426
427 src = qdict_new();
428 qdict_put_str(src, "vnc.listen.addr", "127.0.0.1");
429 qdict_put_str(src, "vnc.listen.port", "5901");
430 qdict_put_str(src, "vnc.acl.rules.0.match", "fred");
431 qdict_put_str(src, "vnc.acl.rules.0.policy", "allow");
432 qdict_put_str(src, "vnc.acl.rules.1.match", "bob");
433 qdict_put_str(src, "vnc.acl.rules.1.policy", "deny");
434 qdict_put_str(src, "vnc.acl.default", "deny");
435 qdict_put_str(src, "vnc.acl..name", "acl0");
436 qdict_put_str(src, "vnc.acl.rule..name", "acl0");
437 qdict_put(src, "empty.dict.a", qlist_new());
438 qdict_put(src, "empty.list.0", qdict_new());
439
440 dst = qobject_to(QDict, qdict_crumple(src, &error_abort));
441 g_assert(dst);
442 g_assert_cmpint(qdict_size(dst), ==, 2);
443
444 vnc = qdict_get_qdict(dst, "vnc");
445 g_assert(vnc);
446 g_assert_cmpint(qdict_size(vnc), ==, 3);
447
448 listen = qdict_get_qdict(vnc, "listen");
449 g_assert(listen);
450 g_assert_cmpint(qdict_size(listen), ==, 2);
451 g_assert_cmpstr("127.0.0.1", ==, qdict_get_str(listen, "addr"));
452 g_assert_cmpstr("5901", ==, qdict_get_str(listen, "port"));
453
454 acl = qdict_get_qdict(vnc, "acl");
455 g_assert(acl);
456 g_assert_cmpint(qdict_size(acl), ==, 3);
457
458 rules = qdict_get_qlist(acl, "rules");
459 g_assert(rules);
460 g_assert_cmpint(qlist_size(rules), ==, 2);
461
462 rule = qobject_to(QDict, qlist_pop(rules));
463 g_assert(rule);
464 g_assert_cmpint(qdict_size(rule), ==, 2);
465 g_assert_cmpstr("fred", ==, qdict_get_str(rule, "match"));
466 g_assert_cmpstr("allow", ==, qdict_get_str(rule, "policy"));
467 qobject_unref(rule);
468
469 rule = qobject_to(QDict, qlist_pop(rules));
470 g_assert(rule);
471 g_assert_cmpint(qdict_size(rule), ==, 2);
472 g_assert_cmpstr("bob", ==, qdict_get_str(rule, "match"));
473 g_assert_cmpstr("deny", ==, qdict_get_str(rule, "policy"));
474 qobject_unref(rule);
475
476
477 g_assert_cmpstr("acl0", ==, qdict_get_str(vnc, "acl.name"));
478 g_assert_cmpstr("acl0", ==, qdict_get_str(acl, "rule.name"));
479
480 empty = qdict_get_qdict(dst, "empty");
481 g_assert(empty);
482 g_assert_cmpint(qdict_size(empty), ==, 2);
483 empty_dict = qdict_get_qdict(empty, "dict");
484 g_assert(empty_dict);
485 g_assert_cmpint(qdict_size(empty_dict), ==, 1);
486 empty_dict_a = qdict_get_qlist(empty_dict, "a");
487 g_assert(empty_dict_a && qlist_empty(empty_dict_a));
488 empty_list = qdict_get_qlist(empty, "list");
489 g_assert(empty_list);
490 g_assert_cmpint(qlist_size(empty_list), ==, 1);
491 empty_list_0 = qobject_to(QDict, qlist_pop(empty_list));
492 g_assert(empty_list_0);
493 g_assert_cmpint(qdict_size(empty_list_0), ==, 0);
494 qobject_unref(empty_list_0);
495
496 qobject_unref(src);
497 qobject_unref(dst);
498}
499
500static void qdict_crumple_test_empty(void)
501{
502 QDict *src, *dst;
503
504 src = qdict_new();
505
506 dst = qobject_to(QDict, qdict_crumple(src, &error_abort));
507 g_assert(dst);
508 g_assert_cmpint(qdict_size(dst), ==, 0);
509
510 qobject_unref(src);
511 qobject_unref(dst);
512}
513
514static int qdict_count_entries(QDict *dict)
515{
516 const QDictEntry *e;
517 int count = 0;
518
519 for (e = qdict_first(dict); e; e = qdict_next(dict, e)) {
520 count++;
521 }
522
523 return count;
524}
525
526static void qdict_rename_keys_test(void)
527{
528 QDict *dict = qdict_new();
529 QDict *copy;
530 QDictRenames *renames;
531 Error *local_err = NULL;
532
533 qdict_put_str(dict, "abc", "foo");
534 qdict_put_str(dict, "abcdef", "bar");
535 qdict_put_int(dict, "number", 42);
536 qdict_put_bool(dict, "flag", true);
537 qdict_put_null(dict, "nothing");
538
539
540 renames = (QDictRenames[]) {
541 { NULL, "this can be anything" }
542 };
543 copy = qdict_clone_shallow(dict);
544 qdict_rename_keys(copy, renames, &error_abort);
545
546 g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo");
547 g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar");
548 g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42);
549 g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true);
550 g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL);
551 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
552
553 qobject_unref(copy);
554
555
556 renames = (QDictRenames[]) {
557 { "abc", "str1" },
558 { "abcdef", "str2" },
559 { "number", "int" },
560 { "flag", "bool" },
561 { "nothing", "null" },
562 { NULL , NULL }
563 };
564 copy = qdict_clone_shallow(dict);
565 qdict_rename_keys(copy, renames, &error_abort);
566
567 g_assert(!qdict_haskey(copy, "abc"));
568 g_assert(!qdict_haskey(copy, "abcdef"));
569 g_assert(!qdict_haskey(copy, "number"));
570 g_assert(!qdict_haskey(copy, "flag"));
571 g_assert(!qdict_haskey(copy, "nothing"));
572
573 g_assert_cmpstr(qdict_get_str(copy, "str1"), ==, "foo");
574 g_assert_cmpstr(qdict_get_str(copy, "str2"), ==, "bar");
575 g_assert_cmpint(qdict_get_int(copy, "int"), ==, 42);
576 g_assert_cmpint(qdict_get_bool(copy, "bool"), ==, true);
577 g_assert(qobject_type(qdict_get(copy, "null")) == QTYPE_QNULL);
578 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
579
580 qobject_unref(copy);
581
582
583 renames = (QDictRenames[]) {
584 { "abc", "tmp" },
585 { "abcdef", "abc" },
586 { "number", "abcdef" },
587 { "flag", "number" },
588 { "nothing", "flag" },
589 { "tmp", "nothing" },
590 { NULL , NULL }
591 };
592 copy = qdict_clone_shallow(dict);
593 qdict_rename_keys(copy, renames, &error_abort);
594
595 g_assert_cmpstr(qdict_get_str(copy, "nothing"), ==, "foo");
596 g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "bar");
597 g_assert_cmpint(qdict_get_int(copy, "abcdef"), ==, 42);
598 g_assert_cmpint(qdict_get_bool(copy, "number"), ==, true);
599 g_assert(qobject_type(qdict_get(copy, "flag")) == QTYPE_QNULL);
600 g_assert(!qdict_haskey(copy, "tmp"));
601 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
602
603 qobject_unref(copy);
604
605
606 renames = (QDictRenames[]) {
607 { "abcdef", "abc" },
608 { NULL , NULL }
609 };
610 copy = qdict_clone_shallow(dict);
611 qdict_rename_keys(copy, renames, &local_err);
612
613 error_free_or_abort(&local_err);
614
615 g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo");
616 g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar");
617 g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42);
618 g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true);
619 g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL);
620 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
621
622 qobject_unref(copy);
623
624
625 renames = (QDictRenames[]) {
626 { "abcdef", "abc" },
627 { NULL , NULL }
628 };
629
630 qobject_unref(dict);
631 dict = qdict_new();
632
633 qdict_rename_keys(dict, renames, &error_abort);
634 g_assert(qdict_first(dict) == NULL);
635
636 qobject_unref(dict);
637}
638
639static void qdict_crumple_test_bad_inputs(void)
640{
641 QDict *src, *nested;
642 Error *error = NULL;
643
644 src = qdict_new();
645
646 qdict_put_str(src, "rule.0", "fred");
647 qdict_put_str(src, "rule.0.policy", "allow");
648
649 g_assert(qdict_crumple(src, &error) == NULL);
650 error_free_or_abort(&error);
651 qobject_unref(src);
652
653 src = qdict_new();
654
655 qdict_put_str(src, "rule.0", "fred");
656 qdict_put_str(src, "rule.a", "allow");
657
658 g_assert(qdict_crumple(src, &error) == NULL);
659 error_free_or_abort(&error);
660 qobject_unref(src);
661
662 src = qdict_new();
663
664 nested = qdict_new();
665 qdict_put(nested, "x", qdict_new());
666 qdict_put(src, "rule.a", nested);
667 qdict_put_str(src, "rule.b", "allow");
668
669 g_assert(qdict_crumple(src, &error) == NULL);
670 error_free_or_abort(&error);
671 qobject_unref(src);
672
673 src = qdict_new();
674
675 qdict_put_str(src, "rule.0", "deny");
676 qdict_put_str(src, "rule.3", "allow");
677
678 g_assert(qdict_crumple(src, &error) == NULL);
679 error_free_or_abort(&error);
680 qobject_unref(src);
681
682 src = qdict_new();
683
684 qdict_put_str(src, "rule.0", "deny");
685 qdict_put_str(src, "rule.+1", "allow");
686
687 g_assert(qdict_crumple(src, &error) == NULL);
688 error_free_or_abort(&error);
689 qobject_unref(src);
690}
691
692int main(int argc, char **argv)
693{
694 g_test_init(&argc, &argv, NULL);
695
696 g_test_add_func("/public/defaults", qdict_defaults_test);
697 g_test_add_func("/public/flatten", qdict_flatten_test);
698 g_test_add_func("/public/clone_flatten", qdict_clone_flatten_test);
699 g_test_add_func("/public/array_split", qdict_array_split_test);
700 g_test_add_func("/public/array_entries", qdict_array_entries_test);
701 g_test_add_func("/public/join", qdict_join_test);
702 g_test_add_func("/public/crumple/recursive",
703 qdict_crumple_test_recursive);
704 g_test_add_func("/public/crumple/empty",
705 qdict_crumple_test_empty);
706 g_test_add_func("/public/crumple/bad_inputs",
707 qdict_crumple_test_bad_inputs);
708
709 g_test_add_func("/public/rename_keys", qdict_rename_keys_test);
710
711 return g_test_run();
712}
713