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
495 qobject_unref(src);
496 qobject_unref(dst);
497}
498
499static void qdict_crumple_test_empty(void)
500{
501 QDict *src, *dst;
502
503 src = qdict_new();
504
505 dst = qobject_to(QDict, qdict_crumple(src, &error_abort));
506
507 g_assert_cmpint(qdict_size(dst), ==, 0);
508
509 qobject_unref(src);
510 qobject_unref(dst);
511}
512
513static int qdict_count_entries(QDict *dict)
514{
515 const QDictEntry *e;
516 int count = 0;
517
518 for (e = qdict_first(dict); e; e = qdict_next(dict, e)) {
519 count++;
520 }
521
522 return count;
523}
524
525static void qdict_rename_keys_test(void)
526{
527 QDict *dict = qdict_new();
528 QDict *copy;
529 QDictRenames *renames;
530 Error *local_err = NULL;
531
532 qdict_put_str(dict, "abc", "foo");
533 qdict_put_str(dict, "abcdef", "bar");
534 qdict_put_int(dict, "number", 42);
535 qdict_put_bool(dict, "flag", true);
536 qdict_put_null(dict, "nothing");
537
538
539 renames = (QDictRenames[]) {
540 { NULL, "this can be anything" }
541 };
542 copy = qdict_clone_shallow(dict);
543 qdict_rename_keys(copy, renames, &error_abort);
544
545 g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo");
546 g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar");
547 g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42);
548 g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true);
549 g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL);
550 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
551
552 qobject_unref(copy);
553
554
555 renames = (QDictRenames[]) {
556 { "abc", "str1" },
557 { "abcdef", "str2" },
558 { "number", "int" },
559 { "flag", "bool" },
560 { "nothing", "null" },
561 { NULL , NULL }
562 };
563 copy = qdict_clone_shallow(dict);
564 qdict_rename_keys(copy, renames, &error_abort);
565
566 g_assert(!qdict_haskey(copy, "abc"));
567 g_assert(!qdict_haskey(copy, "abcdef"));
568 g_assert(!qdict_haskey(copy, "number"));
569 g_assert(!qdict_haskey(copy, "flag"));
570 g_assert(!qdict_haskey(copy, "nothing"));
571
572 g_assert_cmpstr(qdict_get_str(copy, "str1"), ==, "foo");
573 g_assert_cmpstr(qdict_get_str(copy, "str2"), ==, "bar");
574 g_assert_cmpint(qdict_get_int(copy, "int"), ==, 42);
575 g_assert_cmpint(qdict_get_bool(copy, "bool"), ==, true);
576 g_assert(qobject_type(qdict_get(copy, "null")) == QTYPE_QNULL);
577 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
578
579 qobject_unref(copy);
580
581
582 renames = (QDictRenames[]) {
583 { "abc", "tmp" },
584 { "abcdef", "abc" },
585 { "number", "abcdef" },
586 { "flag", "number" },
587 { "nothing", "flag" },
588 { "tmp", "nothing" },
589 { NULL , NULL }
590 };
591 copy = qdict_clone_shallow(dict);
592 qdict_rename_keys(copy, renames, &error_abort);
593
594 g_assert_cmpstr(qdict_get_str(copy, "nothing"), ==, "foo");
595 g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "bar");
596 g_assert_cmpint(qdict_get_int(copy, "abcdef"), ==, 42);
597 g_assert_cmpint(qdict_get_bool(copy, "number"), ==, true);
598 g_assert(qobject_type(qdict_get(copy, "flag")) == QTYPE_QNULL);
599 g_assert(!qdict_haskey(copy, "tmp"));
600 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
601
602 qobject_unref(copy);
603
604
605 renames = (QDictRenames[]) {
606 { "abcdef", "abc" },
607 { NULL , NULL }
608 };
609 copy = qdict_clone_shallow(dict);
610 qdict_rename_keys(copy, renames, &local_err);
611
612 g_assert(local_err != NULL);
613 error_free(local_err);
614 local_err = NULL;
615
616 g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo");
617 g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar");
618 g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42);
619 g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true);
620 g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL);
621 g_assert_cmpint(qdict_count_entries(copy), ==, 5);
622
623 qobject_unref(copy);
624
625
626 renames = (QDictRenames[]) {
627 { "abcdef", "abc" },
628 { NULL , NULL }
629 };
630
631 qobject_unref(dict);
632 dict = qdict_new();
633
634 qdict_rename_keys(dict, renames, &error_abort);
635 g_assert(qdict_first(dict) == NULL);
636
637 qobject_unref(dict);
638}
639
640static void qdict_crumple_test_bad_inputs(void)
641{
642 QDict *src, *nested;
643 Error *error = NULL;
644
645 src = qdict_new();
646
647 qdict_put_str(src, "rule.0", "fred");
648 qdict_put_str(src, "rule.0.policy", "allow");
649
650 g_assert(qdict_crumple(src, &error) == NULL);
651 g_assert(error != NULL);
652 error_free(error);
653 error = NULL;
654 qobject_unref(src);
655
656 src = qdict_new();
657
658 qdict_put_str(src, "rule.0", "fred");
659 qdict_put_str(src, "rule.a", "allow");
660
661 g_assert(qdict_crumple(src, &error) == NULL);
662 g_assert(error != NULL);
663 error_free(error);
664 error = NULL;
665 qobject_unref(src);
666
667 src = qdict_new();
668
669 nested = qdict_new();
670 qdict_put(nested, "x", qdict_new());
671 qdict_put(src, "rule.a", nested);
672 qdict_put_str(src, "rule.b", "allow");
673
674 g_assert(qdict_crumple(src, &error) == NULL);
675 g_assert(error != NULL);
676 error_free(error);
677 error = NULL;
678 qobject_unref(src);
679
680 src = qdict_new();
681
682 qdict_put_str(src, "rule.0", "deny");
683 qdict_put_str(src, "rule.3", "allow");
684
685 g_assert(qdict_crumple(src, &error) == NULL);
686 g_assert(error != NULL);
687 error_free(error);
688 error = NULL;
689 qobject_unref(src);
690
691 src = qdict_new();
692
693 qdict_put_str(src, "rule.0", "deny");
694 qdict_put_str(src, "rule.+1", "allow");
695
696 g_assert(qdict_crumple(src, &error) == NULL);
697 g_assert(error != NULL);
698 error_free(error);
699 error = NULL;
700 qobject_unref(src);
701}
702
703int main(int argc, char **argv)
704{
705 g_test_init(&argc, &argv, NULL);
706
707 g_test_add_func("/public/defaults", qdict_defaults_test);
708 g_test_add_func("/public/flatten", qdict_flatten_test);
709 g_test_add_func("/public/clone_flatten", qdict_clone_flatten_test);
710 g_test_add_func("/public/array_split", qdict_array_split_test);
711 g_test_add_func("/public/array_entries", qdict_array_entries_test);
712 g_test_add_func("/public/join", qdict_join_test);
713 g_test_add_func("/public/crumple/recursive",
714 qdict_crumple_test_recursive);
715 g_test_add_func("/public/crumple/empty",
716 qdict_crumple_test_empty);
717 g_test_add_func("/public/crumple/bad_inputs",
718 qdict_crumple_test_bad_inputs);
719
720 g_test_add_func("/public/rename_keys", qdict_rename_keys_test);
721
722 return g_test_run();
723}
724