Statistics
| Branch: | Revision:

root / tests / test-qmp-input-strict.c @ 164a101f

History | View | Annotate | Download (7 kB)

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 "qemu-common.h"
18
#include "qapi/qmp-input-visitor.h"
19
#include "test-qapi-types.h"
20
#include "test-qapi-visit.h"
21
#include "qapi/qmp/types.h"
22

    
23
typedef struct TestInputVisitorData {
24
    QObject *obj;
25
    QmpInputVisitor *qiv;
26
} TestInputVisitorData;
27

    
28
static void validate_teardown(TestInputVisitorData *data,
29
                               const void *unused)
30
{
31
    qobject_decref(data->obj);
32
    data->obj = NULL;
33

    
34
    if (data->qiv) {
35
        qmp_input_visitor_cleanup(data->qiv);
36
        data->qiv = NULL;
37
    }
38
}
39

    
40
/* This is provided instead of a test setup function so that the JSON
41
   string used by the tests are kept in the test functions (and not
42
   int main()) */
43
static GCC_FMT_ATTR(2, 3)
44
Visitor *validate_test_init(TestInputVisitorData *data,
45
                             const char *json_string, ...)
46
{
47
    Visitor *v;
48
    va_list ap;
49

    
50
    va_start(ap, json_string);
51
    data->obj = qobject_from_jsonv(json_string, &ap);
52
    va_end(ap);
53

    
54
    g_assert(data->obj != NULL);
55

    
56
    data->qiv = qmp_input_visitor_new_strict(data->obj);
57
    g_assert(data->qiv != NULL);
58

    
59
    v = qmp_input_get_visitor(data->qiv);
60
    g_assert(v != NULL);
61

    
62
    return v;
63
}
64

    
65
typedef struct TestStruct
66
{
67
    int64_t integer;
68
    bool boolean;
69
    char *string;
70
} TestStruct;
71

    
72
static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
73
                                  const char *name, Error **errp)
74
{
75
    visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
76
                       errp);
77

    
78
    visit_type_int(v, &(*obj)->integer, "integer", errp);
79
    visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
80
    visit_type_str(v, &(*obj)->string, "string", errp);
81

    
82
    visit_end_struct(v, errp);
83
}
84

    
85
static void test_validate_struct(TestInputVisitorData *data,
86
                                  const void *unused)
87
{
88
    TestStruct *p = NULL;
89
    Error *errp = NULL;
90
    Visitor *v;
91

    
92
    v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
93

    
94
    visit_type_TestStruct(v, &p, NULL, &errp);
95
    g_assert(!error_is_set(&errp));
96
    g_free(p->string);
97
    g_free(p);
98
}
99

    
100
static void test_validate_struct_nested(TestInputVisitorData *data,
101
                                         const void *unused)
102
{
103
    UserDefNested *udp = NULL;
104
    Error *errp = NULL;
105
    Visitor *v;
106

    
107
    v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
108

    
109
    visit_type_UserDefNested(v, &udp, NULL, &errp);
110
    g_assert(!error_is_set(&errp));
111
    qapi_free_UserDefNested(udp);
112
}
113

    
114
static void test_validate_list(TestInputVisitorData *data,
115
                                const void *unused)
116
{
117
    UserDefOneList *head = NULL;
118
    Error *errp = NULL;
119
    Visitor *v;
120

    
121
    v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
122

    
123
    visit_type_UserDefOneList(v, &head, NULL, &errp);
124
    g_assert(!error_is_set(&errp));
125
    qapi_free_UserDefOneList(head);
126
}
127

    
128
static void test_validate_union(TestInputVisitorData *data,
129
                                 const void *unused)
130
{
131
    UserDefUnion *tmp = NULL;
132
    Visitor *v;
133
    Error *errp = NULL;
134

    
135
    v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
136

    
137
    visit_type_UserDefUnion(v, &tmp, NULL, &errp);
138
    g_assert(!error_is_set(&errp));
139
    qapi_free_UserDefUnion(tmp);
140
}
141

    
142
static void test_validate_fail_struct(TestInputVisitorData *data,
143
                                       const void *unused)
144
{
145
    TestStruct *p = NULL;
146
    Error *errp = NULL;
147
    Visitor *v;
148

    
149
    v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
150

    
151
    visit_type_TestStruct(v, &p, NULL, &errp);
152
    g_assert(error_is_set(&errp));
153
    if (p) {
154
        g_free(p->string);
155
    }
156
    g_free(p);
157
}
158

    
159
static void test_validate_fail_struct_nested(TestInputVisitorData *data,
160
                                              const void *unused)
161
{
162
    UserDefNested *udp = NULL;
163
    Error *errp = NULL;
164
    Visitor *v;
165

    
166
    v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
167

    
168
    visit_type_UserDefNested(v, &udp, NULL, &errp);
169
    g_assert(error_is_set(&errp));
170
    qapi_free_UserDefNested(udp);
171
}
172

    
173
static void test_validate_fail_list(TestInputVisitorData *data,
174
                                     const void *unused)
175
{
176
    UserDefOneList *head = NULL;
177
    Error *errp = NULL;
178
    Visitor *v;
179

    
180
    v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
181

    
182
    visit_type_UserDefOneList(v, &head, NULL, &errp);
183
    g_assert(error_is_set(&errp));
184
    qapi_free_UserDefOneList(head);
185
}
186

    
187
static void test_validate_fail_union(TestInputVisitorData *data,
188
                                      const void *unused)
189
{
190
    UserDefUnion *tmp = NULL;
191
    Error *errp = NULL;
192
    Visitor *v;
193

    
194
    v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 }, 'extra': 'yyy' }");
195

    
196
    visit_type_UserDefUnion(v, &tmp, NULL, &errp);
197
    g_assert(error_is_set(&errp));
198
    qapi_free_UserDefUnion(tmp);
199
}
200

    
201
static void validate_test_add(const char *testpath,
202
                               TestInputVisitorData *data,
203
                               void (*test_func)(TestInputVisitorData *data, const void *user_data))
204
{
205
    g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
206
               validate_teardown);
207
}
208

    
209
int main(int argc, char **argv)
210
{
211
    TestInputVisitorData testdata;
212

    
213
    g_test_init(&argc, &argv, NULL);
214

    
215
    validate_test_add("/visitor/input-strict/pass/struct",
216
                       &testdata, test_validate_struct);
217
    validate_test_add("/visitor/input-strict/pass/struct-nested",
218
                       &testdata, test_validate_struct_nested);
219
    validate_test_add("/visitor/input-strict/pass/list",
220
                       &testdata, test_validate_list);
221
    validate_test_add("/visitor/input-strict/pass/union",
222
                       &testdata, test_validate_union);
223
    validate_test_add("/visitor/input-strict/fail/struct",
224
                       &testdata, test_validate_fail_struct);
225
    validate_test_add("/visitor/input-strict/fail/struct-nested",
226
                       &testdata, test_validate_fail_struct_nested);
227
    validate_test_add("/visitor/input-strict/fail/list",
228
                       &testdata, test_validate_fail_list);
229
    validate_test_add("/visitor/input-strict/fail/union",
230
                       &testdata, test_validate_fail_union);
231

    
232
    g_test_run();
233

    
234
    return 0;
235
}