root / tests / test-visitor-serialization.c @ b3ce604e
History | View | Annotate | Download (20.4 kB)
1 | 2d496105 | Michael Roth | /*
|
---|---|---|---|
2 | 2d496105 | Michael Roth | * Unit-tests for visitor-based serialization
|
3 | 2d496105 | Michael Roth | *
|
4 | 2d496105 | Michael Roth | * Copyright IBM, Corp. 2012
|
5 | 2d496105 | Michael Roth | *
|
6 | 2d496105 | Michael Roth | * Authors:
|
7 | 2d496105 | Michael Roth | * Michael Roth <mdroth@linux.vnet.ibm.com>
|
8 | 2d496105 | Michael Roth | *
|
9 | 2d496105 | Michael Roth | * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
10 | 2d496105 | Michael Roth | * See the COPYING file in the top-level directory.
|
11 | 2d496105 | Michael Roth | */
|
12 | 2d496105 | Michael Roth | |
13 | 2d496105 | Michael Roth | #include <glib.h> |
14 | 2d496105 | Michael Roth | #include <stdlib.h> |
15 | 2d496105 | Michael Roth | #include <stdint.h> |
16 | 2d496105 | Michael Roth | #include <float.h> |
17 | 2d496105 | Michael Roth | #include "test-qapi-types.h" |
18 | 2d496105 | Michael Roth | #include "test-qapi-visit.h" |
19 | 2d496105 | Michael Roth | #include "qemu-objects.h" |
20 | 2d496105 | Michael Roth | #include "qapi/qmp-input-visitor.h" |
21 | 2d496105 | Michael Roth | #include "qapi/qmp-output-visitor.h" |
22 | 0d30b0a2 | Michael Roth | #include "qapi/string-input-visitor.h" |
23 | 0d30b0a2 | Michael Roth | #include "qapi/string-output-visitor.h" |
24 | 2d496105 | Michael Roth | |
25 | 2d496105 | Michael Roth | typedef struct PrimitiveType { |
26 | 2d496105 | Michael Roth | union {
|
27 | 2d496105 | Michael Roth | const char *string; |
28 | 2d496105 | Michael Roth | bool boolean;
|
29 | 2d496105 | Michael Roth | double number;
|
30 | 2d496105 | Michael Roth | int64_t integer; |
31 | 2d496105 | Michael Roth | uint8_t u8; |
32 | 2d496105 | Michael Roth | uint16_t u16; |
33 | 2d496105 | Michael Roth | uint32_t u32; |
34 | 2d496105 | Michael Roth | uint64_t u64; |
35 | 2d496105 | Michael Roth | int8_t s8; |
36 | 2d496105 | Michael Roth | int16_t s16; |
37 | 2d496105 | Michael Roth | int32_t s32; |
38 | 2d496105 | Michael Roth | int64_t s64; |
39 | 2d496105 | Michael Roth | intmax_t max; |
40 | 2d496105 | Michael Roth | } value; |
41 | 2d496105 | Michael Roth | enum {
|
42 | 2d496105 | Michael Roth | PTYPE_STRING = 0,
|
43 | 2d496105 | Michael Roth | PTYPE_BOOLEAN, |
44 | 2d496105 | Michael Roth | PTYPE_NUMBER, |
45 | 2d496105 | Michael Roth | PTYPE_INTEGER, |
46 | 2d496105 | Michael Roth | PTYPE_U8, |
47 | 2d496105 | Michael Roth | PTYPE_U16, |
48 | 2d496105 | Michael Roth | PTYPE_U32, |
49 | 2d496105 | Michael Roth | PTYPE_U64, |
50 | 2d496105 | Michael Roth | PTYPE_S8, |
51 | 2d496105 | Michael Roth | PTYPE_S16, |
52 | 2d496105 | Michael Roth | PTYPE_S32, |
53 | 2d496105 | Michael Roth | PTYPE_S64, |
54 | 2d496105 | Michael Roth | PTYPE_EOL, |
55 | 2d496105 | Michael Roth | } type; |
56 | 2d496105 | Michael Roth | const char *description; |
57 | 2d496105 | Michael Roth | } PrimitiveType; |
58 | 2d496105 | Michael Roth | |
59 | 2d496105 | Michael Roth | /* test helpers */
|
60 | 2d496105 | Michael Roth | |
61 | 2d496105 | Michael Roth | static void visit_primitive_type(Visitor *v, void **native, Error **errp) |
62 | 2d496105 | Michael Roth | { |
63 | 2d496105 | Michael Roth | PrimitiveType *pt = *native; |
64 | 2d496105 | Michael Roth | switch(pt->type) {
|
65 | 2d496105 | Michael Roth | case PTYPE_STRING:
|
66 | 2d496105 | Michael Roth | visit_type_str(v, (char **)&pt->value.string, NULL, errp); |
67 | 2d496105 | Michael Roth | break;
|
68 | 2d496105 | Michael Roth | case PTYPE_BOOLEAN:
|
69 | 2d496105 | Michael Roth | visit_type_bool(v, &pt->value.boolean, NULL, errp);
|
70 | 2d496105 | Michael Roth | break;
|
71 | 2d496105 | Michael Roth | case PTYPE_NUMBER:
|
72 | 2d496105 | Michael Roth | visit_type_number(v, &pt->value.number, NULL, errp);
|
73 | 2d496105 | Michael Roth | break;
|
74 | 2d496105 | Michael Roth | case PTYPE_INTEGER:
|
75 | 2d496105 | Michael Roth | visit_type_int(v, &pt->value.integer, NULL, errp);
|
76 | 2d496105 | Michael Roth | break;
|
77 | 2d496105 | Michael Roth | case PTYPE_U8:
|
78 | 2d496105 | Michael Roth | visit_type_uint8(v, &pt->value.u8, NULL, errp);
|
79 | 2d496105 | Michael Roth | break;
|
80 | 2d496105 | Michael Roth | case PTYPE_U16:
|
81 | 2d496105 | Michael Roth | visit_type_uint16(v, &pt->value.u16, NULL, errp);
|
82 | 2d496105 | Michael Roth | break;
|
83 | 2d496105 | Michael Roth | case PTYPE_U32:
|
84 | 2d496105 | Michael Roth | visit_type_uint32(v, &pt->value.u32, NULL, errp);
|
85 | 2d496105 | Michael Roth | break;
|
86 | 2d496105 | Michael Roth | case PTYPE_U64:
|
87 | 2d496105 | Michael Roth | visit_type_uint64(v, &pt->value.u64, NULL, errp);
|
88 | 2d496105 | Michael Roth | break;
|
89 | 2d496105 | Michael Roth | case PTYPE_S8:
|
90 | 2d496105 | Michael Roth | visit_type_int8(v, &pt->value.s8, NULL, errp);
|
91 | 2d496105 | Michael Roth | break;
|
92 | 2d496105 | Michael Roth | case PTYPE_S16:
|
93 | 2d496105 | Michael Roth | visit_type_int16(v, &pt->value.s16, NULL, errp);
|
94 | 2d496105 | Michael Roth | break;
|
95 | 2d496105 | Michael Roth | case PTYPE_S32:
|
96 | 2d496105 | Michael Roth | visit_type_int32(v, &pt->value.s32, NULL, errp);
|
97 | 2d496105 | Michael Roth | break;
|
98 | 2d496105 | Michael Roth | case PTYPE_S64:
|
99 | 2d496105 | Michael Roth | visit_type_int64(v, &pt->value.s64, NULL, errp);
|
100 | 2d496105 | Michael Roth | break;
|
101 | 2d496105 | Michael Roth | case PTYPE_EOL:
|
102 | 2d496105 | Michael Roth | g_assert(false);
|
103 | 2d496105 | Michael Roth | } |
104 | 2d496105 | Michael Roth | } |
105 | 2d496105 | Michael Roth | |
106 | 2d496105 | Michael Roth | typedef struct TestStruct |
107 | 2d496105 | Michael Roth | { |
108 | 2d496105 | Michael Roth | int64_t integer; |
109 | 2d496105 | Michael Roth | bool boolean;
|
110 | 2d496105 | Michael Roth | char *string;
|
111 | 2d496105 | Michael Roth | } TestStruct; |
112 | 2d496105 | Michael Roth | |
113 | 2d496105 | Michael Roth | static void visit_type_TestStruct(Visitor *v, TestStruct **obj, |
114 | 2d496105 | Michael Roth | const char *name, Error **errp) |
115 | 2d496105 | Michael Roth | { |
116 | 2d496105 | Michael Roth | visit_start_struct(v, (void **)obj, NULL, name, sizeof(TestStruct), errp); |
117 | 2d496105 | Michael Roth | |
118 | 2d496105 | Michael Roth | visit_type_int(v, &(*obj)->integer, "integer", errp);
|
119 | 2d496105 | Michael Roth | visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
|
120 | 2d496105 | Michael Roth | visit_type_str(v, &(*obj)->string, "string", errp);
|
121 | 2d496105 | Michael Roth | |
122 | 2d496105 | Michael Roth | visit_end_struct(v, errp); |
123 | 2d496105 | Michael Roth | } |
124 | 2d496105 | Michael Roth | |
125 | 2d496105 | Michael Roth | static TestStruct *struct_create(void) |
126 | 2d496105 | Michael Roth | { |
127 | 2d496105 | Michael Roth | TestStruct *ts = g_malloc0(sizeof(*ts));
|
128 | 2d496105 | Michael Roth | ts->integer = -42;
|
129 | 2d496105 | Michael Roth | ts->boolean = true;
|
130 | 2d496105 | Michael Roth | ts->string = strdup("test string");
|
131 | 2d496105 | Michael Roth | return ts;
|
132 | 2d496105 | Michael Roth | } |
133 | 2d496105 | Michael Roth | |
134 | 2d496105 | Michael Roth | static void struct_compare(TestStruct *ts1, TestStruct *ts2) |
135 | 2d496105 | Michael Roth | { |
136 | 2d496105 | Michael Roth | g_assert(ts1); |
137 | 2d496105 | Michael Roth | g_assert(ts2); |
138 | 2d496105 | Michael Roth | g_assert_cmpint(ts1->integer, ==, ts2->integer); |
139 | 2d496105 | Michael Roth | g_assert(ts1->boolean == ts2->boolean); |
140 | 2d496105 | Michael Roth | g_assert_cmpstr(ts1->string, ==, ts2->string); |
141 | 2d496105 | Michael Roth | } |
142 | 2d496105 | Michael Roth | |
143 | 2d496105 | Michael Roth | static void struct_cleanup(TestStruct *ts) |
144 | 2d496105 | Michael Roth | { |
145 | 2d496105 | Michael Roth | g_free(ts->string); |
146 | 2d496105 | Michael Roth | g_free(ts); |
147 | 2d496105 | Michael Roth | } |
148 | 2d496105 | Michael Roth | |
149 | 2d496105 | Michael Roth | static void visit_struct(Visitor *v, void **native, Error **errp) |
150 | 2d496105 | Michael Roth | { |
151 | 2d496105 | Michael Roth | visit_type_TestStruct(v, (TestStruct **)native, NULL, errp);
|
152 | 2d496105 | Michael Roth | } |
153 | 2d496105 | Michael Roth | |
154 | 2d496105 | Michael Roth | static UserDefNested *nested_struct_create(void) |
155 | 2d496105 | Michael Roth | { |
156 | 2d496105 | Michael Roth | UserDefNested *udnp = g_malloc0(sizeof(*udnp));
|
157 | 2d496105 | Michael Roth | udnp->string0 = strdup("test_string0");
|
158 | 2d496105 | Michael Roth | udnp->dict1.string1 = strdup("test_string1");
|
159 | 2d496105 | Michael Roth | udnp->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
|
160 | 2d496105 | Michael Roth | udnp->dict1.dict2.userdef1->integer = 42;
|
161 | 2d496105 | Michael Roth | udnp->dict1.dict2.userdef1->string = strdup("test_string");
|
162 | 2d496105 | Michael Roth | udnp->dict1.dict2.string2 = strdup("test_string2");
|
163 | 2d496105 | Michael Roth | udnp->dict1.has_dict3 = true;
|
164 | 2d496105 | Michael Roth | udnp->dict1.dict3.userdef2 = g_malloc0(sizeof(UserDefOne));
|
165 | 2d496105 | Michael Roth | udnp->dict1.dict3.userdef2->integer = 43;
|
166 | 2d496105 | Michael Roth | udnp->dict1.dict3.userdef2->string = strdup("test_string");
|
167 | 2d496105 | Michael Roth | udnp->dict1.dict3.string3 = strdup("test_string3");
|
168 | 2d496105 | Michael Roth | return udnp;
|
169 | 2d496105 | Michael Roth | } |
170 | 2d496105 | Michael Roth | |
171 | 2d496105 | Michael Roth | static void nested_struct_compare(UserDefNested *udnp1, UserDefNested *udnp2) |
172 | 2d496105 | Michael Roth | { |
173 | 2d496105 | Michael Roth | g_assert(udnp1); |
174 | 2d496105 | Michael Roth | g_assert(udnp2); |
175 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->string0, ==, udnp2->string0); |
176 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.string1, ==, udnp2->dict1.string1); |
177 | 2d496105 | Michael Roth | g_assert_cmpint(udnp1->dict1.dict2.userdef1->integer, ==, |
178 | 2d496105 | Michael Roth | udnp2->dict1.dict2.userdef1->integer); |
179 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict2.userdef1->string, ==, |
180 | 2d496105 | Michael Roth | udnp2->dict1.dict2.userdef1->string); |
181 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict2.string2, ==, udnp2->dict1.dict2.string2); |
182 | 2d496105 | Michael Roth | g_assert(udnp1->dict1.has_dict3 == udnp2->dict1.has_dict3); |
183 | 2d496105 | Michael Roth | g_assert_cmpint(udnp1->dict1.dict3.userdef2->integer, ==, |
184 | 2d496105 | Michael Roth | udnp2->dict1.dict3.userdef2->integer); |
185 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict3.userdef2->string, ==, |
186 | 2d496105 | Michael Roth | udnp2->dict1.dict3.userdef2->string); |
187 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict3.string3, ==, udnp2->dict1.dict3.string3); |
188 | 2d496105 | Michael Roth | } |
189 | 2d496105 | Michael Roth | |
190 | 2d496105 | Michael Roth | static void nested_struct_cleanup(UserDefNested *udnp) |
191 | 2d496105 | Michael Roth | { |
192 | 2d496105 | Michael Roth | qapi_free_UserDefNested(udnp); |
193 | 2d496105 | Michael Roth | } |
194 | 2d496105 | Michael Roth | |
195 | 2d496105 | Michael Roth | static void visit_nested_struct(Visitor *v, void **native, Error **errp) |
196 | 2d496105 | Michael Roth | { |
197 | 2d496105 | Michael Roth | visit_type_UserDefNested(v, (UserDefNested **)native, NULL, errp);
|
198 | 2d496105 | Michael Roth | } |
199 | 2d496105 | Michael Roth | |
200 | 2d496105 | Michael Roth | static void visit_nested_struct_list(Visitor *v, void **native, Error **errp) |
201 | 2d496105 | Michael Roth | { |
202 | 2d496105 | Michael Roth | visit_type_UserDefNestedList(v, (UserDefNestedList **)native, NULL, errp);
|
203 | 2d496105 | Michael Roth | } |
204 | 2d496105 | Michael Roth | |
205 | 2d496105 | Michael Roth | /* test cases */
|
206 | 2d496105 | Michael Roth | |
207 | 2d496105 | Michael Roth | typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp); |
208 | 2d496105 | Michael Roth | |
209 | 2d496105 | Michael Roth | typedef enum VisitorCapabilities { |
210 | 2d496105 | Michael Roth | VCAP_PRIMITIVES = 1,
|
211 | 2d496105 | Michael Roth | VCAP_STRUCTURES = 2,
|
212 | 2d496105 | Michael Roth | VCAP_LISTS = 4,
|
213 | 2d496105 | Michael Roth | } VisitorCapabilities; |
214 | 2d496105 | Michael Roth | |
215 | 2d496105 | Michael Roth | typedef struct SerializeOps { |
216 | 2d496105 | Michael Roth | void (*serialize)(void *native_in, void **datap, |
217 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp); |
218 | 2d496105 | Michael Roth | void (*deserialize)(void **native_out, void *datap, |
219 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp); |
220 | 2d496105 | Michael Roth | void (*cleanup)(void *datap); |
221 | 2d496105 | Michael Roth | const char *type; |
222 | 2d496105 | Michael Roth | VisitorCapabilities caps; |
223 | 2d496105 | Michael Roth | } SerializeOps; |
224 | 2d496105 | Michael Roth | |
225 | 2d496105 | Michael Roth | typedef struct TestArgs { |
226 | 2d496105 | Michael Roth | const SerializeOps *ops;
|
227 | 2d496105 | Michael Roth | void *test_data;
|
228 | 2d496105 | Michael Roth | } TestArgs; |
229 | 2d496105 | Michael Roth | |
230 | 2d496105 | Michael Roth | #define FLOAT_STRING_PRECISION 6 /* corresponding to n in %.nf formatting */ |
231 | 2d496105 | Michael Roth | static gsize calc_float_string_storage(double value) |
232 | 2d496105 | Michael Roth | { |
233 | 2d496105 | Michael Roth | int whole_value = value;
|
234 | 2d496105 | Michael Roth | gsize i = 0;
|
235 | 2d496105 | Michael Roth | do {
|
236 | 2d496105 | Michael Roth | i++; |
237 | 2d496105 | Michael Roth | } while (whole_value /= 10); |
238 | 2d496105 | Michael Roth | return i + 2 + FLOAT_STRING_PRECISION; |
239 | 2d496105 | Michael Roth | } |
240 | 2d496105 | Michael Roth | |
241 | 2d496105 | Michael Roth | static void test_primitives(gconstpointer opaque) |
242 | 2d496105 | Michael Roth | { |
243 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
244 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
245 | 2d496105 | Michael Roth | PrimitiveType *pt = args->test_data; |
246 | 2d496105 | Michael Roth | PrimitiveType *pt_copy = g_malloc0(sizeof(*pt_copy));
|
247 | 2d496105 | Michael Roth | Error *err = NULL;
|
248 | 2d496105 | Michael Roth | void *serialize_data;
|
249 | 2d496105 | Michael Roth | char *double1, *double2;
|
250 | 2d496105 | Michael Roth | |
251 | 2d496105 | Michael Roth | pt_copy->type = pt->type; |
252 | 2d496105 | Michael Roth | ops->serialize(pt, &serialize_data, visit_primitive_type, &err); |
253 | 2d496105 | Michael Roth | ops->deserialize((void **)&pt_copy, serialize_data, visit_primitive_type, &err);
|
254 | 2d496105 | Michael Roth | |
255 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
256 | 2d496105 | Michael Roth | g_assert(pt_copy != NULL);
|
257 | 2d496105 | Michael Roth | if (pt->type == PTYPE_STRING) {
|
258 | 2d496105 | Michael Roth | g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string); |
259 | 2d496105 | Michael Roth | } else if (pt->type == PTYPE_NUMBER) { |
260 | 2d496105 | Michael Roth | /* we serialize with %f for our reference visitors, so rather than fuzzy
|
261 | 2d496105 | Michael Roth | * floating math to test "equality", just compare the formatted values
|
262 | 2d496105 | Michael Roth | */
|
263 | 2d496105 | Michael Roth | double1 = g_malloc0(calc_float_string_storage(pt->value.number)); |
264 | 2d496105 | Michael Roth | double2 = g_malloc0(calc_float_string_storage(pt_copy->value.number)); |
265 | 2d496105 | Michael Roth | g_assert_cmpstr(double1, ==, double2); |
266 | 2d496105 | Michael Roth | g_free(double1); |
267 | 2d496105 | Michael Roth | g_free(double2); |
268 | 2d496105 | Michael Roth | } else if (pt->type == PTYPE_BOOLEAN) { |
269 | 2d496105 | Michael Roth | g_assert_cmpint(!!pt->value.max, ==, !!pt->value.max); |
270 | 2d496105 | Michael Roth | } else {
|
271 | 2d496105 | Michael Roth | g_assert_cmpint(pt->value.max, ==, pt_copy->value.max); |
272 | 2d496105 | Michael Roth | } |
273 | 2d496105 | Michael Roth | |
274 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
275 | 2d496105 | Michael Roth | g_free(args); |
276 | 2d496105 | Michael Roth | } |
277 | 2d496105 | Michael Roth | |
278 | 2d496105 | Michael Roth | static void test_struct(gconstpointer opaque) |
279 | 2d496105 | Michael Roth | { |
280 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
281 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
282 | 2d496105 | Michael Roth | TestStruct *ts = struct_create(); |
283 | 2d496105 | Michael Roth | TestStruct *ts_copy = NULL;
|
284 | 2d496105 | Michael Roth | Error *err = NULL;
|
285 | 2d496105 | Michael Roth | void *serialize_data;
|
286 | 2d496105 | Michael Roth | |
287 | 2d496105 | Michael Roth | ops->serialize(ts, &serialize_data, visit_struct, &err); |
288 | 2d496105 | Michael Roth | ops->deserialize((void **)&ts_copy, serialize_data, visit_struct, &err);
|
289 | 2d496105 | Michael Roth | |
290 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
291 | 2d496105 | Michael Roth | struct_compare(ts, ts_copy); |
292 | 2d496105 | Michael Roth | |
293 | 2d496105 | Michael Roth | struct_cleanup(ts); |
294 | 2d496105 | Michael Roth | struct_cleanup(ts_copy); |
295 | 2d496105 | Michael Roth | |
296 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
297 | 2d496105 | Michael Roth | g_free(args); |
298 | 2d496105 | Michael Roth | } |
299 | 2d496105 | Michael Roth | |
300 | 2d496105 | Michael Roth | static void test_nested_struct(gconstpointer opaque) |
301 | 2d496105 | Michael Roth | { |
302 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
303 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
304 | 2d496105 | Michael Roth | UserDefNested *udnp = nested_struct_create(); |
305 | 2d496105 | Michael Roth | UserDefNested *udnp_copy = NULL;
|
306 | 2d496105 | Michael Roth | Error *err = NULL;
|
307 | 2d496105 | Michael Roth | void *serialize_data;
|
308 | 2d496105 | Michael Roth | |
309 | 2d496105 | Michael Roth | ops->serialize(udnp, &serialize_data, visit_nested_struct, &err); |
310 | 2d496105 | Michael Roth | ops->deserialize((void **)&udnp_copy, serialize_data, visit_nested_struct, &err);
|
311 | 2d496105 | Michael Roth | |
312 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
313 | 2d496105 | Michael Roth | nested_struct_compare(udnp, udnp_copy); |
314 | 2d496105 | Michael Roth | |
315 | 2d496105 | Michael Roth | nested_struct_cleanup(udnp); |
316 | 2d496105 | Michael Roth | nested_struct_cleanup(udnp_copy); |
317 | 2d496105 | Michael Roth | |
318 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
319 | 2d496105 | Michael Roth | g_free(args); |
320 | 2d496105 | Michael Roth | } |
321 | 2d496105 | Michael Roth | |
322 | 2d496105 | Michael Roth | static void test_nested_struct_list(gconstpointer opaque) |
323 | 2d496105 | Michael Roth | { |
324 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
325 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
326 | 2d496105 | Michael Roth | UserDefNestedList *listp = NULL, *tmp, *tmp_copy, *listp_copy = NULL; |
327 | 2d496105 | Michael Roth | Error *err = NULL;
|
328 | 2d496105 | Michael Roth | void *serialize_data;
|
329 | 2d496105 | Michael Roth | int i = 0; |
330 | 2d496105 | Michael Roth | |
331 | 2d496105 | Michael Roth | for (i = 0; i < 8; i++) { |
332 | 2d496105 | Michael Roth | tmp = g_malloc0(sizeof(UserDefNestedList));
|
333 | 2d496105 | Michael Roth | tmp->value = nested_struct_create(); |
334 | 2d496105 | Michael Roth | tmp->next = listp; |
335 | 2d496105 | Michael Roth | listp = tmp; |
336 | 2d496105 | Michael Roth | } |
337 | 2d496105 | Michael Roth | |
338 | 2d496105 | Michael Roth | ops->serialize(listp, &serialize_data, visit_nested_struct_list, &err); |
339 | 2d496105 | Michael Roth | ops->deserialize((void **)&listp_copy, serialize_data,
|
340 | 2d496105 | Michael Roth | visit_nested_struct_list, &err); |
341 | 2d496105 | Michael Roth | |
342 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
343 | 2d496105 | Michael Roth | |
344 | 2d496105 | Michael Roth | tmp = listp; |
345 | 2d496105 | Michael Roth | tmp_copy = listp_copy; |
346 | 2d496105 | Michael Roth | while (listp_copy) {
|
347 | 2d496105 | Michael Roth | g_assert(listp); |
348 | 2d496105 | Michael Roth | nested_struct_compare(listp->value, listp_copy->value); |
349 | 2d496105 | Michael Roth | listp = listp->next; |
350 | 2d496105 | Michael Roth | listp_copy = listp_copy->next; |
351 | 2d496105 | Michael Roth | } |
352 | 2d496105 | Michael Roth | |
353 | 2d496105 | Michael Roth | qapi_free_UserDefNestedList(tmp); |
354 | 2d496105 | Michael Roth | qapi_free_UserDefNestedList(tmp_copy); |
355 | 2d496105 | Michael Roth | |
356 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
357 | 2d496105 | Michael Roth | g_free(args); |
358 | 2d496105 | Michael Roth | } |
359 | 2d496105 | Michael Roth | |
360 | 2d496105 | Michael Roth | PrimitiveType pt_values[] = { |
361 | 2d496105 | Michael Roth | /* string tests */
|
362 | 2d496105 | Michael Roth | { |
363 | 2d496105 | Michael Roth | .description = "string_empty",
|
364 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
365 | 2d496105 | Michael Roth | .value.string = "",
|
366 | 2d496105 | Michael Roth | }, |
367 | 2d496105 | Michael Roth | { |
368 | 2d496105 | Michael Roth | .description = "string_whitespace",
|
369 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
370 | 2d496105 | Michael Roth | .value.string = "a b c\td",
|
371 | 2d496105 | Michael Roth | }, |
372 | 2d496105 | Michael Roth | { |
373 | 2d496105 | Michael Roth | .description = "string_newlines",
|
374 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
375 | 2d496105 | Michael Roth | .value.string = "a\nb\n",
|
376 | 2d496105 | Michael Roth | }, |
377 | 2d496105 | Michael Roth | { |
378 | 2d496105 | Michael Roth | .description = "string_commas",
|
379 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
380 | 2d496105 | Michael Roth | .value.string = "a,b, c,d",
|
381 | 2d496105 | Michael Roth | }, |
382 | 2d496105 | Michael Roth | { |
383 | 2d496105 | Michael Roth | .description = "string_single_quoted",
|
384 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
385 | 2d496105 | Michael Roth | .value.string = "'a b',cd",
|
386 | 2d496105 | Michael Roth | }, |
387 | 2d496105 | Michael Roth | { |
388 | 2d496105 | Michael Roth | .description = "string_double_quoted",
|
389 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
390 | 2d496105 | Michael Roth | .value.string = "\"a b\",cd",
|
391 | 2d496105 | Michael Roth | }, |
392 | 2d496105 | Michael Roth | /* boolean tests */
|
393 | 2d496105 | Michael Roth | { |
394 | 2d496105 | Michael Roth | .description = "boolean_true1",
|
395 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
396 | 2d496105 | Michael Roth | .value.boolean = true,
|
397 | 2d496105 | Michael Roth | }, |
398 | 2d496105 | Michael Roth | { |
399 | 2d496105 | Michael Roth | .description = "boolean_true2",
|
400 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
401 | 2d496105 | Michael Roth | .value.boolean = 8,
|
402 | 2d496105 | Michael Roth | }, |
403 | 2d496105 | Michael Roth | { |
404 | 2d496105 | Michael Roth | .description = "boolean_true3",
|
405 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
406 | 2d496105 | Michael Roth | .value.boolean = -1,
|
407 | 2d496105 | Michael Roth | }, |
408 | 2d496105 | Michael Roth | { |
409 | 2d496105 | Michael Roth | .description = "boolean_false1",
|
410 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
411 | 2d496105 | Michael Roth | .value.boolean = false,
|
412 | 2d496105 | Michael Roth | }, |
413 | 2d496105 | Michael Roth | { |
414 | 2d496105 | Michael Roth | .description = "boolean_false2",
|
415 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
416 | 2d496105 | Michael Roth | .value.boolean = 0,
|
417 | 2d496105 | Michael Roth | }, |
418 | 2d496105 | Michael Roth | /* number tests (double) */
|
419 | 2d496105 | Michael Roth | /* note: we format these to %.6f before comparing, since that's how
|
420 | 2d496105 | Michael Roth | * we serialize them and it doesn't make sense to check precision
|
421 | 2d496105 | Michael Roth | * beyond that.
|
422 | 2d496105 | Michael Roth | */
|
423 | 2d496105 | Michael Roth | { |
424 | 2d496105 | Michael Roth | .description = "number_sanity1",
|
425 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
426 | 2d496105 | Michael Roth | .value.number = -1,
|
427 | 2d496105 | Michael Roth | }, |
428 | 2d496105 | Michael Roth | { |
429 | 2d496105 | Michael Roth | .description = "number_sanity2",
|
430 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
431 | 2d496105 | Michael Roth | .value.number = 3.14159265, |
432 | 2d496105 | Michael Roth | }, |
433 | 2d496105 | Michael Roth | { |
434 | 2d496105 | Michael Roth | .description = "number_min",
|
435 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
436 | 2d496105 | Michael Roth | .value.number = DBL_MIN, |
437 | 2d496105 | Michael Roth | }, |
438 | 2d496105 | Michael Roth | { |
439 | 2d496105 | Michael Roth | .description = "number_max",
|
440 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
441 | 2d496105 | Michael Roth | .value.number = DBL_MAX, |
442 | 2d496105 | Michael Roth | }, |
443 | 2d496105 | Michael Roth | /* integer tests (int64) */
|
444 | 2d496105 | Michael Roth | { |
445 | 2d496105 | Michael Roth | .description = "integer_sanity1",
|
446 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
447 | 2d496105 | Michael Roth | .value.integer = -1,
|
448 | 2d496105 | Michael Roth | }, |
449 | 2d496105 | Michael Roth | { |
450 | 2d496105 | Michael Roth | .description = "integer_sanity2",
|
451 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
452 | 2d496105 | Michael Roth | .value.integer = INT64_MAX / 2 + 1, |
453 | 2d496105 | Michael Roth | }, |
454 | 2d496105 | Michael Roth | { |
455 | 2d496105 | Michael Roth | .description = "integer_min",
|
456 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
457 | 2d496105 | Michael Roth | .value.integer = INT64_MIN, |
458 | 2d496105 | Michael Roth | }, |
459 | 2d496105 | Michael Roth | { |
460 | 2d496105 | Michael Roth | .description = "integer_max",
|
461 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
462 | 2d496105 | Michael Roth | .value.integer = INT64_MAX, |
463 | 2d496105 | Michael Roth | }, |
464 | 2d496105 | Michael Roth | /* uint8 tests */
|
465 | 2d496105 | Michael Roth | { |
466 | 2d496105 | Michael Roth | .description = "uint8_sanity1",
|
467 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
468 | 2d496105 | Michael Roth | .value.u8 = 1,
|
469 | 2d496105 | Michael Roth | }, |
470 | 2d496105 | Michael Roth | { |
471 | 2d496105 | Michael Roth | .description = "uint8_sanity2",
|
472 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
473 | 2d496105 | Michael Roth | .value.u8 = UINT8_MAX / 2 + 1, |
474 | 2d496105 | Michael Roth | }, |
475 | 2d496105 | Michael Roth | { |
476 | 2d496105 | Michael Roth | .description = "uint8_min",
|
477 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
478 | 2d496105 | Michael Roth | .value.u8 = 0,
|
479 | 2d496105 | Michael Roth | }, |
480 | 2d496105 | Michael Roth | { |
481 | 2d496105 | Michael Roth | .description = "uint8_max",
|
482 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
483 | 2d496105 | Michael Roth | .value.u8 = UINT8_MAX, |
484 | 2d496105 | Michael Roth | }, |
485 | 2d496105 | Michael Roth | /* uint16 tests */
|
486 | 2d496105 | Michael Roth | { |
487 | 2d496105 | Michael Roth | .description = "uint16_sanity1",
|
488 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
489 | 2d496105 | Michael Roth | .value.u16 = 1,
|
490 | 2d496105 | Michael Roth | }, |
491 | 2d496105 | Michael Roth | { |
492 | 2d496105 | Michael Roth | .description = "uint16_sanity2",
|
493 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
494 | 2d496105 | Michael Roth | .value.u16 = UINT16_MAX / 2 + 1, |
495 | 2d496105 | Michael Roth | }, |
496 | 2d496105 | Michael Roth | { |
497 | 2d496105 | Michael Roth | .description = "uint16_min",
|
498 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
499 | 2d496105 | Michael Roth | .value.u16 = 0,
|
500 | 2d496105 | Michael Roth | }, |
501 | 2d496105 | Michael Roth | { |
502 | 2d496105 | Michael Roth | .description = "uint16_max",
|
503 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
504 | 2d496105 | Michael Roth | .value.u16 = UINT16_MAX, |
505 | 2d496105 | Michael Roth | }, |
506 | 2d496105 | Michael Roth | /* uint32 tests */
|
507 | 2d496105 | Michael Roth | { |
508 | 2d496105 | Michael Roth | .description = "uint32_sanity1",
|
509 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
510 | 2d496105 | Michael Roth | .value.u32 = 1,
|
511 | 2d496105 | Michael Roth | }, |
512 | 2d496105 | Michael Roth | { |
513 | 2d496105 | Michael Roth | .description = "uint32_sanity2",
|
514 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
515 | 2d496105 | Michael Roth | .value.u32 = UINT32_MAX / 2 + 1, |
516 | 2d496105 | Michael Roth | }, |
517 | 2d496105 | Michael Roth | { |
518 | 2d496105 | Michael Roth | .description = "uint32_min",
|
519 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
520 | 2d496105 | Michael Roth | .value.u32 = 0,
|
521 | 2d496105 | Michael Roth | }, |
522 | 2d496105 | Michael Roth | { |
523 | 2d496105 | Michael Roth | .description = "uint32_max",
|
524 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
525 | 2d496105 | Michael Roth | .value.u32 = UINT32_MAX, |
526 | 2d496105 | Michael Roth | }, |
527 | 2d496105 | Michael Roth | /* uint64 tests */
|
528 | 2d496105 | Michael Roth | { |
529 | 2d496105 | Michael Roth | .description = "uint64_sanity1",
|
530 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
531 | 2d496105 | Michael Roth | .value.u64 = 1,
|
532 | 2d496105 | Michael Roth | }, |
533 | 2d496105 | Michael Roth | { |
534 | 2d496105 | Michael Roth | .description = "uint64_sanity2",
|
535 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
536 | 2d496105 | Michael Roth | .value.u64 = UINT64_MAX / 2 + 1, |
537 | 2d496105 | Michael Roth | }, |
538 | 2d496105 | Michael Roth | { |
539 | 2d496105 | Michael Roth | .description = "uint64_min",
|
540 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
541 | 2d496105 | Michael Roth | .value.u64 = 0,
|
542 | 2d496105 | Michael Roth | }, |
543 | 2d496105 | Michael Roth | { |
544 | 2d496105 | Michael Roth | .description = "uint64_max",
|
545 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
546 | 2d496105 | Michael Roth | .value.u64 = UINT64_MAX, |
547 | 2d496105 | Michael Roth | }, |
548 | 2d496105 | Michael Roth | /* int8 tests */
|
549 | 2d496105 | Michael Roth | { |
550 | 2d496105 | Michael Roth | .description = "int8_sanity1",
|
551 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
552 | 2d496105 | Michael Roth | .value.s8 = -1,
|
553 | 2d496105 | Michael Roth | }, |
554 | 2d496105 | Michael Roth | { |
555 | 2d496105 | Michael Roth | .description = "int8_sanity2",
|
556 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
557 | 2d496105 | Michael Roth | .value.s8 = INT8_MAX / 2 + 1, |
558 | 2d496105 | Michael Roth | }, |
559 | 2d496105 | Michael Roth | { |
560 | 2d496105 | Michael Roth | .description = "int8_min",
|
561 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
562 | 2d496105 | Michael Roth | .value.s8 = INT8_MIN, |
563 | 2d496105 | Michael Roth | }, |
564 | 2d496105 | Michael Roth | { |
565 | 2d496105 | Michael Roth | .description = "int8_max",
|
566 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
567 | 2d496105 | Michael Roth | .value.s8 = INT8_MAX, |
568 | 2d496105 | Michael Roth | }, |
569 | 2d496105 | Michael Roth | /* int16 tests */
|
570 | 2d496105 | Michael Roth | { |
571 | 2d496105 | Michael Roth | .description = "int16_sanity1",
|
572 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
573 | 2d496105 | Michael Roth | .value.s16 = -1,
|
574 | 2d496105 | Michael Roth | }, |
575 | 2d496105 | Michael Roth | { |
576 | 2d496105 | Michael Roth | .description = "int16_sanity2",
|
577 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
578 | 2d496105 | Michael Roth | .value.s16 = INT16_MAX / 2 + 1, |
579 | 2d496105 | Michael Roth | }, |
580 | 2d496105 | Michael Roth | { |
581 | 2d496105 | Michael Roth | .description = "int16_min",
|
582 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
583 | 2d496105 | Michael Roth | .value.s16 = INT16_MIN, |
584 | 2d496105 | Michael Roth | }, |
585 | 2d496105 | Michael Roth | { |
586 | 2d496105 | Michael Roth | .description = "int16_max",
|
587 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
588 | 2d496105 | Michael Roth | .value.s16 = INT16_MAX, |
589 | 2d496105 | Michael Roth | }, |
590 | 2d496105 | Michael Roth | /* int32 tests */
|
591 | 2d496105 | Michael Roth | { |
592 | 2d496105 | Michael Roth | .description = "int32_sanity1",
|
593 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
594 | 2d496105 | Michael Roth | .value.s32 = -1,
|
595 | 2d496105 | Michael Roth | }, |
596 | 2d496105 | Michael Roth | { |
597 | 2d496105 | Michael Roth | .description = "int32_sanity2",
|
598 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
599 | 2d496105 | Michael Roth | .value.s32 = INT32_MAX / 2 + 1, |
600 | 2d496105 | Michael Roth | }, |
601 | 2d496105 | Michael Roth | { |
602 | 2d496105 | Michael Roth | .description = "int32_min",
|
603 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
604 | 2d496105 | Michael Roth | .value.s32 = INT32_MIN, |
605 | 2d496105 | Michael Roth | }, |
606 | 2d496105 | Michael Roth | { |
607 | 2d496105 | Michael Roth | .description = "int32_max",
|
608 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
609 | 2d496105 | Michael Roth | .value.s32 = INT32_MAX, |
610 | 2d496105 | Michael Roth | }, |
611 | 2d496105 | Michael Roth | /* int64 tests */
|
612 | 2d496105 | Michael Roth | { |
613 | 2d496105 | Michael Roth | .description = "int64_sanity1",
|
614 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
615 | 2d496105 | Michael Roth | .value.s64 = -1,
|
616 | 2d496105 | Michael Roth | }, |
617 | 2d496105 | Michael Roth | { |
618 | 2d496105 | Michael Roth | .description = "int64_sanity2",
|
619 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
620 | 2d496105 | Michael Roth | .value.s64 = INT64_MAX / 2 + 1, |
621 | 2d496105 | Michael Roth | }, |
622 | 2d496105 | Michael Roth | { |
623 | 2d496105 | Michael Roth | .description = "int64_min",
|
624 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
625 | 2d496105 | Michael Roth | .value.s64 = INT64_MIN, |
626 | 2d496105 | Michael Roth | }, |
627 | 2d496105 | Michael Roth | { |
628 | 2d496105 | Michael Roth | .description = "int64_max",
|
629 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
630 | 2d496105 | Michael Roth | .value.s64 = INT64_MAX, |
631 | 2d496105 | Michael Roth | }, |
632 | 2d496105 | Michael Roth | { .type = PTYPE_EOL } |
633 | 2d496105 | Michael Roth | }; |
634 | 2d496105 | Michael Roth | |
635 | 2d496105 | Michael Roth | /* visitor-specific op implementations */
|
636 | 2d496105 | Michael Roth | |
637 | 2d496105 | Michael Roth | typedef struct QmpSerializeData { |
638 | 2d496105 | Michael Roth | QmpOutputVisitor *qov; |
639 | 2d496105 | Michael Roth | QmpInputVisitor *qiv; |
640 | 2d496105 | Michael Roth | } QmpSerializeData; |
641 | 2d496105 | Michael Roth | |
642 | 2d496105 | Michael Roth | static void qmp_serialize(void *native_in, void **datap, |
643 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp) |
644 | 2d496105 | Michael Roth | { |
645 | 2d496105 | Michael Roth | QmpSerializeData *d = g_malloc0(sizeof(*d));
|
646 | 2d496105 | Michael Roth | |
647 | 2d496105 | Michael Roth | d->qov = qmp_output_visitor_new(); |
648 | 2d496105 | Michael Roth | visit(qmp_output_get_visitor(d->qov), &native_in, errp); |
649 | 2d496105 | Michael Roth | *datap = d; |
650 | 2d496105 | Michael Roth | } |
651 | 2d496105 | Michael Roth | |
652 | 2d496105 | Michael Roth | static void qmp_deserialize(void **native_out, void *datap, |
653 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp) |
654 | 2d496105 | Michael Roth | { |
655 | 2d496105 | Michael Roth | QmpSerializeData *d = datap; |
656 | 2d496105 | Michael Roth | QString *output_json = qobject_to_json(qmp_output_get_qobject(d->qov)); |
657 | 2d496105 | Michael Roth | QObject *obj = qobject_from_json(qstring_get_str(output_json)); |
658 | 2d496105 | Michael Roth | |
659 | 2d496105 | Michael Roth | QDECREF(output_json); |
660 | 2d496105 | Michael Roth | d->qiv = qmp_input_visitor_new(obj); |
661 | 2d496105 | Michael Roth | visit(qmp_input_get_visitor(d->qiv), native_out, errp); |
662 | 2d496105 | Michael Roth | } |
663 | 2d496105 | Michael Roth | |
664 | 2d496105 | Michael Roth | static void qmp_cleanup(void *datap) |
665 | 2d496105 | Michael Roth | { |
666 | 2d496105 | Michael Roth | QmpSerializeData *d = datap; |
667 | 2d496105 | Michael Roth | qmp_output_visitor_cleanup(d->qov); |
668 | 2d496105 | Michael Roth | qmp_input_visitor_cleanup(d->qiv); |
669 | 2d496105 | Michael Roth | } |
670 | 2d496105 | Michael Roth | |
671 | 0d30b0a2 | Michael Roth | typedef struct StringSerializeData { |
672 | 0d30b0a2 | Michael Roth | StringOutputVisitor *sov; |
673 | 0d30b0a2 | Michael Roth | StringInputVisitor *siv; |
674 | 0d30b0a2 | Michael Roth | } StringSerializeData; |
675 | 0d30b0a2 | Michael Roth | |
676 | 0d30b0a2 | Michael Roth | static void string_serialize(void *native_in, void **datap, |
677 | 0d30b0a2 | Michael Roth | VisitorFunc visit, Error **errp) |
678 | 0d30b0a2 | Michael Roth | { |
679 | 0d30b0a2 | Michael Roth | StringSerializeData *d = g_malloc0(sizeof(*d));
|
680 | 0d30b0a2 | Michael Roth | |
681 | 0d30b0a2 | Michael Roth | d->sov = string_output_visitor_new(); |
682 | 0d30b0a2 | Michael Roth | visit(string_output_get_visitor(d->sov), &native_in, errp); |
683 | 0d30b0a2 | Michael Roth | *datap = d; |
684 | 0d30b0a2 | Michael Roth | } |
685 | 0d30b0a2 | Michael Roth | |
686 | 0d30b0a2 | Michael Roth | static void string_deserialize(void **native_out, void *datap, |
687 | 0d30b0a2 | Michael Roth | VisitorFunc visit, Error **errp) |
688 | 0d30b0a2 | Michael Roth | { |
689 | 0d30b0a2 | Michael Roth | StringSerializeData *d = datap; |
690 | 0d30b0a2 | Michael Roth | |
691 | 0d30b0a2 | Michael Roth | d->siv = string_input_visitor_new(string_output_get_string(d->sov)); |
692 | 0d30b0a2 | Michael Roth | visit(string_input_get_visitor(d->siv), native_out, errp); |
693 | 0d30b0a2 | Michael Roth | } |
694 | 0d30b0a2 | Michael Roth | |
695 | 0d30b0a2 | Michael Roth | static void string_cleanup(void *datap) |
696 | 0d30b0a2 | Michael Roth | { |
697 | 0d30b0a2 | Michael Roth | StringSerializeData *d = datap; |
698 | 0d30b0a2 | Michael Roth | string_output_visitor_cleanup(d->sov); |
699 | 0d30b0a2 | Michael Roth | string_input_visitor_cleanup(d->siv); |
700 | 0d30b0a2 | Michael Roth | } |
701 | 0d30b0a2 | Michael Roth | |
702 | 2d496105 | Michael Roth | /* visitor registration, test harness */
|
703 | 2d496105 | Michael Roth | |
704 | 2d496105 | Michael Roth | /* note: to function interchangeably as a serialization mechanism your
|
705 | 2d496105 | Michael Roth | * visitor test implementation should pass the test cases for all visitor
|
706 | 2d496105 | Michael Roth | * capabilities: primitives, structures, and lists
|
707 | 2d496105 | Michael Roth | */
|
708 | 2d496105 | Michael Roth | static const SerializeOps visitors[] = { |
709 | 2d496105 | Michael Roth | { |
710 | 2d496105 | Michael Roth | .type = "QMP",
|
711 | 2d496105 | Michael Roth | .serialize = qmp_serialize, |
712 | 2d496105 | Michael Roth | .deserialize = qmp_deserialize, |
713 | 2d496105 | Michael Roth | .cleanup = qmp_cleanup, |
714 | 2d496105 | Michael Roth | .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS |
715 | 2d496105 | Michael Roth | }, |
716 | 0d30b0a2 | Michael Roth | { |
717 | 0d30b0a2 | Michael Roth | .type = "String",
|
718 | 0d30b0a2 | Michael Roth | .serialize = string_serialize, |
719 | 0d30b0a2 | Michael Roth | .deserialize = string_deserialize, |
720 | 0d30b0a2 | Michael Roth | .cleanup = string_cleanup, |
721 | 0d30b0a2 | Michael Roth | .caps = VCAP_PRIMITIVES |
722 | 0d30b0a2 | Michael Roth | }, |
723 | 2d496105 | Michael Roth | { NULL }
|
724 | 2d496105 | Michael Roth | }; |
725 | 2d496105 | Michael Roth | |
726 | 2d496105 | Michael Roth | static void add_visitor_type(const SerializeOps *ops) |
727 | 2d496105 | Michael Roth | { |
728 | 2d496105 | Michael Roth | char testname_prefix[128]; |
729 | 2d496105 | Michael Roth | char testname[128]; |
730 | 2d496105 | Michael Roth | TestArgs *args; |
731 | 2d496105 | Michael Roth | int i = 0; |
732 | 2d496105 | Michael Roth | |
733 | 2d496105 | Michael Roth | sprintf(testname_prefix, "/visitor/serialization/%s", ops->type);
|
734 | 2d496105 | Michael Roth | |
735 | 2d496105 | Michael Roth | if (ops->caps & VCAP_PRIMITIVES) {
|
736 | 2d496105 | Michael Roth | while (pt_values[i].type != PTYPE_EOL) {
|
737 | 2d496105 | Michael Roth | sprintf(testname, "%s/primitives/%s", testname_prefix,
|
738 | 2d496105 | Michael Roth | pt_values[i].description); |
739 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
740 | 2d496105 | Michael Roth | args->ops = ops; |
741 | 2d496105 | Michael Roth | args->test_data = &pt_values[i]; |
742 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_primitives); |
743 | 2d496105 | Michael Roth | i++; |
744 | 2d496105 | Michael Roth | } |
745 | 2d496105 | Michael Roth | } |
746 | 2d496105 | Michael Roth | |
747 | 2d496105 | Michael Roth | if (ops->caps & VCAP_STRUCTURES) {
|
748 | 2d496105 | Michael Roth | sprintf(testname, "%s/struct", testname_prefix);
|
749 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
750 | 2d496105 | Michael Roth | args->ops = ops; |
751 | 2d496105 | Michael Roth | args->test_data = NULL;
|
752 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_struct); |
753 | 2d496105 | Michael Roth | |
754 | 2d496105 | Michael Roth | sprintf(testname, "%s/nested_struct", testname_prefix);
|
755 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
756 | 2d496105 | Michael Roth | args->ops = ops; |
757 | 2d496105 | Michael Roth | args->test_data = NULL;
|
758 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_nested_struct); |
759 | 2d496105 | Michael Roth | } |
760 | 2d496105 | Michael Roth | |
761 | 2d496105 | Michael Roth | if (ops->caps & VCAP_LISTS) {
|
762 | 2d496105 | Michael Roth | sprintf(testname, "%s/nested_struct_list", testname_prefix);
|
763 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
764 | 2d496105 | Michael Roth | args->ops = ops; |
765 | 2d496105 | Michael Roth | args->test_data = NULL;
|
766 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_nested_struct_list); |
767 | 2d496105 | Michael Roth | } |
768 | 2d496105 | Michael Roth | } |
769 | 2d496105 | Michael Roth | |
770 | 2d496105 | Michael Roth | int main(int argc, char **argv) |
771 | 2d496105 | Michael Roth | { |
772 | 2d496105 | Michael Roth | int i = 0; |
773 | 2d496105 | Michael Roth | |
774 | 2d496105 | Michael Roth | g_test_init(&argc, &argv, NULL);
|
775 | 2d496105 | Michael Roth | |
776 | 2d496105 | Michael Roth | while (visitors[i].type != NULL) { |
777 | 2d496105 | Michael Roth | add_visitor_type(&visitors[i]); |
778 | 2d496105 | Michael Roth | i++; |
779 | 2d496105 | Michael Roth | } |
780 | 2d496105 | Michael Roth | |
781 | 2d496105 | Michael Roth | g_test_run(); |
782 | 2d496105 | Michael Roth | |
783 | 2d496105 | Michael Roth | return 0; |
784 | 2d496105 | Michael Roth | } |