|
|
1.1 root 1: /*
2: * QMP Input Visitor unit-tests (strict mode).
3: *
4: * Copyright (C) 2011-2012 Red Hat Inc.
5: *
6: * Authors:
7: * Luiz Capitulino <[email protected]>
8: * Paolo Bonzini <[email protected]>
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.