]> Git Repo - qemu.git/blob - tests/test-string-input-visitor.c
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190426' into staging
[qemu.git] / tests / test-string-input-visitor.c
1 /*
2  * String Input Visitor unit-tests.
3  *
4  * Copyright (C) 2012 Red Hat Inc.
5  *
6  * Authors:
7  *  Paolo Bonzini <[email protected]> (based on test-qobject-input-visitor)
8  *
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.
11  */
12
13 #include "qemu/osdep.h"
14
15 #include "qemu-common.h"
16 #include "qapi/error.h"
17 #include "qapi/string-input-visitor.h"
18 #include "test-qapi-visit.h"
19
20 typedef struct TestInputVisitorData {
21     Visitor *v;
22 } TestInputVisitorData;
23
24 static void visitor_input_teardown(TestInputVisitorData *data,
25                                    const void *unused)
26 {
27     if (data->v) {
28         visit_free(data->v);
29         data->v = NULL;
30     }
31 }
32
33 /* This is provided instead of a test setup function so that the JSON
34    string used by the tests are kept in the test functions (and not
35    int main()) */
36 static
37 Visitor *visitor_input_test_init(TestInputVisitorData *data,
38                                  const char *string)
39 {
40     visitor_input_teardown(data, NULL);
41
42     data->v = string_input_visitor_new(string);
43     g_assert(data->v);
44     return data->v;
45 }
46
47 static void test_visitor_in_int(TestInputVisitorData *data,
48                                 const void *unused)
49 {
50     int64_t res = 0, value = -42;
51     Error *err = NULL;
52     Visitor *v;
53
54     v = visitor_input_test_init(data, "-42");
55
56     visit_type_int(v, NULL, &res, &err);
57     g_assert(!err);
58     g_assert_cmpint(res, ==, value);
59
60     v = visitor_input_test_init(data, "not an int");
61
62     visit_type_int(v, NULL, &res, &err);
63     error_free_or_abort(&err);
64
65     v = visitor_input_test_init(data, "");
66
67     visit_type_int(v, NULL, &res, &err);
68     error_free_or_abort(&err);
69 }
70
71 static void check_ilist(Visitor *v, int64_t *expected, size_t n)
72 {
73     int64List *res = NULL;
74     int64List *tail;
75     int i;
76
77     visit_type_int64List(v, NULL, &res, &error_abort);
78     tail = res;
79     for (i = 0; i < n; i++) {
80         g_assert(tail);
81         g_assert_cmpint(tail->value, ==, expected[i]);
82         tail = tail->next;
83     }
84     g_assert(!tail);
85
86     qapi_free_int64List(res);
87 }
88
89 static void check_ulist(Visitor *v, uint64_t *expected, size_t n)
90 {
91     uint64List *res = NULL;
92     uint64List *tail;
93     int i;
94
95     visit_type_uint64List(v, NULL, &res, &error_abort);
96     tail = res;
97     for (i = 0; i < n; i++) {
98         g_assert(tail);
99         g_assert_cmpuint(tail->value, ==, expected[i]);
100         tail = tail->next;
101     }
102     g_assert(!tail);
103
104     qapi_free_uint64List(res);
105 }
106
107 static void test_visitor_in_intList(TestInputVisitorData *data,
108                                     const void *unused)
109 {
110     int64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
111                           8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
112     int64_t expect2[] = { 32767, -32768, -32767 };
113     int64_t expect3[] = { INT64_MIN, INT64_MAX };
114     int64_t expect4[] = { 1 };
115     int64_t expect5[] = { INT64_MAX - 2,  INT64_MAX - 1, INT64_MAX };
116     Error *err = NULL;
117     int64List *res = NULL;
118     Visitor *v;
119     int64_t val;
120
121     /* Valid lists */
122
123     v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
124     check_ilist(v, expect1, ARRAY_SIZE(expect1));
125
126     v = visitor_input_test_init(data, "32767,-32768--32767");
127     check_ilist(v, expect2, ARRAY_SIZE(expect2));
128
129     v = visitor_input_test_init(data,
130                                 "-9223372036854775808,9223372036854775807");
131     check_ilist(v, expect3, ARRAY_SIZE(expect3));
132
133     v = visitor_input_test_init(data, "1-1");
134     check_ilist(v, expect4, ARRAY_SIZE(expect4));
135
136     v = visitor_input_test_init(data,
137                                 "9223372036854775805-9223372036854775807");
138     check_ilist(v, expect5, ARRAY_SIZE(expect5));
139
140     /* Value too large */
141
142     v = visitor_input_test_init(data, "9223372036854775808");
143     visit_type_int64List(v, NULL, &res, &err);
144     error_free_or_abort(&err);
145     g_assert(!res);
146
147     /* Value too small */
148
149     v = visitor_input_test_init(data, "-9223372036854775809");
150     visit_type_int64List(v, NULL, &res, &err);
151     error_free_or_abort(&err);
152     g_assert(!res);
153
154     /* Range not ascending */
155
156     v = visitor_input_test_init(data, "3-1");
157     visit_type_int64List(v, NULL, &res, &err);
158     error_free_or_abort(&err);
159     g_assert(!res);
160
161     v = visitor_input_test_init(data, "9223372036854775807-0");
162     visit_type_int64List(v, NULL, &res, &err);
163     error_free_or_abort(&err);
164     g_assert(!res);
165
166     /* Range too big (65536 is the limit against DOS attacks) */
167
168     v = visitor_input_test_init(data, "0-65536");
169     visit_type_int64List(v, NULL, &res, &err);
170     error_free_or_abort(&err);
171     g_assert(!res);
172
173     /* Empty list */
174
175     v = visitor_input_test_init(data, "");
176     visit_type_int64List(v, NULL, &res, &error_abort);
177     g_assert(!res);
178
179     /* Not a list */
180
181     v = visitor_input_test_init(data, "not an int list");
182
183     visit_type_int64List(v, NULL, &res, &err);
184     error_free_or_abort(&err);
185     g_assert(!res);
186
187     /* Unvisited list tail */
188
189     v = visitor_input_test_init(data, "0,2-3");
190
191     visit_start_list(v, NULL, NULL, 0, &error_abort);
192     visit_type_int64(v, NULL, &val, &error_abort);
193     g_assert_cmpint(val, ==, 0);
194     visit_type_int64(v, NULL, &val, &error_abort);
195     g_assert_cmpint(val, ==, 2);
196
197     visit_check_list(v, &err);
198     error_free_or_abort(&err);
199     visit_end_list(v, NULL);
200
201     /* Visit beyond end of list */
202
203     v = visitor_input_test_init(data, "0");
204
205     visit_start_list(v, NULL, NULL, 0, &error_abort);
206     visit_type_int64(v, NULL, &val, &err);
207     g_assert_cmpint(val, ==, 0);
208     visit_type_int64(v, NULL, &val, &err);
209     error_free_or_abort(&err);
210
211     visit_check_list(v, &error_abort);
212     visit_end_list(v, NULL);
213 }
214
215 static void test_visitor_in_uintList(TestInputVisitorData *data,
216                                      const void *unused)
217 {
218     uint64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7,
219                            8, 9, 1, 2, 3, 4, 5, 6, 7, 8 };
220     uint64_t expect2[] = { 32767, -32768, -32767 };
221     uint64_t expect3[] = { INT64_MIN, INT64_MAX };
222     uint64_t expect4[] = { 1 };
223     uint64_t expect5[] = { UINT64_MAX };
224     uint64_t expect6[] = { UINT64_MAX - 2,  UINT64_MAX - 1, UINT64_MAX };
225     Error *err = NULL;
226     uint64List *res = NULL;
227     Visitor *v;
228     uint64_t val;
229
230     /* Valid lists */
231
232     v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
233     check_ulist(v, expect1, ARRAY_SIZE(expect1));
234
235     v = visitor_input_test_init(data, "32767,-32768--32767");
236     check_ulist(v, expect2, ARRAY_SIZE(expect2));
237
238     v = visitor_input_test_init(data,
239                                 "-9223372036854775808,9223372036854775807");
240     check_ulist(v, expect3, ARRAY_SIZE(expect3));
241
242     v = visitor_input_test_init(data, "1-1");
243     check_ulist(v, expect4, ARRAY_SIZE(expect4));
244
245     v = visitor_input_test_init(data, "18446744073709551615");
246     check_ulist(v, expect5, ARRAY_SIZE(expect5));
247
248     v = visitor_input_test_init(data,
249                                 "18446744073709551613-18446744073709551615");
250     check_ulist(v, expect6, ARRAY_SIZE(expect6));
251
252     /* Value too large */
253
254     v = visitor_input_test_init(data, "18446744073709551616");
255     visit_type_uint64List(v, NULL, &res, &err);
256     error_free_or_abort(&err);
257     g_assert(!res);
258
259     /* Value too small */
260
261     v = visitor_input_test_init(data, "-18446744073709551616");
262     visit_type_uint64List(v, NULL, &res, &err);
263     error_free_or_abort(&err);
264     g_assert(!res);
265
266     /* Range not ascending */
267
268     v = visitor_input_test_init(data, "3-1");
269     visit_type_uint64List(v, NULL, &res, &err);
270     error_free_or_abort(&err);
271     g_assert(!res);
272
273     v = visitor_input_test_init(data, "18446744073709551615-0");
274     visit_type_uint64List(v, NULL, &res, &err);
275     error_free_or_abort(&err);
276     g_assert(!res);
277
278     /* Range too big (65536 is the limit against DOS attacks) */
279
280     v = visitor_input_test_init(data, "0-65536");
281     visit_type_uint64List(v, NULL, &res, &err);
282     error_free_or_abort(&err);
283     g_assert(!res);
284
285     /* Empty list */
286
287     v = visitor_input_test_init(data, "");
288     visit_type_uint64List(v, NULL, &res, &error_abort);
289     g_assert(!res);
290
291     /* Not a list */
292
293     v = visitor_input_test_init(data, "not an uint list");
294
295     visit_type_uint64List(v, NULL, &res, &err);
296     error_free_or_abort(&err);
297     g_assert(!res);
298
299     /* Unvisited list tail */
300
301     v = visitor_input_test_init(data, "0,2-3");
302
303     visit_start_list(v, NULL, NULL, 0, &error_abort);
304     visit_type_uint64(v, NULL, &val, &error_abort);
305     g_assert_cmpuint(val, ==, 0);
306     visit_type_uint64(v, NULL, &val, &error_abort);
307     g_assert_cmpuint(val, ==, 2);
308
309     visit_check_list(v, &err);
310     error_free_or_abort(&err);
311     visit_end_list(v, NULL);
312
313     /* Visit beyond end of list */
314
315     v = visitor_input_test_init(data, "0");
316
317     visit_start_list(v, NULL, NULL, 0, &error_abort);
318     visit_type_uint64(v, NULL, &val, &err);
319     g_assert_cmpuint(val, ==, 0);
320     visit_type_uint64(v, NULL, &val, &err);
321     error_free_or_abort(&err);
322
323     visit_check_list(v, &error_abort);
324     visit_end_list(v, NULL);
325 }
326
327 static void test_visitor_in_bool(TestInputVisitorData *data,
328                                  const void *unused)
329 {
330     Error *err = NULL;
331     bool res = false;
332     Visitor *v;
333
334     v = visitor_input_test_init(data, "true");
335
336     visit_type_bool(v, NULL, &res, &err);
337     g_assert(!err);
338     g_assert_cmpint(res, ==, true);
339
340     v = visitor_input_test_init(data, "yes");
341
342     visit_type_bool(v, NULL, &res, &err);
343     g_assert(!err);
344     g_assert_cmpint(res, ==, true);
345
346     v = visitor_input_test_init(data, "on");
347
348     visit_type_bool(v, NULL, &res, &err);
349     g_assert(!err);
350     g_assert_cmpint(res, ==, true);
351
352     v = visitor_input_test_init(data, "false");
353
354     visit_type_bool(v, NULL, &res, &err);
355     g_assert(!err);
356     g_assert_cmpint(res, ==, false);
357
358     v = visitor_input_test_init(data, "no");
359
360     visit_type_bool(v, NULL, &res, &err);
361     g_assert(!err);
362     g_assert_cmpint(res, ==, false);
363
364     v = visitor_input_test_init(data, "off");
365
366     visit_type_bool(v, NULL, &res, &err);
367     g_assert(!err);
368     g_assert_cmpint(res, ==, false);
369 }
370
371 static void test_visitor_in_number(TestInputVisitorData *data,
372                                    const void *unused)
373 {
374     double res = 0, value = 3.14;
375     Error *err = NULL;
376     Visitor *v;
377
378     v = visitor_input_test_init(data, "3.14");
379
380     visit_type_number(v, NULL, &res, &err);
381     g_assert(!err);
382     g_assert_cmpfloat(res, ==, value);
383
384     /* NaN and infinity has to be rejected */
385
386     v = visitor_input_test_init(data, "NaN");
387
388     visit_type_number(v, NULL, &res, &err);
389     error_free_or_abort(&err);
390
391     v = visitor_input_test_init(data, "inf");
392
393     visit_type_number(v, NULL, &res, &err);
394     error_free_or_abort(&err);
395
396 }
397
398 static void test_visitor_in_string(TestInputVisitorData *data,
399                                    const void *unused)
400 {
401     char *res = NULL, *value = (char *) "Q E M U";
402     Error *err = NULL;
403     Visitor *v;
404
405     v = visitor_input_test_init(data, value);
406
407     visit_type_str(v, NULL, &res, &err);
408     g_assert(!err);
409     g_assert_cmpstr(res, ==, value);
410
411     g_free(res);
412 }
413
414 static void test_visitor_in_enum(TestInputVisitorData *data,
415                                  const void *unused)
416 {
417     Error *err = NULL;
418     Visitor *v;
419     EnumOne i;
420
421     for (i = 0; i < ENUM_ONE__MAX; i++) {
422         EnumOne res = -1;
423
424         v = visitor_input_test_init(data, EnumOne_str(i));
425
426         visit_type_EnumOne(v, NULL, &res, &err);
427         g_assert(!err);
428         g_assert_cmpint(i, ==, res);
429     }
430 }
431
432 /* Try to crash the visitors */
433 static void test_visitor_in_fuzz(TestInputVisitorData *data,
434                                  const void *unused)
435 {
436     int64_t ires;
437     intList *ilres;
438     bool bres;
439     double nres;
440     char *sres;
441     EnumOne eres;
442     Visitor *v;
443     unsigned int i;
444     char buf[10000];
445
446     for (i = 0; i < 100; i++) {
447         unsigned int j;
448
449         j = g_test_rand_int_range(0, sizeof(buf) - 1);
450
451         buf[j] = '\0';
452
453         if (j != 0) {
454             for (j--; j != 0; j--) {
455                 buf[j - 1] = (char)g_test_rand_int_range(0, 256);
456             }
457         }
458
459         v = visitor_input_test_init(data, buf);
460         visit_type_int(v, NULL, &ires, NULL);
461
462         v = visitor_input_test_init(data, buf);
463         visit_type_intList(v, NULL, &ilres, NULL);
464         qapi_free_intList(ilres);
465
466         v = visitor_input_test_init(data, buf);
467         visit_type_bool(v, NULL, &bres, NULL);
468
469         v = visitor_input_test_init(data, buf);
470         visit_type_number(v, NULL, &nres, NULL);
471
472         v = visitor_input_test_init(data, buf);
473         sres = NULL;
474         visit_type_str(v, NULL, &sres, NULL);
475         g_free(sres);
476
477         v = visitor_input_test_init(data, buf);
478         visit_type_EnumOne(v, NULL, &eres, NULL);
479     }
480 }
481
482 static void input_visitor_test_add(const char *testpath,
483                                    TestInputVisitorData *data,
484                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
485 {
486     g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
487                visitor_input_teardown);
488 }
489
490 int main(int argc, char **argv)
491 {
492     TestInputVisitorData in_visitor_data;
493
494     g_test_init(&argc, &argv, NULL);
495
496     input_visitor_test_add("/string-visitor/input/int",
497                            &in_visitor_data, test_visitor_in_int);
498     input_visitor_test_add("/string-visitor/input/intList",
499                            &in_visitor_data, test_visitor_in_intList);
500     input_visitor_test_add("/string-visitor/input/uintList",
501                            &in_visitor_data, test_visitor_in_uintList);
502     input_visitor_test_add("/string-visitor/input/bool",
503                            &in_visitor_data, test_visitor_in_bool);
504     input_visitor_test_add("/string-visitor/input/number",
505                            &in_visitor_data, test_visitor_in_number);
506     input_visitor_test_add("/string-visitor/input/string",
507                             &in_visitor_data, test_visitor_in_string);
508     input_visitor_test_add("/string-visitor/input/enum",
509                             &in_visitor_data, test_visitor_in_enum);
510     input_visitor_test_add("/string-visitor/input/fuzz",
511                             &in_visitor_data, test_visitor_in_fuzz);
512
513     g_test_run();
514
515     return 0;
516 }
This page took 0.052516 seconds and 4 git commands to generate.