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