1
2
3
4
5
6
7
8
9
10
11
12#include <glib.h>
13
14#include "qapi/qmp/qint.h"
15#include "qapi/qmp/qdict.h"
16#include "qapi/qmp/qstring.h"
17#include "qemu-common.h"
18
19
20
21
22
23
24
25static void qdict_new_test(void)
26{
27 QDict *qdict;
28
29 qdict = qdict_new();
30 g_assert(qdict != NULL);
31 g_assert(qdict_size(qdict) == 0);
32 g_assert(qdict->base.refcnt == 1);
33 g_assert(qobject_type(QOBJECT(qdict)) == QTYPE_QDICT);
34
35
36 g_free(qdict);
37}
38
39static void qdict_put_obj_test(void)
40{
41 QInt *qi;
42 QDict *qdict;
43 QDictEntry *ent;
44 const int num = 42;
45
46 qdict = qdict_new();
47
48
49 qdict_put_obj(qdict, "", QOBJECT(qint_from_int(num)));
50
51 g_assert(qdict_size(qdict) == 1);
52 ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]);
53 qi = qobject_to_qint(ent->value);
54 g_assert(qint_get_int(qi) == num);
55
56
57 QDECREF(qi);
58 g_free(ent->key);
59 g_free(ent);
60 g_free(qdict);
61}
62
63static void qdict_destroy_simple_test(void)
64{
65 QDict *qdict;
66
67 qdict = qdict_new();
68 qdict_put_obj(qdict, "num", QOBJECT(qint_from_int(0)));
69 qdict_put_obj(qdict, "str", QOBJECT(qstring_from_str("foo")));
70
71 QDECREF(qdict);
72}
73
74static void qdict_get_test(void)
75{
76 QInt *qi;
77 QObject *obj;
78 const int value = -42;
79 const char *key = "test";
80 QDict *tests_dict = qdict_new();
81
82 qdict_put(tests_dict, key, qint_from_int(value));
83
84 obj = qdict_get(tests_dict, key);
85 g_assert(obj != NULL);
86
87 qi = qobject_to_qint(obj);
88 g_assert(qint_get_int(qi) == value);
89
90 QDECREF(tests_dict);
91}
92
93static void qdict_get_int_test(void)
94{
95 int ret;
96 const int value = 100;
97 const char *key = "int";
98 QDict *tests_dict = qdict_new();
99
100 qdict_put(tests_dict, key, qint_from_int(value));
101
102 ret = qdict_get_int(tests_dict, key);
103 g_assert(ret == value);
104
105 QDECREF(tests_dict);
106}
107
108static void qdict_get_try_int_test(void)
109{
110 int ret;
111 const int value = 100;
112 const char *key = "int";
113 QDict *tests_dict = qdict_new();
114
115 qdict_put(tests_dict, key, qint_from_int(value));
116
117 ret = qdict_get_try_int(tests_dict, key, 0);
118 g_assert(ret == value);
119
120 QDECREF(tests_dict);
121}
122
123static void qdict_get_str_test(void)
124{
125 const char *p;
126 const char *key = "key";
127 const char *str = "string";
128 QDict *tests_dict = qdict_new();
129
130 qdict_put(tests_dict, key, qstring_from_str(str));
131
132 p = qdict_get_str(tests_dict, key);
133 g_assert(p != NULL);
134 g_assert(strcmp(p, str) == 0);
135
136 QDECREF(tests_dict);
137}
138
139static void qdict_get_try_str_test(void)
140{
141 const char *p;
142 const char *key = "key";
143 const char *str = "string";
144 QDict *tests_dict = qdict_new();
145
146 qdict_put(tests_dict, key, qstring_from_str(str));
147
148 p = qdict_get_try_str(tests_dict, key);
149 g_assert(p != NULL);
150 g_assert(strcmp(p, str) == 0);
151
152 QDECREF(tests_dict);
153}
154
155static void qdict_defaults_test(void)
156{
157 QDict *dict, *copy;
158
159 dict = qdict_new();
160 copy = qdict_new();
161
162 qdict_set_default_str(dict, "foo", "abc");
163 qdict_set_default_str(dict, "foo", "def");
164 g_assert_cmpstr(qdict_get_str(dict, "foo"), ==, "abc");
165 qdict_set_default_str(dict, "bar", "ghi");
166
167 qdict_copy_default(copy, dict, "foo");
168 g_assert_cmpstr(qdict_get_str(copy, "foo"), ==, "abc");
169 qdict_set_default_str(copy, "bar", "xyz");
170 qdict_copy_default(copy, dict, "bar");
171 g_assert_cmpstr(qdict_get_str(copy, "bar"), ==, "xyz");
172
173 QDECREF(copy);
174 QDECREF(dict);
175}
176
177static void qdict_haskey_not_test(void)
178{
179 QDict *tests_dict = qdict_new();
180 g_assert(qdict_haskey(tests_dict, "test") == 0);
181
182 QDECREF(tests_dict);
183}
184
185static void qdict_haskey_test(void)
186{
187 const char *key = "test";
188 QDict *tests_dict = qdict_new();
189
190 qdict_put(tests_dict, key, qint_from_int(0));
191 g_assert(qdict_haskey(tests_dict, key) == 1);
192
193 QDECREF(tests_dict);
194}
195
196static void qdict_del_test(void)
197{
198 const char *key = "key test";
199 QDict *tests_dict = qdict_new();
200
201 qdict_put(tests_dict, key, qstring_from_str("foo"));
202 g_assert(qdict_size(tests_dict) == 1);
203
204 qdict_del(tests_dict, key);
205
206 g_assert(qdict_size(tests_dict) == 0);
207 g_assert(qdict_haskey(tests_dict, key) == 0);
208
209 QDECREF(tests_dict);
210}
211
212static void qobject_to_qdict_test(void)
213{
214 QDict *tests_dict = qdict_new();
215 g_assert(qobject_to_qdict(QOBJECT(tests_dict)) == tests_dict);
216
217 QDECREF(tests_dict);
218}
219
220static void qdict_iterapi_test(void)
221{
222 int count;
223 const QDictEntry *ent;
224 QDict *tests_dict = qdict_new();
225
226 g_assert(qdict_first(tests_dict) == NULL);
227
228 qdict_put(tests_dict, "key1", qint_from_int(1));
229 qdict_put(tests_dict, "key2", qint_from_int(2));
230 qdict_put(tests_dict, "key3", qint_from_int(3));
231
232 count = 0;
233 for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){
234 g_assert(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1);
235 count++;
236 }
237
238 g_assert(count == qdict_size(tests_dict));
239
240
241 count = 0;
242 for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){
243 g_assert(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1);
244 count++;
245 }
246
247 g_assert(count == qdict_size(tests_dict));
248
249 QDECREF(tests_dict);
250}
251
252static void qdict_flatten_test(void)
253{
254 QList *list1 = qlist_new();
255 QList *list2 = qlist_new();
256 QDict *dict1 = qdict_new();
257 QDict *dict2 = qdict_new();
258 QDict *dict3 = qdict_new();
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296 qdict_put(dict1, "a", qint_from_int(0));
297 qdict_put(dict1, "b", qint_from_int(1));
298
299 qlist_append_obj(list1, QOBJECT(qint_from_int(23)));
300 qlist_append_obj(list1, QOBJECT(qint_from_int(66)));
301 qlist_append_obj(list1, QOBJECT(dict1));
302 qlist_append_obj(list2, QOBJECT(qint_from_int(42)));
303 qlist_append_obj(list2, QOBJECT(list1));
304
305 qdict_put(dict2, "c", qint_from_int(2));
306 qdict_put(dict2, "d", qint_from_int(3));
307 qdict_put_obj(dict3, "e", QOBJECT(list2));
308 qdict_put_obj(dict3, "f", QOBJECT(dict2));
309 qdict_put(dict3, "g", qint_from_int(4));
310
311 qdict_flatten(dict3);
312
313 g_assert(qdict_get_int(dict3, "e.0") == 42);
314 g_assert(qdict_get_int(dict3, "e.1.0") == 23);
315 g_assert(qdict_get_int(dict3, "e.1.1") == 66);
316 g_assert(qdict_get_int(dict3, "e.1.2.a") == 0);
317 g_assert(qdict_get_int(dict3, "e.1.2.b") == 1);
318 g_assert(qdict_get_int(dict3, "f.c") == 2);
319 g_assert(qdict_get_int(dict3, "f.d") == 3);
320 g_assert(qdict_get_int(dict3, "g") == 4);
321
322 g_assert(qdict_size(dict3) == 8);
323
324 QDECREF(dict3);
325}
326
327static void qdict_array_split_test(void)
328{
329 QDict *test_dict = qdict_new();
330 QDict *dict1, *dict2;
331 QInt *int1;
332 QList *test_list;
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371 qdict_put(test_dict, "1.x", qint_from_int(0));
372 qdict_put(test_dict, "4.y", qint_from_int(1));
373 qdict_put(test_dict, "0.a", qint_from_int(42));
374 qdict_put(test_dict, "o.o", qint_from_int(7));
375 qdict_put(test_dict, "0.b", qint_from_int(23));
376 qdict_put(test_dict, "2", qint_from_int(66));
377
378 qdict_array_split(test_dict, &test_list);
379
380 dict1 = qobject_to_qdict(qlist_pop(test_list));
381 dict2 = qobject_to_qdict(qlist_pop(test_list));
382 int1 = qobject_to_qint(qlist_pop(test_list));
383
384 g_assert(dict1);
385 g_assert(dict2);
386 g_assert(int1);
387 g_assert(qlist_empty(test_list));
388
389 QDECREF(test_list);
390
391 g_assert(qdict_get_int(dict1, "a") == 42);
392 g_assert(qdict_get_int(dict1, "b") == 23);
393
394 g_assert(qdict_size(dict1) == 2);
395
396 QDECREF(dict1);
397
398 g_assert(qdict_get_int(dict2, "x") == 0);
399
400 g_assert(qdict_size(dict2) == 1);
401
402 QDECREF(dict2);
403
404 g_assert(qint_get_int(int1) == 66);
405
406 QDECREF(int1);
407
408 g_assert(qdict_get_int(test_dict, "4.y") == 1);
409 g_assert(qdict_get_int(test_dict, "o.o") == 7);
410
411 g_assert(qdict_size(test_dict) == 2);
412
413 QDECREF(test_dict);
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442 test_dict = qdict_new();
443
444 qdict_put(test_dict, "0", qint_from_int(42));
445 qdict_put(test_dict, "1", qint_from_int(23));
446 qdict_put(test_dict, "1.x", qint_from_int(84));
447
448 qdict_array_split(test_dict, &test_list);
449
450 int1 = qobject_to_qint(qlist_pop(test_list));
451
452 g_assert(int1);
453 g_assert(qlist_empty(test_list));
454
455 QDECREF(test_list);
456
457 g_assert(qint_get_int(int1) == 42);
458
459 QDECREF(int1);
460
461 g_assert(qdict_get_int(test_dict, "1") == 23);
462 g_assert(qdict_get_int(test_dict, "1.x") == 84);
463
464 g_assert(qdict_size(test_dict) == 2);
465
466 QDECREF(test_dict);
467}
468
469static void qdict_array_entries_test(void)
470{
471 QDict *dict = qdict_new();
472
473 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
474
475 qdict_put(dict, "bar", qint_from_int(0));
476 qdict_put(dict, "baz.0", qint_from_int(0));
477 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 0);
478
479 qdict_put(dict, "foo.1", qint_from_int(0));
480 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
481 qdict_put(dict, "foo.0", qint_from_int(0));
482 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 2);
483 qdict_put(dict, "foo.bar", qint_from_int(0));
484 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, -EINVAL);
485 qdict_del(dict, "foo.bar");
486
487 qdict_put(dict, "foo.2.a", qint_from_int(0));
488 qdict_put(dict, "foo.2.b", qint_from_int(0));
489 qdict_put(dict, "foo.2.c", qint_from_int(0));
490 g_assert_cmpint(qdict_array_entries(dict, "foo."), ==, 3);
491 g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
492
493 QDECREF(dict);
494
495 dict = qdict_new();
496 qdict_put(dict, "1", qint_from_int(0));
497 g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
498 qdict_put(dict, "0", qint_from_int(0));
499 g_assert_cmpint(qdict_array_entries(dict, ""), ==, 2);
500 qdict_put(dict, "bar", qint_from_int(0));
501 g_assert_cmpint(qdict_array_entries(dict, ""), ==, -EINVAL);
502 qdict_del(dict, "bar");
503
504 qdict_put(dict, "2.a", qint_from_int(0));
505 qdict_put(dict, "2.b", qint_from_int(0));
506 qdict_put(dict, "2.c", qint_from_int(0));
507 g_assert_cmpint(qdict_array_entries(dict, ""), ==, 3);
508
509 QDECREF(dict);
510}
511
512static void qdict_join_test(void)
513{
514 QDict *dict1, *dict2;
515 bool overwrite = false;
516 int i;
517
518 dict1 = qdict_new();
519 dict2 = qdict_new();
520
521
522
523 do
524 {
525
526 qdict_join(dict1, dict2, overwrite);
527
528 g_assert(qdict_size(dict1) == 0);
529 g_assert(qdict_size(dict2) == 0);
530
531
532
533
534 qdict_put(dict2, "foo", qint_from_int(42));
535
536 for (i = 0; i < 2; i++) {
537 qdict_join(dict1, dict2, overwrite);
538
539 g_assert(qdict_size(dict1) == 1);
540 g_assert(qdict_size(dict2) == 0);
541
542 g_assert(qdict_get_int(dict1, "foo") == 42);
543 }
544
545
546
547 qdict_put(dict2, "bar", qint_from_int(23));
548
549 qdict_join(dict1, dict2, overwrite);
550
551 g_assert(qdict_size(dict1) == 2);
552 g_assert(qdict_size(dict2) == 0);
553
554 g_assert(qdict_get_int(dict1, "foo") == 42);
555 g_assert(qdict_get_int(dict1, "bar") == 23);
556
557
558
559 qdict_put(dict2, "foo", qint_from_int(84));
560
561 qdict_join(dict1, dict2, overwrite);
562
563 g_assert(qdict_size(dict1) == 2);
564 g_assert(qdict_size(dict2) == !overwrite);
565
566 g_assert(qdict_get_int(dict1, "foo") == overwrite ? 84 : 42);
567 g_assert(qdict_get_int(dict1, "bar") == 23);
568
569 if (!overwrite) {
570 g_assert(qdict_get_int(dict2, "foo") == 84);
571 }
572
573
574
575 g_assert(qdict_get(dict1, "foo")->refcnt == 1);
576 g_assert(qdict_get(dict1, "bar")->refcnt == 1);
577
578 if (!overwrite) {
579 g_assert(qdict_get(dict2, "foo")->refcnt == 1);
580 }
581
582
583
584 qdict_del(dict1, "foo");
585 qdict_del(dict1, "bar");
586
587 if (!overwrite) {
588 qdict_del(dict2, "foo");
589 }
590 }
591 while (overwrite ^= true);
592
593
594 QDECREF(dict1);
595 QDECREF(dict2);
596}
597
598
599
600
601
602static void qdict_put_exists_test(void)
603{
604 int value;
605 const char *key = "exists";
606 QDict *tests_dict = qdict_new();
607
608 qdict_put(tests_dict, key, qint_from_int(1));
609 qdict_put(tests_dict, key, qint_from_int(2));
610
611 value = qdict_get_int(tests_dict, key);
612 g_assert(value == 2);
613
614 g_assert(qdict_size(tests_dict) == 1);
615
616 QDECREF(tests_dict);
617}
618
619static void qdict_get_not_exists_test(void)
620{
621 QDict *tests_dict = qdict_new();
622 g_assert(qdict_get(tests_dict, "foo") == NULL);
623
624 QDECREF(tests_dict);
625}
626
627
628
629
630
631
632
633
634static void remove_dots(char *string)
635{
636 char *p = strchr(string, ':');
637 if (p)
638 *p = '\0';
639}
640
641static QString *read_line(FILE *file, char *key)
642{
643 char value[128];
644
645 if (fscanf(file, "%127s%127s", key, value) == EOF) {
646 return NULL;
647 }
648 remove_dots(key);
649 return qstring_from_str(value);
650}
651
652#define reset_file(file) fseek(file, 0L, SEEK_SET)
653
654static void qdict_stress_test(void)
655{
656 size_t lines;
657 char key[128];
658 FILE *test_file;
659 QDict *qdict;
660 QString *value;
661 const char *test_file_path = "qdict-test-data.txt";
662
663 test_file = fopen(test_file_path, "r");
664 g_assert(test_file != NULL);
665
666
667 qdict = qdict_new();
668 g_assert(qdict != NULL);
669
670
671 for (lines = 0;; lines++) {
672 value = read_line(test_file, key);
673 if (!value)
674 break;
675
676 qdict_put(qdict, key, value);
677 }
678 g_assert(qdict_size(qdict) == lines);
679
680
681 reset_file(test_file);
682 for (;;) {
683 const char *str1, *str2;
684
685 value = read_line(test_file, key);
686 if (!value)
687 break;
688
689 str1 = qstring_get_str(value);
690
691 str2 = qdict_get_str(qdict, key);
692 g_assert(str2 != NULL);
693
694 g_assert(strcmp(str1, str2) == 0);
695
696 QDECREF(value);
697 }
698
699
700 reset_file(test_file);
701 for (;;) {
702 value = read_line(test_file, key);
703 if (!value)
704 break;
705
706 qdict_del(qdict, key);
707 QDECREF(value);
708
709 g_assert(qdict_haskey(qdict, key) == 0);
710 }
711 fclose(test_file);
712
713 g_assert(qdict_size(qdict) == 0);
714 QDECREF(qdict);
715}
716
717int main(int argc, char **argv)
718{
719 g_test_init(&argc, &argv, NULL);
720
721 g_test_add_func("/public/new", qdict_new_test);
722 g_test_add_func("/public/put_obj", qdict_put_obj_test);
723 g_test_add_func("/public/destroy_simple", qdict_destroy_simple_test);
724
725
726 g_test_add_func("/public/get", qdict_get_test);
727 g_test_add_func("/public/get_int", qdict_get_int_test);
728 g_test_add_func("/public/get_try_int", qdict_get_try_int_test);
729 g_test_add_func("/public/get_str", qdict_get_str_test);
730 g_test_add_func("/public/get_try_str", qdict_get_try_str_test);
731 g_test_add_func("/public/defaults", qdict_defaults_test);
732 g_test_add_func("/public/haskey_not", qdict_haskey_not_test);
733 g_test_add_func("/public/haskey", qdict_haskey_test);
734 g_test_add_func("/public/del", qdict_del_test);
735 g_test_add_func("/public/to_qdict", qobject_to_qdict_test);
736 g_test_add_func("/public/iterapi", qdict_iterapi_test);
737 g_test_add_func("/public/flatten", qdict_flatten_test);
738 g_test_add_func("/public/array_split", qdict_array_split_test);
739 g_test_add_func("/public/array_entries", qdict_array_entries_test);
740 g_test_add_func("/public/join", qdict_join_test);
741
742 g_test_add_func("/errors/put_exists", qdict_put_exists_test);
743 g_test_add_func("/errors/get_not_exists", qdict_get_not_exists_test);
744
745
746 if (g_test_slow()) {
747 g_test_add_func("/stress/test", qdict_stress_test);
748 }
749
750 return g_test_run();
751}
752