]>
Commit | Line | Data |
---|---|---|
2d7799f2 PB |
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 | ||
79ee7df8 | 16 | #include "qemu-common.h" |
2d7799f2 PB |
17 | #include "qapi/string-input-visitor.h" |
18 | #include "test-qapi-types.h" | |
19 | #include "test-qapi-visit.h" | |
7b1b5d19 | 20 | #include "qapi/qmp/types.h" |
2d7799f2 PB |
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 *errp = NULL; | |
58 | Visitor *v; | |
59 | ||
60 | v = visitor_input_test_init(data, "-42"); | |
61 | ||
62 | visit_type_int(v, &res, NULL, &errp); | |
63 | g_assert(!error_is_set(&errp)); | |
64 | g_assert_cmpint(res, ==, value); | |
65 | } | |
66 | ||
67 | static void test_visitor_in_bool(TestInputVisitorData *data, | |
68 | const void *unused) | |
69 | { | |
70 | Error *errp = NULL; | |
71 | bool res = false; | |
72 | Visitor *v; | |
73 | ||
74 | v = visitor_input_test_init(data, "true"); | |
75 | ||
76 | visit_type_bool(v, &res, NULL, &errp); | |
77 | g_assert(!error_is_set(&errp)); | |
78 | g_assert_cmpint(res, ==, true); | |
79 | visitor_input_teardown(data, unused); | |
80 | ||
81 | v = visitor_input_test_init(data, "yes"); | |
82 | ||
83 | visit_type_bool(v, &res, NULL, &errp); | |
84 | g_assert(!error_is_set(&errp)); | |
85 | g_assert_cmpint(res, ==, true); | |
86 | visitor_input_teardown(data, unused); | |
87 | ||
88 | v = visitor_input_test_init(data, "on"); | |
89 | ||
90 | visit_type_bool(v, &res, NULL, &errp); | |
91 | g_assert(!error_is_set(&errp)); | |
92 | g_assert_cmpint(res, ==, true); | |
93 | visitor_input_teardown(data, unused); | |
94 | ||
95 | v = visitor_input_test_init(data, "false"); | |
96 | ||
97 | visit_type_bool(v, &res, NULL, &errp); | |
98 | g_assert(!error_is_set(&errp)); | |
99 | g_assert_cmpint(res, ==, false); | |
100 | visitor_input_teardown(data, unused); | |
101 | ||
102 | v = visitor_input_test_init(data, "no"); | |
103 | ||
104 | visit_type_bool(v, &res, NULL, &errp); | |
105 | g_assert(!error_is_set(&errp)); | |
106 | g_assert_cmpint(res, ==, false); | |
107 | visitor_input_teardown(data, unused); | |
108 | ||
109 | v = visitor_input_test_init(data, "off"); | |
110 | ||
111 | visit_type_bool(v, &res, NULL, &errp); | |
112 | g_assert(!error_is_set(&errp)); | |
113 | g_assert_cmpint(res, ==, false); | |
114 | } | |
115 | ||
116 | static void test_visitor_in_number(TestInputVisitorData *data, | |
117 | const void *unused) | |
118 | { | |
119 | double res = 0, value = 3.14; | |
120 | Error *errp = NULL; | |
121 | Visitor *v; | |
122 | ||
123 | v = visitor_input_test_init(data, "3.14"); | |
124 | ||
125 | visit_type_number(v, &res, NULL, &errp); | |
126 | g_assert(!error_is_set(&errp)); | |
127 | g_assert_cmpfloat(res, ==, value); | |
128 | } | |
129 | ||
130 | static void test_visitor_in_string(TestInputVisitorData *data, | |
131 | const void *unused) | |
132 | { | |
133 | char *res = NULL, *value = (char *) "Q E M U"; | |
134 | Error *errp = NULL; | |
135 | Visitor *v; | |
136 | ||
137 | v = visitor_input_test_init(data, value); | |
138 | ||
139 | visit_type_str(v, &res, NULL, &errp); | |
140 | g_assert(!error_is_set(&errp)); | |
141 | g_assert_cmpstr(res, ==, value); | |
142 | ||
143 | g_free(res); | |
144 | } | |
145 | ||
146 | static void test_visitor_in_enum(TestInputVisitorData *data, | |
147 | const void *unused) | |
148 | { | |
149 | Error *errp = NULL; | |
150 | Visitor *v; | |
151 | EnumOne i; | |
152 | ||
153 | for (i = 0; EnumOne_lookup[i]; i++) { | |
154 | EnumOne res = -1; | |
155 | ||
156 | v = visitor_input_test_init(data, EnumOne_lookup[i]); | |
157 | ||
158 | visit_type_EnumOne(v, &res, NULL, &errp); | |
159 | g_assert(!error_is_set(&errp)); | |
160 | g_assert_cmpint(i, ==, res); | |
161 | ||
162 | visitor_input_teardown(data, NULL); | |
163 | } | |
164 | ||
165 | data->siv = NULL; | |
166 | } | |
167 | ||
3f0f31a0 BS |
168 | /* Try to crash the visitors */ |
169 | static void test_visitor_in_fuzz(TestInputVisitorData *data, | |
170 | const void *unused) | |
171 | { | |
172 | int64_t ires; | |
173 | bool bres; | |
174 | double nres; | |
175 | char *sres; | |
176 | EnumOne eres; | |
3f0f31a0 BS |
177 | Visitor *v; |
178 | unsigned int i; | |
179 | char buf[10000]; | |
180 | ||
181 | for (i = 0; i < 100; i++) { | |
182 | unsigned int j; | |
183 | ||
184 | j = g_test_rand_int_range(0, sizeof(buf) - 1); | |
185 | ||
186 | buf[j] = '\0'; | |
187 | ||
188 | if (j != 0) { | |
189 | for (j--; j != 0; j--) { | |
190 | buf[j - 1] = (char)g_test_rand_int_range(0, 256); | |
191 | } | |
192 | } | |
193 | ||
194 | v = visitor_input_test_init(data, buf); | |
01845438 | 195 | visit_type_int(v, &ires, NULL, NULL); |
3f0f31a0 BS |
196 | |
197 | v = visitor_input_test_init(data, buf); | |
01845438 | 198 | visit_type_bool(v, &bres, NULL, NULL); |
3f0f31a0 BS |
199 | visitor_input_teardown(data, NULL); |
200 | ||
201 | v = visitor_input_test_init(data, buf); | |
01845438 | 202 | visit_type_number(v, &nres, NULL, NULL); |
3f0f31a0 BS |
203 | |
204 | v = visitor_input_test_init(data, buf); | |
01845438 PM |
205 | sres = NULL; |
206 | visit_type_str(v, &sres, NULL, NULL); | |
3f0f31a0 BS |
207 | g_free(sres); |
208 | ||
209 | v = visitor_input_test_init(data, buf); | |
01845438 | 210 | visit_type_EnumOne(v, &eres, NULL, NULL); |
3f0f31a0 BS |
211 | visitor_input_teardown(data, NULL); |
212 | } | |
213 | } | |
214 | ||
2d7799f2 PB |
215 | static void input_visitor_test_add(const char *testpath, |
216 | TestInputVisitorData *data, | |
217 | void (*test_func)(TestInputVisitorData *data, const void *user_data)) | |
218 | { | |
219 | g_test_add(testpath, TestInputVisitorData, data, NULL, test_func, | |
220 | visitor_input_teardown); | |
221 | } | |
222 | ||
223 | int main(int argc, char **argv) | |
224 | { | |
225 | TestInputVisitorData in_visitor_data; | |
226 | ||
227 | g_test_init(&argc, &argv, NULL); | |
228 | ||
229 | input_visitor_test_add("/string-visitor/input/int", | |
230 | &in_visitor_data, test_visitor_in_int); | |
231 | input_visitor_test_add("/string-visitor/input/bool", | |
232 | &in_visitor_data, test_visitor_in_bool); | |
233 | input_visitor_test_add("/string-visitor/input/number", | |
234 | &in_visitor_data, test_visitor_in_number); | |
235 | input_visitor_test_add("/string-visitor/input/string", | |
236 | &in_visitor_data, test_visitor_in_string); | |
237 | input_visitor_test_add("/string-visitor/input/enum", | |
238 | &in_visitor_data, test_visitor_in_enum); | |
3f0f31a0 BS |
239 | input_visitor_test_add("/string-visitor/input/fuzz", |
240 | &in_visitor_data, test_visitor_in_fuzz); | |
2d7799f2 PB |
241 | |
242 | g_test_run(); | |
243 | ||
244 | return 0; | |
245 | } |