2 * String Input Visitor unit-tests.
4 * Copyright (C) 2012 Red Hat Inc.
7 * Paolo Bonzini <pbonzini@redhat.com> (based on test-qobject-input-visitor)
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
15 #include "qapi/error.h"
16 #include "qapi/string-input-visitor.h"
17 #include "test-qapi-visit.h"
19 typedef struct TestInputVisitorData
{
21 } TestInputVisitorData
;
23 static void visitor_input_teardown(TestInputVisitorData
*data
,
32 /* This is provided instead of a test setup function so that the JSON
33 string used by the tests are kept in the test functions (and not
36 Visitor
*visitor_input_test_init(TestInputVisitorData
*data
,
39 visitor_input_teardown(data
, NULL
);
41 data
->v
= string_input_visitor_new(string
);
46 static void test_visitor_in_int(TestInputVisitorData
*data
,
49 int64_t res
= 0, value
= -42;
53 v
= visitor_input_test_init(data
, "-42");
55 visit_type_int(v
, NULL
, &res
, &error_abort
);
56 g_assert_cmpint(res
, ==, value
);
58 v
= visitor_input_test_init(data
, "not an int");
60 visit_type_int(v
, NULL
, &res
, &err
);
61 error_free_or_abort(&err
);
63 v
= visitor_input_test_init(data
, "");
65 visit_type_int(v
, NULL
, &res
, &err
);
66 error_free_or_abort(&err
);
69 static void check_ilist(Visitor
*v
, int64_t *expected
, size_t n
)
71 int64List
*res
= NULL
;
75 visit_type_int64List(v
, NULL
, &res
, &error_abort
);
77 for (i
= 0; i
< n
; i
++) {
79 g_assert_cmpint(tail
->value
, ==, expected
[i
]);
84 qapi_free_int64List(res
);
87 static void check_ulist(Visitor
*v
, uint64_t *expected
, size_t n
)
89 uint64List
*res
= NULL
;
93 visit_type_uint64List(v
, NULL
, &res
, &error_abort
);
95 for (i
= 0; i
< n
; i
++) {
97 g_assert_cmpuint(tail
->value
, ==, expected
[i
]);
102 qapi_free_uint64List(res
);
105 static void test_visitor_in_intList(TestInputVisitorData
*data
,
108 int64_t expect1
[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
109 8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
110 int64_t expect2
[] = { 32767, -32768, -32767 };
111 int64_t expect3
[] = { INT64_MIN
, INT64_MAX
};
112 int64_t expect4
[] = { 1 };
113 int64_t expect5
[] = { INT64_MAX
- 2, INT64_MAX
- 1, INT64_MAX
};
115 int64List
*res
= NULL
;
121 v
= visitor_input_test_init(data
, "1,2,0,2-4,20,5-9,1-8");
122 check_ilist(v
, expect1
, ARRAY_SIZE(expect1
));
124 v
= visitor_input_test_init(data
, "32767,-32768--32767");
125 check_ilist(v
, expect2
, ARRAY_SIZE(expect2
));
127 v
= visitor_input_test_init(data
,
128 "-9223372036854775808,9223372036854775807");
129 check_ilist(v
, expect3
, ARRAY_SIZE(expect3
));
131 v
= visitor_input_test_init(data
, "1-1");
132 check_ilist(v
, expect4
, ARRAY_SIZE(expect4
));
134 v
= visitor_input_test_init(data
,
135 "9223372036854775805-9223372036854775807");
136 check_ilist(v
, expect5
, ARRAY_SIZE(expect5
));
138 /* Value too large */
140 v
= visitor_input_test_init(data
, "9223372036854775808");
141 visit_type_int64List(v
, NULL
, &res
, &err
);
142 error_free_or_abort(&err
);
145 /* Value too small */
147 v
= visitor_input_test_init(data
, "-9223372036854775809");
148 visit_type_int64List(v
, NULL
, &res
, &err
);
149 error_free_or_abort(&err
);
152 /* Range not ascending */
154 v
= visitor_input_test_init(data
, "3-1");
155 visit_type_int64List(v
, NULL
, &res
, &err
);
156 error_free_or_abort(&err
);
159 v
= visitor_input_test_init(data
, "9223372036854775807-0");
160 visit_type_int64List(v
, NULL
, &res
, &err
);
161 error_free_or_abort(&err
);
164 /* Range too big (65536 is the limit against DOS attacks) */
166 v
= visitor_input_test_init(data
, "0-65536");
167 visit_type_int64List(v
, NULL
, &res
, &err
);
168 error_free_or_abort(&err
);
173 v
= visitor_input_test_init(data
, "");
174 visit_type_int64List(v
, NULL
, &res
, &error_abort
);
179 v
= visitor_input_test_init(data
, "not an int list");
181 visit_type_int64List(v
, NULL
, &res
, &err
);
182 error_free_or_abort(&err
);
185 /* Unvisited list tail */
187 v
= visitor_input_test_init(data
, "0,2-3");
189 visit_start_list(v
, NULL
, NULL
, 0, &error_abort
);
190 visit_type_int64(v
, NULL
, &val
, &error_abort
);
191 g_assert_cmpint(val
, ==, 0);
192 visit_type_int64(v
, NULL
, &val
, &error_abort
);
193 g_assert_cmpint(val
, ==, 2);
195 visit_check_list(v
, &err
);
196 error_free_or_abort(&err
);
197 visit_end_list(v
, NULL
);
199 /* Visit beyond end of list */
201 v
= visitor_input_test_init(data
, "0");
203 visit_start_list(v
, NULL
, NULL
, 0, &error_abort
);
204 visit_type_int64(v
, NULL
, &val
, &err
);
205 g_assert_cmpint(val
, ==, 0);
206 visit_type_int64(v
, NULL
, &val
, &err
);
207 error_free_or_abort(&err
);
209 visit_check_list(v
, &error_abort
);
210 visit_end_list(v
, NULL
);
213 static void test_visitor_in_uintList(TestInputVisitorData
*data
,
216 uint64_t expect1
[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
217 8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
218 uint64_t expect2
[] = { 32767, -32768, -32767 };
219 uint64_t expect3
[] = { INT64_MIN
, INT64_MAX
};
220 uint64_t expect4
[] = { 1 };
221 uint64_t expect5
[] = { UINT64_MAX
};
222 uint64_t expect6
[] = { UINT64_MAX
- 2, UINT64_MAX
- 1, UINT64_MAX
};
224 uint64List
*res
= NULL
;
230 v
= visitor_input_test_init(data
, "1,2,0,2-4,20,5-9,1-8");
231 check_ulist(v
, expect1
, ARRAY_SIZE(expect1
));
233 v
= visitor_input_test_init(data
, "32767,-32768--32767");
234 check_ulist(v
, expect2
, ARRAY_SIZE(expect2
));
236 v
= visitor_input_test_init(data
,
237 "-9223372036854775808,9223372036854775807");
238 check_ulist(v
, expect3
, ARRAY_SIZE(expect3
));
240 v
= visitor_input_test_init(data
, "1-1");
241 check_ulist(v
, expect4
, ARRAY_SIZE(expect4
));
243 v
= visitor_input_test_init(data
, "18446744073709551615");
244 check_ulist(v
, expect5
, ARRAY_SIZE(expect5
));
246 v
= visitor_input_test_init(data
,
247 "18446744073709551613-18446744073709551615");
248 check_ulist(v
, expect6
, ARRAY_SIZE(expect6
));
250 /* Value too large */
252 v
= visitor_input_test_init(data
, "18446744073709551616");
253 visit_type_uint64List(v
, NULL
, &res
, &err
);
254 error_free_or_abort(&err
);
257 /* Value too small */
259 v
= visitor_input_test_init(data
, "-18446744073709551616");
260 visit_type_uint64List(v
, NULL
, &res
, &err
);
261 error_free_or_abort(&err
);
264 /* Range not ascending */
266 v
= visitor_input_test_init(data
, "3-1");
267 visit_type_uint64List(v
, NULL
, &res
, &err
);
268 error_free_or_abort(&err
);
271 v
= visitor_input_test_init(data
, "18446744073709551615-0");
272 visit_type_uint64List(v
, NULL
, &res
, &err
);
273 error_free_or_abort(&err
);
276 /* Range too big (65536 is the limit against DOS attacks) */
278 v
= visitor_input_test_init(data
, "0-65536");
279 visit_type_uint64List(v
, NULL
, &res
, &err
);
280 error_free_or_abort(&err
);
285 v
= visitor_input_test_init(data
, "");
286 visit_type_uint64List(v
, NULL
, &res
, &error_abort
);
291 v
= visitor_input_test_init(data
, "not an uint list");
293 visit_type_uint64List(v
, NULL
, &res
, &err
);
294 error_free_or_abort(&err
);
297 /* Unvisited list tail */
299 v
= visitor_input_test_init(data
, "0,2-3");
301 visit_start_list(v
, NULL
, NULL
, 0, &error_abort
);
302 visit_type_uint64(v
, NULL
, &val
, &error_abort
);
303 g_assert_cmpuint(val
, ==, 0);
304 visit_type_uint64(v
, NULL
, &val
, &error_abort
);
305 g_assert_cmpuint(val
, ==, 2);
307 visit_check_list(v
, &err
);
308 error_free_or_abort(&err
);
309 visit_end_list(v
, NULL
);
311 /* Visit beyond end of list */
313 v
= visitor_input_test_init(data
, "0");
315 visit_start_list(v
, NULL
, NULL
, 0, &error_abort
);
316 visit_type_uint64(v
, NULL
, &val
, &err
);
317 g_assert_cmpuint(val
, ==, 0);
318 visit_type_uint64(v
, NULL
, &val
, &err
);
319 error_free_or_abort(&err
);
321 visit_check_list(v
, &error_abort
);
322 visit_end_list(v
, NULL
);
325 static void test_visitor_in_bool(TestInputVisitorData
*data
,
331 v
= visitor_input_test_init(data
, "true");
333 visit_type_bool(v
, NULL
, &res
, &error_abort
);
334 g_assert_cmpint(res
, ==, true);
336 v
= visitor_input_test_init(data
, "yes");
338 visit_type_bool(v
, NULL
, &res
, &error_abort
);
339 g_assert_cmpint(res
, ==, true);
341 v
= visitor_input_test_init(data
, "on");
343 visit_type_bool(v
, NULL
, &res
, &error_abort
);
344 g_assert_cmpint(res
, ==, true);
346 v
= visitor_input_test_init(data
, "false");
348 visit_type_bool(v
, NULL
, &res
, &error_abort
);
349 g_assert_cmpint(res
, ==, false);
351 v
= visitor_input_test_init(data
, "no");
353 visit_type_bool(v
, NULL
, &res
, &error_abort
);
354 g_assert_cmpint(res
, ==, false);
356 v
= visitor_input_test_init(data
, "off");
358 visit_type_bool(v
, NULL
, &res
, &error_abort
);
359 g_assert_cmpint(res
, ==, false);
362 static void test_visitor_in_number(TestInputVisitorData
*data
,
365 double res
= 0, value
= 3.14;
369 v
= visitor_input_test_init(data
, "3.14");
371 visit_type_number(v
, NULL
, &res
, &error_abort
);
372 g_assert_cmpfloat(res
, ==, value
);
374 /* NaN and infinity has to be rejected */
376 v
= visitor_input_test_init(data
, "NaN");
378 visit_type_number(v
, NULL
, &res
, &err
);
379 error_free_or_abort(&err
);
381 v
= visitor_input_test_init(data
, "inf");
383 visit_type_number(v
, NULL
, &res
, &err
);
384 error_free_or_abort(&err
);
388 static void test_visitor_in_string(TestInputVisitorData
*data
,
391 char *res
= NULL
, *value
= (char *) "Q E M U";
394 v
= visitor_input_test_init(data
, value
);
396 visit_type_str(v
, NULL
, &res
, &error_abort
);
397 g_assert_cmpstr(res
, ==, value
);
402 static void test_visitor_in_enum(TestInputVisitorData
*data
,
408 for (i
= 0; i
< ENUM_ONE__MAX
; i
++) {
411 v
= visitor_input_test_init(data
, EnumOne_str(i
));
413 visit_type_EnumOne(v
, NULL
, &res
, &error_abort
);
414 g_assert_cmpint(i
, ==, res
);
418 /* Try to crash the visitors */
419 static void test_visitor_in_fuzz(TestInputVisitorData
*data
,
432 for (i
= 0; i
< 100; i
++) {
435 j
= g_test_rand_int_range(0, sizeof(buf
) - 1);
439 for (k
= 0; k
!= j
; k
++) {
440 buf
[k
] = (char)g_test_rand_int_range(0, 256);
443 v
= visitor_input_test_init(data
, buf
);
444 visit_type_int(v
, NULL
, &ires
, NULL
);
446 v
= visitor_input_test_init(data
, buf
);
447 visit_type_intList(v
, NULL
, &ilres
, NULL
);
448 qapi_free_intList(ilres
);
450 v
= visitor_input_test_init(data
, buf
);
451 visit_type_bool(v
, NULL
, &bres
, NULL
);
453 v
= visitor_input_test_init(data
, buf
);
454 visit_type_number(v
, NULL
, &nres
, NULL
);
456 v
= visitor_input_test_init(data
, buf
);
458 visit_type_str(v
, NULL
, &sres
, NULL
);
461 v
= visitor_input_test_init(data
, buf
);
462 visit_type_EnumOne(v
, NULL
, &eres
, NULL
);
466 static void input_visitor_test_add(const char *testpath
,
467 TestInputVisitorData
*data
,
468 void (*test_func
)(TestInputVisitorData
*data
, const void *user_data
))
470 g_test_add(testpath
, TestInputVisitorData
, data
, NULL
, test_func
,
471 visitor_input_teardown
);
474 int main(int argc
, char **argv
)
476 TestInputVisitorData in_visitor_data
;
478 g_test_init(&argc
, &argv
, NULL
);
480 input_visitor_test_add("/string-visitor/input/int",
481 &in_visitor_data
, test_visitor_in_int
);
482 input_visitor_test_add("/string-visitor/input/intList",
483 &in_visitor_data
, test_visitor_in_intList
);
484 input_visitor_test_add("/string-visitor/input/uintList",
485 &in_visitor_data
, test_visitor_in_uintList
);
486 input_visitor_test_add("/string-visitor/input/bool",
487 &in_visitor_data
, test_visitor_in_bool
);
488 input_visitor_test_add("/string-visitor/input/number",
489 &in_visitor_data
, test_visitor_in_number
);
490 input_visitor_test_add("/string-visitor/input/string",
491 &in_visitor_data
, test_visitor_in_string
);
492 input_visitor_test_add("/string-visitor/input/enum",
493 &in_visitor_data
, test_visitor_in_enum
);
494 input_visitor_test_add("/string-visitor/input/fuzz",
495 &in_visitor_data
, test_visitor_in_fuzz
);