]> git.proxmox.com Git - qemu.git/blame - tests/test-qmp-input-strict.c
mips-linux-user: Always support rdhwr.
[qemu.git] / tests / test-qmp-input-strict.c
CommitLineData
e38ac962
PB
1/*
2 * QMP Input Visitor unit-tests (strict mode).
3 *
4 * Copyright (C) 2011-2012 Red Hat Inc.
5 *
6 * Authors:
7 * Luiz Capitulino <lcapitulino@redhat.com>
8 * Paolo Bonzini <pbonzini@redhat.com>
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
11 * See the COPYING file in the top-level directory.
12 */
13
14#include <glib.h>
15#include <stdarg.h>
16
17#include "qapi/qmp-input-visitor.h"
18#include "test-qapi-types.h"
19#include "test-qapi-visit.h"
20#include "qemu-objects.h"
21
22typedef struct TestInputVisitorData {
23 QObject *obj;
24 QmpInputVisitor *qiv;
25} TestInputVisitorData;
26
27static void validate_teardown(TestInputVisitorData *data,
28 const void *unused)
29{
30 qobject_decref(data->obj);
31 data->obj = NULL;
32
33 if (data->qiv) {
34 qmp_input_visitor_cleanup(data->qiv);
35 data->qiv = NULL;
36 }
37}
38
39/* This is provided instead of a test setup function so that the JSON
40 string used by the tests are kept in the test functions (and not
41 int main()) */
42static GCC_FMT_ATTR(2, 3)
43Visitor *validate_test_init(TestInputVisitorData *data,
44 const char *json_string, ...)
45{
46 Visitor *v;
47 va_list ap;
48
49 va_start(ap, json_string);
50 data->obj = qobject_from_jsonv(json_string, &ap);
51 va_end(ap);
52
53 g_assert(data->obj != NULL);
54
55 data->qiv = qmp_input_visitor_new_strict(data->obj);
56 g_assert(data->qiv != NULL);
57
58 v = qmp_input_get_visitor(data->qiv);
59 g_assert(v != NULL);
60
61 return v;
62}
63
64typedef struct TestStruct
65{
66 int64_t integer;
67 bool boolean;
68 char *string;
69} TestStruct;
70
71static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
72 const char *name, Error **errp)
73{
74 visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
75 errp);
76
77 visit_type_int(v, &(*obj)->integer, "integer", errp);
78 visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
79 visit_type_str(v, &(*obj)->string, "string", errp);
80
81 visit_end_struct(v, errp);
82}
83
84static void test_validate_struct(TestInputVisitorData *data,
85 const void *unused)
86{
87 TestStruct *p = NULL;
88 Error *errp = NULL;
89 Visitor *v;
90
91 v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
92
93 visit_type_TestStruct(v, &p, NULL, &errp);
94 g_assert(!error_is_set(&errp));
95 g_free(p->string);
96 g_free(p);
97}
98
99static void test_validate_struct_nested(TestInputVisitorData *data,
100 const void *unused)
101{
102 UserDefNested *udp = NULL;
103 Error *errp = NULL;
104 Visitor *v;
105
106 v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
107
108 visit_type_UserDefNested(v, &udp, NULL, &errp);
109 g_assert(!error_is_set(&errp));
110 qapi_free_UserDefNested(udp);
111}
112
113static void test_validate_list(TestInputVisitorData *data,
114 const void *unused)
115{
116 UserDefOneList *head = NULL;
117 Error *errp = NULL;
118 Visitor *v;
119
120 v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
121
122 visit_type_UserDefOneList(v, &head, NULL, &errp);
123 g_assert(!error_is_set(&errp));
124 qapi_free_UserDefOneList(head);
125}
126
127static void test_validate_union(TestInputVisitorData *data,
128 const void *unused)
129{
130 UserDefUnion *tmp = NULL;
131 Visitor *v;
132 Error *errp = NULL;
133
134 v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
135
136 visit_type_UserDefUnion(v, &tmp, NULL, &errp);
137 g_assert(!error_is_set(&errp));
138 qapi_free_UserDefUnion(tmp);
139}
140
141static void test_validate_fail_struct(TestInputVisitorData *data,
142 const void *unused)
143{
144 TestStruct *p = NULL;
145 Error *errp = NULL;
146 Visitor *v;
147
148 v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
149
150 visit_type_TestStruct(v, &p, NULL, &errp);
151 g_assert(error_is_set(&errp));
152 if (p) {
153 g_free(p->string);
154 }
155 g_free(p);
156}
157
158static void test_validate_fail_struct_nested(TestInputVisitorData *data,
159 const void *unused)
160{
161 UserDefNested *udp = NULL;
162 Error *errp = NULL;
163 Visitor *v;
164
165 v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
166
167 visit_type_UserDefNested(v, &udp, NULL, &errp);
168 g_assert(error_is_set(&errp));
169 qapi_free_UserDefNested(udp);
170}
171
172static void test_validate_fail_list(TestInputVisitorData *data,
173 const void *unused)
174{
175 UserDefOneList *head = NULL;
176 Error *errp = NULL;
177 Visitor *v;
178
179 v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
180
181 visit_type_UserDefOneList(v, &head, NULL, &errp);
182 g_assert(error_is_set(&errp));
183 qapi_free_UserDefOneList(head);
184}
185
186static void test_validate_fail_union(TestInputVisitorData *data,
187 const void *unused)
188{
189 UserDefUnion *tmp = NULL;
190 Error *errp = NULL;
191 Visitor *v;
192
193 v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 }, 'extra': 'yyy' }");
194
195 visit_type_UserDefUnion(v, &tmp, NULL, &errp);
196 g_assert(error_is_set(&errp));
197 qapi_free_UserDefUnion(tmp);
198}
199
200static void validate_test_add(const char *testpath,
201 TestInputVisitorData *data,
202 void (*test_func)(TestInputVisitorData *data, const void *user_data))
203{
204 g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
205 validate_teardown);
206}
207
208int main(int argc, char **argv)
209{
210 TestInputVisitorData testdata;
211
212 g_test_init(&argc, &argv, NULL);
213
214 validate_test_add("/visitor/input-strict/pass/struct",
215 &testdata, test_validate_struct);
216 validate_test_add("/visitor/input-strict/pass/struct-nested",
217 &testdata, test_validate_struct_nested);
218 validate_test_add("/visitor/input-strict/pass/list",
219 &testdata, test_validate_list);
220 validate_test_add("/visitor/input-strict/pass/union",
221 &testdata, test_validate_union);
222 validate_test_add("/visitor/input-strict/fail/struct",
223 &testdata, test_validate_fail_struct);
224 validate_test_add("/visitor/input-strict/fail/struct-nested",
225 &testdata, test_validate_fail_struct_nested);
226 validate_test_add("/visitor/input-strict/fail/list",
227 &testdata, test_validate_fail_list);
228 validate_test_add("/visitor/input-strict/fail/union",
229 &testdata, test_validate_fail_union);
230
231 g_test_run();
232
233 return 0;
234}