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