Pull into test files generated from qapi-schema-test.json by visiter/types generators so we can do unit tests against the generated code.
Also, add test cases for handling of nested structs/qobjects. Note: optional members are implemented yet so test case is slightly gimped. Signed-off-by: Michael Roth <mdr...@linux.vnet.ibm.com> --- test-visiter.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 98 insertions(+), 0 deletions(-) diff --git a/test-visiter.c b/test-visiter.c index 4aec8ab..28810d2 100644 --- a/test-visiter.c +++ b/test-visiter.c @@ -1,6 +1,8 @@ #include <glib.h> #include "qapi/qmp-output-visiter.h" #include "qapi/qmp-input-visiter.h" +#include "test-qapi-types.h" +#include "test-qapi-visit.h" #include "qemu-objects.h" typedef struct TestStruct @@ -37,6 +39,100 @@ static void visit_type_TestStructList(Visiter *m, TestStructList ** obj, const c visit_end_list(m, errp); } +/* test deep nesting with refs to other user-defined types */ +static void test_nested_structs(void) +{ + QmpOutputVisiter *mo; + QmpInputVisiter *mi; + Visiter *v; + UserDefOne ud1; + UserDefOne *ud1_p = &ud1, *ud1c_p = NULL; + UserDefTwo ud2; + UserDefTwo *ud2_p = &ud2, *ud2c_p = NULL; + Error *err = NULL; + QObject *obj; + QString *str; + + ud1.integer = 42; + ud1.string = strdup("fourty two"); + + /* sanity check */ + mo = qmp_output_visiter_new(); + v = qmp_output_get_visiter(mo); + visit_type_UserDefOne(v, &ud1_p, "o_O", &err); + if (err) { + g_error("%s", error_get_pretty(err)); + } + obj = qmp_output_get_qobject(mo); + g_assert(obj); + qobject_decref(obj); + + ud2.string = strdup("fourty three"); + ud2.dict.string = strdup("fourty four"); + ud2.dict.dict.userdef = ud1_p; + ud2.dict.dict.string = strdup("fourty five"); + ud2.dict.has_dict2 = true; + ud2.dict.dict2.userdef = ud1_p; + ud2.dict.dict2.string = strdup("fourty six"); + + /* c type -> qobject */ + mo = qmp_output_visiter_new(); + v = qmp_output_get_visiter(mo); + visit_type_UserDefTwo(v, &ud2_p, "unused", &err); + if (err) { + g_error("%s", error_get_pretty(err)); + } + obj = qmp_output_get_qobject(mo); + g_assert(obj); + str = qobject_to_json_pretty(obj); + g_print("%s\n", qstring_get_str(str)); + QDECREF(str); + + /* qobject -> c type, should match original struct */ + mi = qmp_input_visiter_new(obj); + v = qmp_input_get_visiter(mi); + visit_type_UserDefTwo(v, &ud2c_p, "unused", &err); + if (err) { + g_error("%s", error_get_pretty(err)); + } + + g_assert(!g_strcmp0(ud2c_p->string, ud2.string)); + g_assert(!g_strcmp0(ud2c_p->dict.string, ud2.dict.string)); + + ud1c_p = ud2c_p->dict.dict.userdef; + g_assert(ud1c_p->integer == ud1_p->integer); + g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string)); + + g_assert(!g_strcmp0(ud2c_p->dict.dict.string, ud2.dict.dict.string)); + + /* TODO: ud2.dict.dict2 is optional dict, so these require + * visit_start_optional() to be implemented for input visiter + */ + /* + ud1c_p = ud2c_p->dict.dict2.userdef; + g_assert(ud1c_p->integer == ud1_p->integer); + g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string)); + */ + + g_assert(g_strcmp0(ud2c_p->dict.dict2.string, ud2.dict.dict2.string)); + + qemu_free(ud1.string); + qemu_free(ud2.string); + qemu_free(ud2.dict.string); + qemu_free(ud2.dict.dict.string); + qemu_free(ud2.dict.dict2.string); + + qemu_free(ud1c_p->string); + qemu_free(ud1c_p); + qemu_free(ud2c_p->string); + qemu_free(ud2c_p->dict.string); + qemu_free(ud2c_p->dict.dict.string); + qemu_free(ud2c_p->dict.dict2.string); + qemu_free(ud2c_p); + + qobject_decref(obj); +} + int main(int argc, char **argv) { QmpOutputVisiter *mo; @@ -122,6 +218,8 @@ int main(int argc, char **argv) qobject_decref(obj); + g_test_add_func("/0.15/nested_structs", test_nested_structs); + g_test_run(); return 0; -- 1.7.0.4