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