2 * QAPI Forwarding Visitor unit-tests.
4 * Copyright (C) 2021 Red Hat Inc.
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
10 #include "qemu/osdep.h"
12 #include "qapi/forward-visitor.h"
13 #include "qapi/qobject-input-visitor.h"
14 #include "qapi/error.h"
15 #include "qapi/qmp/qobject.h"
16 #include "qapi/qmp/qdict.h"
17 #include "test-qapi-visit.h"
18 #include "qemu/keyval.h"
20 typedef bool GenericVisitor (Visitor
*, const char *, void **, Error
**);
21 #define CAST_VISIT_TYPE(fn) ((GenericVisitor *)(fn))
24 * Parse @srcstr and wrap it with a ForwardFieldVisitor converting "src" to
25 * "dst". Check that visiting the result with "src" name fails, and return
26 * the result of visiting "dst".
28 static void *visit_with_forward(const char *srcstr
, GenericVisitor
*fn
)
31 QDict
*src
= keyval_parse(srcstr
, NULL
, &help
, &error_abort
);
36 v
= qobject_input_visitor_new_keyval(QOBJECT(src
));
37 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
39 alias_v
= visitor_forward_field(v
, "dst", "src");
40 fn(alias_v
, "src", &result
, &err
);
41 error_free_or_abort(&err
);
43 fn(alias_v
, "dst", &result
, &err
);
47 visit_end_struct(v
, NULL
);
49 qobject_unref(QOBJECT(src
));
53 static void test_forward_any(void)
55 QObject
*src
= visit_with_forward("src.integer=42,src.string=Hello,src.enum1=value2",
56 CAST_VISIT_TYPE(visit_type_any
));
57 Visitor
*v
= qobject_input_visitor_new_keyval(src
);
61 visit_type_UserDefOne(v
, NULL
, &dst
, &err
);
65 g_assert_cmpint(dst
->integer
, ==, 42);
66 g_assert_cmpstr(dst
->string
, ==, "Hello");
67 g_assert_cmpint(dst
->has_enum1
, ==, true);
68 g_assert_cmpint(dst
->enum1
, ==, ENUM_ONE_VALUE2
);
69 qapi_free_UserDefOne(dst
);
70 qobject_unref(QOBJECT(src
));
73 static void test_forward_size(void)
76 * visit_type_size does not return a pointer, so visit_with_forward
80 QDict
*src
= keyval_parse("src=1.5M", NULL
, &help
, &error_abort
);
85 v
= qobject_input_visitor_new_keyval(QOBJECT(src
));
86 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
88 alias_v
= visitor_forward_field(v
, "dst", "src");
89 visit_type_size(alias_v
, "src", &result
, &err
);
90 error_free_or_abort(&err
);
91 visit_type_size(alias_v
, "dst", &result
, &err
);
92 assert(result
== 3 << 19);
96 visit_end_struct(v
, NULL
);
98 qobject_unref(QOBJECT(src
));
101 static void test_forward_number(void)
104 * visit_type_number does not return a pointer, so visit_with_forward
108 QDict
*src
= keyval_parse("src=1.5", NULL
, &help
, &error_abort
);
109 Visitor
*v
, *alias_v
;
113 v
= qobject_input_visitor_new_keyval(QOBJECT(src
));
114 visit_start_struct(v
, NULL
, NULL
, 0, &error_abort
);
116 alias_v
= visitor_forward_field(v
, "dst", "src");
117 visit_type_number(alias_v
, "src", &result
, &err
);
118 error_free_or_abort(&err
);
119 visit_type_number(alias_v
, "dst", &result
, &err
);
120 assert(result
== 1.5);
124 visit_end_struct(v
, NULL
);
126 qobject_unref(QOBJECT(src
));
129 static void test_forward_string(void)
131 char *dst
= visit_with_forward("src=Hello",
132 CAST_VISIT_TYPE(visit_type_str
));
134 g_assert_cmpstr(dst
, ==, "Hello");
138 static void test_forward_struct(void)
140 UserDefOne
*dst
= visit_with_forward("src.integer=42,src.string=Hello",
141 CAST_VISIT_TYPE(visit_type_UserDefOne
));
143 g_assert_cmpint(dst
->integer
, ==, 42);
144 g_assert_cmpstr(dst
->string
, ==, "Hello");
145 g_assert_cmpint(dst
->has_enum1
, ==, false);
146 qapi_free_UserDefOne(dst
);
149 static void test_forward_alternate(void)
151 AltStrObj
*s_dst
= visit_with_forward("src=hello",
152 CAST_VISIT_TYPE(visit_type_AltStrObj
));
153 AltStrObj
*o_dst
= visit_with_forward("src.integer=42,src.boolean=true,src.string=world",
154 CAST_VISIT_TYPE(visit_type_AltStrObj
));
156 g_assert_cmpint(s_dst
->type
, ==, QTYPE_QSTRING
);
157 g_assert_cmpstr(s_dst
->u
.s
, ==, "hello");
158 g_assert_cmpint(o_dst
->type
, ==, QTYPE_QDICT
);
159 g_assert_cmpint(o_dst
->u
.o
.integer
, ==, 42);
160 g_assert_cmpint(o_dst
->u
.o
.boolean
, ==, true);
161 g_assert_cmpstr(o_dst
->u
.o
.string
, ==, "world");
163 qapi_free_AltStrObj(s_dst
);
164 qapi_free_AltStrObj(o_dst
);
167 static void test_forward_list(void)
169 uint8List
*dst
= visit_with_forward("src.0=1,src.1=2,src.2=3,src.3=4",
170 CAST_VISIT_TYPE(visit_type_uint8List
));
174 for (tmp
= dst
, i
= 1; i
<= 4; i
++) {
176 g_assert_cmpint(tmp
->value
, ==, i
);
180 qapi_free_uint8List(dst
);
183 int main(int argc
, char **argv
)
185 g_test_init(&argc
, &argv
, NULL
);
187 g_test_add_func("/visitor/forward/struct", test_forward_struct
);
188 g_test_add_func("/visitor/forward/alternate", test_forward_alternate
);
189 g_test_add_func("/visitor/forward/string", test_forward_string
);
190 g_test_add_func("/visitor/forward/size", test_forward_size
);
191 g_test_add_func("/visitor/forward/number", test_forward_number
);
192 g_test_add_func("/visitor/forward/any", test_forward_any
);
193 g_test_add_func("/visitor/forward/list", test_forward_list
);