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