Add qemu 2.4.0
[kvmfornfv.git] / qemu / 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 <pbonzini@redhat.com> (based on test-qmp-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 <glib.h>
14 #include <stdarg.h>
15
16 #include "qemu-common.h"
17 #include "qapi/string-input-visitor.h"
18 #include "test-qapi-types.h"
19 #include "test-qapi-visit.h"
20 #include "qapi/qmp/types.h"
21
22 typedef struct TestInputVisitorData {
23     StringInputVisitor *siv;
24 } TestInputVisitorData;
25
26 static void visitor_input_teardown(TestInputVisitorData *data,
27                                    const void *unused)
28 {
29     if (data->siv) {
30         string_input_visitor_cleanup(data->siv);
31         data->siv = NULL;
32     }
33 }
34
35 /* This is provided instead of a test setup function so that the JSON
36    string used by the tests are kept in the test functions (and not
37    int main()) */
38 static
39 Visitor *visitor_input_test_init(TestInputVisitorData *data,
40                                  const char *string)
41 {
42     Visitor *v;
43
44     data->siv = string_input_visitor_new(string);
45     g_assert(data->siv != NULL);
46
47     v = string_input_get_visitor(data->siv);
48     g_assert(v != NULL);
49
50     return v;
51 }
52
53 static void test_visitor_in_int(TestInputVisitorData *data,
54                                 const void *unused)
55 {
56     int64_t res = 0, value = -42;
57     Error *err = NULL;
58     Visitor *v;
59
60     v = visitor_input_test_init(data, "-42");
61
62     visit_type_int(v, &res, NULL, &err);
63     g_assert(!err);
64     g_assert_cmpint(res, ==, value);
65 }
66
67 static void test_visitor_in_intList(TestInputVisitorData *data,
68                                     const void *unused)
69 {
70     int64_t value[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20};
71     int16List *res = NULL, *tmp;
72     Visitor *v;
73     int i = 0;
74
75     v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
76
77     visit_type_int16List(v, &res, NULL, &error_abort);
78     tmp = res;
79     while (i < sizeof(value) / sizeof(value[0])) {
80         g_assert(tmp);
81         g_assert_cmpint(tmp->value, ==, value[i++]);
82         tmp = tmp->next;
83     }
84     g_assert(!tmp);
85
86     tmp = res;
87     while (tmp) {
88         res = res->next;
89         g_free(tmp);
90         tmp = res;
91     }
92 }
93
94 static void test_visitor_in_bool(TestInputVisitorData *data,
95                                  const void *unused)
96 {
97     Error *err = NULL;
98     bool res = false;
99     Visitor *v;
100
101     v = visitor_input_test_init(data, "true");
102
103     visit_type_bool(v, &res, NULL, &err);
104     g_assert(!err);
105     g_assert_cmpint(res, ==, true);
106     visitor_input_teardown(data, unused);
107
108     v = visitor_input_test_init(data, "yes");
109
110     visit_type_bool(v, &res, NULL, &err);
111     g_assert(!err);
112     g_assert_cmpint(res, ==, true);
113     visitor_input_teardown(data, unused);
114
115     v = visitor_input_test_init(data, "on");
116
117     visit_type_bool(v, &res, NULL, &err);
118     g_assert(!err);
119     g_assert_cmpint(res, ==, true);
120     visitor_input_teardown(data, unused);
121
122     v = visitor_input_test_init(data, "false");
123
124     visit_type_bool(v, &res, NULL, &err);
125     g_assert(!err);
126     g_assert_cmpint(res, ==, false);
127     visitor_input_teardown(data, unused);
128
129     v = visitor_input_test_init(data, "no");
130
131     visit_type_bool(v, &res, NULL, &err);
132     g_assert(!err);
133     g_assert_cmpint(res, ==, false);
134     visitor_input_teardown(data, unused);
135
136     v = visitor_input_test_init(data, "off");
137
138     visit_type_bool(v, &res, NULL, &err);
139     g_assert(!err);
140     g_assert_cmpint(res, ==, false);
141 }
142
143 static void test_visitor_in_number(TestInputVisitorData *data,
144                                    const void *unused)
145 {
146     double res = 0, value = 3.14;
147     Error *err = NULL;
148     Visitor *v;
149
150     v = visitor_input_test_init(data, "3.14");
151
152     visit_type_number(v, &res, NULL, &err);
153     g_assert(!err);
154     g_assert_cmpfloat(res, ==, value);
155 }
156
157 static void test_visitor_in_string(TestInputVisitorData *data,
158                                    const void *unused)
159 {
160     char *res = NULL, *value = (char *) "Q E M U";
161     Error *err = NULL;
162     Visitor *v;
163
164     v = visitor_input_test_init(data, value);
165
166     visit_type_str(v, &res, NULL, &err);
167     g_assert(!err);
168     g_assert_cmpstr(res, ==, value);
169
170     g_free(res);
171 }
172
173 static void test_visitor_in_enum(TestInputVisitorData *data,
174                                  const void *unused)
175 {
176     Error *err = NULL;
177     Visitor *v;
178     EnumOne i;
179
180     for (i = 0; EnumOne_lookup[i]; i++) {
181         EnumOne res = -1;
182
183         v = visitor_input_test_init(data, EnumOne_lookup[i]);
184
185         visit_type_EnumOne(v, &res, NULL, &err);
186         g_assert(!err);
187         g_assert_cmpint(i, ==, res);
188
189         visitor_input_teardown(data, NULL);
190     }
191
192     data->siv = NULL;
193 }
194
195 /* Try to crash the visitors */
196 static void test_visitor_in_fuzz(TestInputVisitorData *data,
197                                  const void *unused)
198 {
199     int64_t ires;
200     intList *ilres;
201     bool bres;
202     double nres;
203     char *sres;
204     EnumOne eres;
205     Visitor *v;
206     unsigned int i;
207     char buf[10000];
208
209     for (i = 0; i < 100; i++) {
210         unsigned int j;
211
212         j = g_test_rand_int_range(0, sizeof(buf) - 1);
213
214         buf[j] = '\0';
215
216         if (j != 0) {
217             for (j--; j != 0; j--) {
218                 buf[j - 1] = (char)g_test_rand_int_range(0, 256);
219             }
220         }
221
222         v = visitor_input_test_init(data, buf);
223         visit_type_int(v, &ires, NULL, NULL);
224         visitor_input_teardown(data, NULL);
225
226         v = visitor_input_test_init(data, buf);
227         visit_type_intList(v, &ilres, NULL, NULL);
228         visitor_input_teardown(data, NULL);
229
230         v = visitor_input_test_init(data, buf);
231         visit_type_bool(v, &bres, NULL, NULL);
232         visitor_input_teardown(data, NULL);
233
234         v = visitor_input_test_init(data, buf);
235         visit_type_number(v, &nres, NULL, NULL);
236         visitor_input_teardown(data, NULL);
237
238         v = visitor_input_test_init(data, buf);
239         sres = NULL;
240         visit_type_str(v, &sres, NULL, NULL);
241         g_free(sres);
242         visitor_input_teardown(data, NULL);
243
244         v = visitor_input_test_init(data, buf);
245         visit_type_EnumOne(v, &eres, NULL, NULL);
246         visitor_input_teardown(data, NULL);
247     }
248 }
249
250 static void input_visitor_test_add(const char *testpath,
251                                    TestInputVisitorData *data,
252                                    void (*test_func)(TestInputVisitorData *data, const void *user_data))
253 {
254     g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
255                visitor_input_teardown);
256 }
257
258 int main(int argc, char **argv)
259 {
260     TestInputVisitorData in_visitor_data;
261
262     g_test_init(&argc, &argv, NULL);
263
264     input_visitor_test_add("/string-visitor/input/int",
265                            &in_visitor_data, test_visitor_in_int);
266     input_visitor_test_add("/string-visitor/input/intList",
267                            &in_visitor_data, test_visitor_in_intList);
268     input_visitor_test_add("/string-visitor/input/bool",
269                            &in_visitor_data, test_visitor_in_bool);
270     input_visitor_test_add("/string-visitor/input/number",
271                            &in_visitor_data, test_visitor_in_number);
272     input_visitor_test_add("/string-visitor/input/string",
273                             &in_visitor_data, test_visitor_in_string);
274     input_visitor_test_add("/string-visitor/input/enum",
275                             &in_visitor_data, test_visitor_in_enum);
276     input_visitor_test_add("/string-visitor/input/fuzz",
277                             &in_visitor_data, test_visitor_in_fuzz);
278
279     g_test_run();
280
281     return 0;
282 }