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
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 g_assert(local_err != NULL);
614 error_free(local_err);
615 local_err = NULL;
616
617 g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo");
618 g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar");
619 g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42);
620 g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true);
621 g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL);
622 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
623
624 qobject_unref(copy);
625
626
627 renames = (QDictRenames[]) {
628 { "abcdef", "abc" },
629 { NULL , NULL }
630 };
631
632 qobject_unref(dict);
633 dict = qdict_new();
634
635 qdict_rename_keys(dict, renames, &error_abort);
636 g_assert(qdict_first(dict) == NULL);
637
638 qobject_unref(dict);
639}
640
641static void qdict_crumple_test_bad_inputs(void)
642{
643 QDict *src, *nested;
644 Error *error = NULL;
645
646 src = qdict_new();
647
648 qdict_put_str(src, "rule.0", "fred");
649 qdict_put_str(src, "rule.0.policy", "allow");
650
651 g_assert(qdict_crumple(src, &error) == NULL);
652 g_assert(error != NULL);
653 error_free(error);
654 error = NULL;
655 qobject_unref(src);
656
657 src = qdict_new();
658
659 qdict_put_str(src, "rule.0", "fred");
660 qdict_put_str(src, "rule.a", "allow");
661
662 g_assert(qdict_crumple(src, &error) == NULL);
663 g_assert(error != NULL);
664 error_free(error);
665 error = NULL;
666 qobject_unref(src);
667
668 src = qdict_new();
669
670 nested = qdict_new();
671 qdict_put(nested, "x", qdict_new());
672 qdict_put(src, "rule.a", nested);
673 qdict_put_str(src, "rule.b", "allow");
674
675 g_assert(qdict_crumple(src, &error) == NULL);
676 g_assert(error != NULL);
677 error_free(error);
678 error = NULL;
679 qobject_unref(src);
680
681 src = qdict_new();
682
683 qdict_put_str(src, "rule.0", "deny");
684 qdict_put_str(src, "rule.3", "allow");
685
686 g_assert(qdict_crumple(src, &error) == NULL);
687 g_assert(error != NULL);
688 error_free(error);
689 error = NULL;
690 qobject_unref(src);
691
692 src = qdict_new();
693
694 qdict_put_str(src, "rule.0", "deny");
695 qdict_put_str(src, "rule.+1", "allow");
696
697 g_assert(qdict_crumple(src, &error) == NULL);
698 g_assert(error != NULL);
699 error_free(error);
700 error = NULL;
701 qobject_unref(src);
702}
703
704int main(int argc, char **argv)
705{
706 g_test_init(&argc, &argv, NULL);
707
708 g_test_add_func("/public/defaults", qdict_defaults_test);
709 g_test_add_func("/public/flatten", qdict_flatten_test);
710 g_test_add_func("/public/clone_flatten", qdict_clone_flatten_test);
711 g_test_add_func("/public/array_split", qdict_array_split_test);
712 g_test_add_func("/public/array_entries", qdict_array_entries_test);
713 g_test_add_func("/public/join", qdict_join_test);
714 g_test_add_func("/public/crumple/recursive",
715 qdict_crumple_test_recursive);
716 g_test_add_func("/public/crumple/empty",
717 qdict_crumple_test_empty);
718 g_test_add_func("/public/crumple/bad_inputs",
719 qdict_crumple_test_bad_inputs);
720
721 g_test_add_func("/public/rename_keys", qdict_rename_keys_test);
722
723 return g_test_run();
724}
725