xref: /qemu/tests/unit/test-string-output-visitor.c (revision a8fff94d28bd2f0db37b2194cbfa197ba998b7f7)
1 /*
2  * String Output Visitor unit-tests.
3  *
4  * Copyright (C) 2012 Red Hat Inc.
5  *
6  * Authors:
7  *  Paolo Bonzini <pbonzini@redhat.com> (based on test-qmp-output-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-output-visitor.h"
18 #include "test-qapi-types.h"
19 #include "test-qapi-visit.h"
20 #include "qapi/qmp/types.h"
21 
22 typedef struct TestOutputVisitorData {
23     StringOutputVisitor *sov;
24     Visitor *ov;
25     bool human;
26 } TestOutputVisitorData;
27 
28 static void visitor_output_setup_internal(TestOutputVisitorData *data,
29                                           bool human)
30 {
31     data->human = human;
32     data->sov = string_output_visitor_new(human);
33     g_assert(data->sov);
34     data->ov = string_output_get_visitor(data->sov);
35     g_assert(data->ov);
36 }
37 
38 static void visitor_output_setup(TestOutputVisitorData *data,
39                                  const void *unused)
40 {
41     return visitor_output_setup_internal(data, false);
42 }
43 
44 static void visitor_output_setup_human(TestOutputVisitorData *data,
45                                        const void *unused)
46 {
47     return visitor_output_setup_internal(data, true);
48 }
49 
50 static void visitor_output_teardown(TestOutputVisitorData *data,
51                                     const void *unused)
52 {
53     visit_free(data->ov);
54     data->sov = NULL;
55     data->ov = NULL;
56 }
57 
58 static void visitor_reset(TestOutputVisitorData *data)
59 {
60     bool human = data->human;
61 
62     visitor_output_teardown(data, NULL);
63     visitor_output_setup_internal(data, human);
64 }
65 
66 static void test_visitor_out_int(TestOutputVisitorData *data,
67                                  const void *unused)
68 {
69     int64_t value = 42;
70     Error *err = NULL;
71     char *str;
72 
73     visit_type_int(data->ov, NULL, &value, &err);
74     g_assert(!err);
75 
76     str = string_output_get_string(data->sov);
77     g_assert(str != NULL);
78     if (data->human) {
79         g_assert_cmpstr(str, ==, "42 (0x2a)");
80     } else {
81         g_assert_cmpstr(str, ==, "42");
82     }
83     g_free(str);
84 }
85 
86 static void test_visitor_out_intList(TestOutputVisitorData *data,
87                                      const void *unused)
88 {
89     int64_t value[] = {0, 1, 9, 10, 16, 15, 14,
90         3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX};
91     intList *list = NULL, **tmp = &list;
92     int i;
93     Error *err = NULL;
94     char *str;
95 
96     for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) {
97         *tmp = g_malloc0(sizeof(**tmp));
98         (*tmp)->value = value[i];
99         tmp = &(*tmp)->next;
100     }
101 
102     visit_type_intList(data->ov, NULL, &list, &err);
103     g_assert(err == NULL);
104 
105     str = string_output_get_string(data->sov);
106     g_assert(str != NULL);
107     if (data->human) {
108         g_assert_cmpstr(str, ==,
109             "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807 "
110             "(0x0-0x1,0x3-0x6,0x9-0x10,0x15-0x16,"
111             "0x7ffffffffffffffe-0x7fffffffffffffff)");
112     } else {
113         g_assert_cmpstr(str, ==,
114             "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807");
115     }
116     g_free(str);
117     qapi_free_intList(list);
118 }
119 
120 static void test_visitor_out_bool(TestOutputVisitorData *data,
121                                   const void *unused)
122 {
123     Error *err = NULL;
124     bool value = true;
125     char *str;
126 
127     visit_type_bool(data->ov, NULL, &value, &err);
128     g_assert(!err);
129 
130     str = string_output_get_string(data->sov);
131     g_assert(str != NULL);
132     g_assert_cmpstr(str, ==, "true");
133     g_free(str);
134 }
135 
136 static void test_visitor_out_number(TestOutputVisitorData *data,
137                                     const void *unused)
138 {
139     double value = 3.14;
140     Error *err = NULL;
141     char *str;
142 
143     visit_type_number(data->ov, NULL, &value, &err);
144     g_assert(!err);
145 
146     str = string_output_get_string(data->sov);
147     g_assert(str != NULL);
148     g_assert_cmpstr(str, ==, "3.140000");
149     g_free(str);
150 }
151 
152 static void test_visitor_out_string(TestOutputVisitorData *data,
153                                     const void *unused)
154 {
155     char *string = (char *) "Q E M U";
156     const char *string_human = "\"Q E M U\"";
157     Error *err = NULL;
158     char *str;
159 
160     visit_type_str(data->ov, NULL, &string, &err);
161     g_assert(!err);
162 
163     str = string_output_get_string(data->sov);
164     g_assert(str != NULL);
165     if (data->human) {
166         g_assert_cmpstr(str, ==, string_human);
167     } else {
168         g_assert_cmpstr(str, ==, string);
169     }
170     g_free(str);
171 }
172 
173 static void test_visitor_out_no_string(TestOutputVisitorData *data,
174                                        const void *unused)
175 {
176     char *string = NULL;
177     char *str;
178 
179     /* A null string should return "" */
180     visit_type_str(data->ov, NULL, &string, &error_abort);
181 
182     str = string_output_get_string(data->sov);
183     g_assert(str != NULL);
184     if (data->human) {
185         g_assert_cmpstr(str, ==, "<null>");
186     } else {
187         g_assert_cmpstr(str, ==, "");
188     }
189     g_free(str);
190 }
191 
192 static void test_visitor_out_enum(TestOutputVisitorData *data,
193                                   const void *unused)
194 {
195     char *str;
196     EnumOne i;
197 
198     for (i = 0; i < ENUM_ONE__MAX; i++) {
199         visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
200 
201         str = string_output_get_string(data->sov);
202         g_assert(str != NULL);
203         if (data->human) {
204             char *str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]);
205 
206             g_assert_cmpstr(str, ==, str_human);
207             g_free(str_human);
208         } else {
209             g_assert_cmpstr(str, ==, EnumOne_lookup[i]);
210         }
211         g_free(str);
212         visitor_reset(data);
213     }
214 }
215 
216 static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
217                                          const void *unused)
218 {
219     EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 };
220     Error *err;
221 
222     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
223         err = NULL;
224         visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
225         error_free_or_abort(&err);
226     }
227 }
228 
229 static void
230 output_visitor_test_add(const char *testpath,
231                         TestOutputVisitorData *data,
232                         void (*test_func)(TestOutputVisitorData *data,
233                                           const void *user_data),
234                         bool human)
235 {
236     g_test_add(testpath, TestOutputVisitorData, data,
237                human ? visitor_output_setup_human : visitor_output_setup,
238                test_func, visitor_output_teardown);
239 }
240 
241 int main(int argc, char **argv)
242 {
243     TestOutputVisitorData out_visitor_data;
244 
245     g_test_init(&argc, &argv, NULL);
246 
247     output_visitor_test_add("/string-visitor/output/int",
248                             &out_visitor_data, test_visitor_out_int, false);
249     output_visitor_test_add("/string-visitor/output/int-human",
250                             &out_visitor_data, test_visitor_out_int, true);
251     output_visitor_test_add("/string-visitor/output/bool",
252                             &out_visitor_data, test_visitor_out_bool, false);
253     output_visitor_test_add("/string-visitor/output/bool-human",
254                             &out_visitor_data, test_visitor_out_bool, true);
255     output_visitor_test_add("/string-visitor/output/number",
256                             &out_visitor_data, test_visitor_out_number, false);
257     output_visitor_test_add("/string-visitor/output/number-human",
258                             &out_visitor_data, test_visitor_out_number, true);
259     output_visitor_test_add("/string-visitor/output/string",
260                             &out_visitor_data, test_visitor_out_string, false);
261     output_visitor_test_add("/string-visitor/output/string-human",
262                             &out_visitor_data, test_visitor_out_string, true);
263     output_visitor_test_add("/string-visitor/output/no-string",
264                             &out_visitor_data, test_visitor_out_no_string,
265                             false);
266     output_visitor_test_add("/string-visitor/output/no-string-human",
267                             &out_visitor_data, test_visitor_out_no_string,
268                             true);
269     output_visitor_test_add("/string-visitor/output/enum",
270                             &out_visitor_data, test_visitor_out_enum, false);
271     output_visitor_test_add("/string-visitor/output/enum-human",
272                             &out_visitor_data, test_visitor_out_enum, true);
273     output_visitor_test_add("/string-visitor/output/enum-errors",
274                             &out_visitor_data, test_visitor_out_enum_errors,
275                             false);
276     output_visitor_test_add("/string-visitor/output/enum-errors-human",
277                             &out_visitor_data, test_visitor_out_enum_errors,
278                             true);
279     output_visitor_test_add("/string-visitor/output/intList",
280                             &out_visitor_data, test_visitor_out_intList, false);
281     output_visitor_test_add("/string-visitor/output/intList-human",
282                             &out_visitor_data, test_visitor_out_intList, true);
283 
284     g_test_run();
285 
286     return 0;
287 }
288