sync with tizen_2.2
[sdk/emulator/qemu.git] / tests / test-qmp-input-strict.c
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
22 typedef struct TestInputVisitorData {
23     QObject *obj;
24     QmpInputVisitor *qiv;
25 } TestInputVisitorData;
26
27 static 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()) */
42 static GCC_FMT_ATTR(2, 3)
43 Visitor *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
64 typedef struct TestStruct
65 {
66     int64_t integer;
67     bool boolean;
68     char *string;
69 } TestStruct;
70
71 static 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
84 static 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
99 static 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
113 static 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
127 static 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
141 static 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
158 static 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
172 static 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
186 static 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
200 static 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
208 int 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 }