* [Qemu-devel] [PATCH v2 0/4]: Improve QMP visitor unit-tests
@ 2011-12-05 14:45 Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 1/4] configure: Don't mix glib and libcheck tests Luiz Capitulino
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Luiz Capitulino @ 2011-12-05 14:45 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, mdroth
This series introduces two new test programs: test-qmp-output-visitor and
test-qmp-input-visitor.
As their names suggest, they contain unit-tests to check QMP's Visitor
implementation. They supersede the test-visitor program (which is dropped
by this series).
Besides adding new unit-tests, I've _tried_ to follow these principles:
- The tests don't print test result data to be manually checked by humans.
Instead, all results are checked with g_assert()s and printed results
are only OK or FAILED
- Each test-case checks a single functionality
- A test-case is only allowed to use a QAPI functionality after it has
been tested
- setup and teardown functions are used as much as possible to avoid
duplication
PS: The first patch is a fix unrelated to the QAPI.
changelog
---------
v2
o Rebase against Makefile changes in master
o Typo fix in patch 1/4
Makefile | 9 +-
configure | 5 +-
qapi-schema-test.json | 6 +
test-qmp-input-visitor.c | 270 +++++++++++++++++++++++++++++
test-qmp-output-visitor.c | 423 +++++++++++++++++++++++++++++++++++++++++++++
test-visitor.c | 338 ------------------------------------
6 files changed, 708 insertions(+), 343 deletions(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 1/4] configure: Don't mix glib and libcheck tests
2011-12-05 14:45 [Qemu-devel] [PATCH v2 0/4]: Improve QMP visitor unit-tests Luiz Capitulino
@ 2011-12-05 14:45 ` Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 2/4] Introduce test-qmp-output-visitor Luiz Capitulino
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Luiz Capitulino @ 2011-12-05 14:45 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, mdroth
test-coroutine is listed as a libcheck test in the 'checks' variable. This
is not right because 'make check' won't run test-coroutine if libcheck
tests are not enabled (either because libcheck isn't detected or because
--disable-check-utests is passed).
Tests using the glib test framework are independent from libcheck and
afaik are always present (although having a configure switch to disable
them is probably worth it).
Untangle test-coroutine from the libcheck tests by introducing the
'test_progs' variable and using it to generate the test list used by
'make check'.
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
configure | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index ac4840d..a1cabad 100755
--- a/configure
+++ b/configure
@@ -2742,8 +2742,9 @@ if test "$softmmu" = yes ; then
fi
if [ "$check_utests" = "yes" ]; then
checks="check-qint check-qstring check-qdict check-qlist"
- checks="check-qfloat check-qjson test-coroutine $checks"
+ checks="check-qfloat check-qjson $checks"
fi
+ test_progs="$checks test-coroutine"
fi
fi
@@ -3232,7 +3233,7 @@ if test "$trace_default" = "yes"; then
fi
echo "TOOLS=$tools" >> $config_host_mak
-echo "CHECKS=$checks" >> $config_host_mak
+echo "CHECKS=$test_progs" >> $config_host_mak
echo "ROMS=$roms" >> $config_host_mak
echo "MAKE=$make" >> $config_host_mak
echo "INSTALL=$install" >> $config_host_mak
--
1.7.8.dirty
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 2/4] Introduce test-qmp-output-visitor
2011-12-05 14:45 [Qemu-devel] [PATCH v2 0/4]: Improve QMP visitor unit-tests Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 1/4] configure: Don't mix glib and libcheck tests Luiz Capitulino
@ 2011-12-05 14:45 ` Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 3/4] Introduce test-qmp-input-visitor Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 4/4] Drop test-visitor Luiz Capitulino
3 siblings, 0 replies; 5+ messages in thread
From: Luiz Capitulino @ 2011-12-05 14:45 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, mdroth
Contains unit-tests for the QMP output visitor implementation.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
Makefile | 5 +-
configure | 2 +-
qapi-schema-test.json | 6 +
test-qmp-output-visitor.c | 423 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 434 insertions(+), 2 deletions(-)
create mode 100644 test-qmp-output-visitor.c
diff --git a/Makefile b/Makefile
index 301c75e..206854a 100644
--- a/Makefile
+++ b/Makefile
@@ -169,7 +169,7 @@ test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y)
$(qapi-obj-y): $(GENERATED_HEADERS)
qapi-dir := $(BUILD_DIR)/qapi-generated
-test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
+test-qmp-output-visitor.o test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
$(qapi-dir)/test-qapi-types.c $(qapi-dir)/test-qapi-types.h :\
@@ -205,6 +205,9 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py
test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
test-visitor: test-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+test-qmp-output-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
+test-qmp-output-visitor: test-qmp-output-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+
test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y)
test-qmp-commands: test-qmp-commands.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
diff --git a/configure b/configure
index a1cabad..ad403f7 100755
--- a/configure
+++ b/configure
@@ -2744,7 +2744,7 @@ if test "$softmmu" = yes ; then
checks="check-qint check-qstring check-qdict check-qlist"
checks="check-qfloat check-qjson $checks"
fi
- test_progs="$checks test-coroutine"
+ test_progs="$checks test-coroutine test-qmp-output-visitor"
fi
fi
diff --git a/qapi-schema-test.json b/qapi-schema-test.json
index 3acedad..2b38919 100644
--- a/qapi-schema-test.json
+++ b/qapi-schema-test.json
@@ -16,6 +16,12 @@
'dict': { 'userdef': 'UserDefOne', 'string': 'str' },
'*dict2': { 'userdef': 'UserDefOne', 'string': 'str' } } } }
+{ 'type': 'UserDefNested',
+ 'data': { 'string0': 'str',
+ 'dict1': { 'string1': 'str',
+ 'dict2': { 'userdef1': 'UserDefOne', 'string2': 'str' },
+ '*dict3': { 'userdef2': 'UserDefOne', 'string3': 'str' } } } }
+
# testing commands
{ 'command': 'user_def_cmd', 'data': {} }
{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
diff --git a/test-qmp-output-visitor.c b/test-qmp-output-visitor.c
new file mode 100644
index 0000000..c94c208
--- /dev/null
+++ b/test-qmp-output-visitor.c
@@ -0,0 +1,423 @@
+/*
+ * QMP Output Visitor unit-tests.
+ *
+ * Copyright (C) 2011 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+
+#include "qapi/qmp-output-visitor.h"
+#include "test-qapi-types.h"
+#include "test-qapi-visit.h"
+#include "qemu-objects.h"
+
+typedef struct TestOutputVisitorData {
+ QmpOutputVisitor *qov;
+ Visitor *ov;
+} TestOutputVisitorData;
+
+static void visitor_output_setup(TestOutputVisitorData *data,
+ const void *unused)
+{
+ data->qov = qmp_output_visitor_new();
+ g_assert(data->qov != NULL);
+
+ data->ov = qmp_output_get_visitor(data->qov);
+ g_assert(data->ov != NULL);
+}
+
+static void visitor_output_teardown(TestOutputVisitorData *data,
+ const void *unused)
+{
+ qmp_output_visitor_cleanup(data->qov);
+ data->qov = NULL;
+ data->ov = NULL;
+}
+
+static void test_visitor_out_int(TestOutputVisitorData *data,
+ const void *unused)
+{
+ int64_t value = -42;
+ Error *errp = NULL;
+ QObject *obj;
+
+ visit_type_int(data->ov, &value, NULL, &errp);
+ g_assert(error_is_set(&errp) == 0);
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QINT);
+ g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, value);
+
+ qobject_decref(obj);
+}
+
+static void test_visitor_out_bool(TestOutputVisitorData *data,
+ const void *unused)
+{
+ Error *errp = NULL;
+ bool value = true;
+ QObject *obj;
+
+ visit_type_bool(data->ov, &value, NULL, &errp);
+ g_assert(error_is_set(&errp) == 0);
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QBOOL);
+ g_assert(qbool_get_int(qobject_to_qbool(obj)) == value);
+
+ qobject_decref(obj);
+}
+
+static void test_visitor_out_number(TestOutputVisitorData *data,
+ const void *unused)
+{
+ double value = 3.14;
+ Error *errp = NULL;
+ QObject *obj;
+
+ visit_type_number(data->ov, &value, NULL, &errp);
+ g_assert(error_is_set(&errp) == 0);
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QFLOAT);
+ g_assert(qfloat_get_double(qobject_to_qfloat(obj)) == value);
+
+ qobject_decref(obj);
+}
+
+static void test_visitor_out_string(TestOutputVisitorData *data,
+ const void *unused)
+{
+ char *string = (char *) "Q E M U";
+ Error *errp = NULL;
+ QObject *obj;
+
+ visit_type_str(data->ov, &string, NULL, &errp);
+ g_assert(error_is_set(&errp) == 0);
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QSTRING);
+ g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, string);
+
+ qobject_decref(obj);
+}
+
+static void test_visitor_out_no_string(TestOutputVisitorData *data,
+ const void *unused)
+{
+ char *string = NULL;
+ Error *errp = NULL;
+ QObject *obj;
+
+ /* A null string should return "" */
+ visit_type_str(data->ov, &string, NULL, &errp);
+ g_assert(error_is_set(&errp) == 0);
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QSTRING);
+ g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, "");
+
+ qobject_decref(obj);
+}
+
+static void test_visitor_out_enum(TestOutputVisitorData *data,
+ const void *unused)
+{
+ Error *errp = NULL;
+ QObject *obj;
+ EnumOne i;
+
+ for (i = 0; i < ENUM_ONE_MAX; i++) {
+ visit_type_EnumOne(data->ov, &i, "unused", &errp);
+ g_assert(!error_is_set(&errp));
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QSTRING);
+ g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==,
+ EnumOne_lookup[i]);
+ qobject_decref(obj);
+ }
+}
+
+static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
+ const void *unused)
+{
+ EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
+ Error *errp;
+
+ for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
+ errp = NULL;
+ visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
+ g_assert(error_is_set(&errp) == true);
+ error_free(errp);
+ }
+}
+
+typedef struct TestStruct
+{
+ int64_t integer;
+ bool boolean;
+ char *string;
+} TestStruct;
+
+static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
+ const char *name, Error **errp)
+{
+ visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
+ errp);
+
+ visit_type_int(v, &(*obj)->integer, "integer", errp);
+ visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
+ visit_type_str(v, &(*obj)->string, "string", errp);
+
+ visit_end_struct(v, errp);
+}
+
+static void test_visitor_out_struct(TestOutputVisitorData *data,
+ const void *unused)
+{
+ TestStruct test_struct = { .integer = 42,
+ .boolean = false,
+ .string = (char *) "foo"};
+ TestStruct *p = &test_struct;
+ Error *errp = NULL;
+ QObject *obj;
+ QDict *qdict;
+
+ visit_type_TestStruct(data->ov, &p, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QDICT);
+
+ qdict = qobject_to_qdict(obj);
+ g_assert_cmpint(qdict_size(qdict), ==, 3);
+ g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
+ g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, 0);
+ g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
+
+ QDECREF(qdict);
+}
+
+static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
+ const void *unused)
+{
+ int64_t value = 42;
+ Error *errp = NULL;
+ UserDefNested *ud2;
+ QObject *obj;
+ QDict *qdict, *dict1, *dict2, *dict3, *userdef;
+ const char *string = "user def string";
+ const char *strings[] = { "fourty two", "fourty three", "fourty four",
+ "fourty five" };
+
+ ud2 = g_malloc0(sizeof(*ud2));
+ ud2->string0 = g_strdup(strings[0]);
+
+ ud2->dict1.string1 = g_strdup(strings[1]);
+ ud2->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
+ ud2->dict1.dict2.userdef1->string = g_strdup(string);
+ ud2->dict1.dict2.userdef1->integer = value;
+ ud2->dict1.dict2.string2 = g_strdup(strings[2]);
+
+ ud2->dict1.has_dict3 = true;
+ ud2->dict1.dict3.userdef2 = g_malloc0(sizeof(UserDefOne));
+ ud2->dict1.dict3.userdef2->string = g_strdup(string);
+ ud2->dict1.dict3.userdef2->integer = value;
+ ud2->dict1.dict3.string3 = g_strdup(strings[3]);
+
+ visit_type_UserDefNested(data->ov, &ud2, "unused", &errp);
+ g_assert(!error_is_set(&errp));
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QDICT);
+
+ qdict = qobject_to_qdict(obj);
+ g_assert_cmpint(qdict_size(qdict), ==, 2);
+ g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
+
+ dict1 = qdict_get_qdict(qdict, "dict1");
+ g_assert_cmpint(qdict_size(dict1), ==, 3);
+ g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
+
+ dict2 = qdict_get_qdict(dict1, "dict2");
+ g_assert_cmpint(qdict_size(dict2), ==, 2);
+ g_assert_cmpstr(qdict_get_str(dict2, "string2"), ==, strings[2]);
+ userdef = qdict_get_qdict(dict2, "userdef1");
+ g_assert_cmpint(qdict_size(userdef), ==, 2);
+ g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
+ g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
+
+ dict3 = qdict_get_qdict(dict1, "dict3");
+ g_assert_cmpint(qdict_size(dict3), ==, 2);
+ g_assert_cmpstr(qdict_get_str(dict3, "string3"), ==, strings[3]);
+ userdef = qdict_get_qdict(dict3, "userdef2");
+ g_assert_cmpint(qdict_size(userdef), ==, 2);
+ g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
+ g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
+
+ QDECREF(qdict);
+ qapi_free_UserDefNested(ud2);
+}
+
+typedef struct TestStructList
+{
+ TestStruct *value;
+ struct TestStructList *next;
+} TestStructList;
+
+static void visit_type_TestStructList(Visitor *v, TestStructList **obj,
+ const char *name, Error **errp)
+{
+ GenericList *i, **head = (GenericList **)obj;
+
+ visit_start_list(v, name, errp);
+
+ for (*head = i = visit_next_list(v, head, errp); i; i = visit_next_list(v, &i, errp)) {
+ TestStructList *native_i = (TestStructList *)i;
+ visit_type_TestStruct(v, &native_i->value, NULL, errp);
+ }
+
+ visit_end_list(v, errp);
+}
+
+static void test_visitor_out_list(TestOutputVisitorData *data,
+ const void *unused)
+{
+ char *value_str = (char *) "list value";
+ TestStructList *p, *head = NULL;
+ const int max_items = 10;
+ bool value_bool = true;
+ int value_int = 10;
+ Error *errp = NULL;
+ QListEntry *entry;
+ QObject *obj;
+ QList *qlist;
+ int i;
+
+ for (i = 0; i < max_items; i++) {
+ p = g_malloc0(sizeof(*p));
+ p->value = g_malloc0(sizeof(*p->value));
+ p->value->integer = value_int;
+ p->value->boolean = value_bool;
+ p->value->string = value_str;
+
+ p->next = head;
+ head = p;
+ }
+
+ visit_type_TestStructList(data->ov, &head, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+
+ obj = qmp_output_get_qobject(data->qov);
+ g_assert(obj != NULL);
+ g_assert(qobject_type(obj) == QTYPE_QLIST);
+
+ qlist = qobject_to_qlist(obj);
+ g_assert(!qlist_empty(qlist));
+
+ i = 0;
+ QLIST_FOREACH_ENTRY(qlist, entry) {
+ QDict *qdict;
+
+ g_assert(qobject_type(entry->value) == QTYPE_QDICT);
+ qdict = qobject_to_qdict(entry->value);
+ g_assert_cmpint(qdict_size(qdict), ==, 3);
+ g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int);
+ g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
+ g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
+ i++;
+ }
+ g_assert_cmpint(i, ==, max_items);
+
+ QDECREF(qlist);
+
+ for (p = head; p;) {
+ TestStructList *tmp = p->next;
+ g_free(p->value);
+ g_free(p);
+ p = tmp;
+ }
+}
+
+static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
+ const void *unused)
+{
+ UserDefNestedList *p, *head = NULL;
+ const char string[] = "foo bar";
+ int i, max_count = 1024;
+
+ for (i = 0; i < max_count; i++) {
+ p = g_malloc0(sizeof(*p));
+ p->value = g_malloc0(sizeof(*p->value));
+
+ p->value->string0 = g_strdup(string);
+ p->value->dict1.string1 = g_strdup(string);
+ p->value->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
+ p->value->dict1.dict2.userdef1->string = g_strdup(string);
+ p->value->dict1.dict2.userdef1->integer = 42;
+ p->value->dict1.dict2.string2 = g_strdup(string);
+ p->value->dict1.has_dict3 = false;
+
+ p->next = head;
+ head = p;
+ }
+
+ qapi_free_UserDefNestedList(head);
+}
+
+static void output_visitor_test_add(const char *testpath,
+ TestOutputVisitorData *data,
+ void (*test_func)(TestOutputVisitorData *data, const void *user_data))
+{
+ g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup,
+ test_func, visitor_output_teardown);
+}
+
+int main(int argc, char **argv)
+{
+ TestOutputVisitorData out_visitor_data;
+
+ g_test_init(&argc, &argv, NULL);
+
+ output_visitor_test_add("/visitor/output/int",
+ &out_visitor_data, test_visitor_out_int);
+ output_visitor_test_add("/visitor/output/bool",
+ &out_visitor_data, test_visitor_out_bool);
+ output_visitor_test_add("/visitor/output/number",
+ &out_visitor_data, test_visitor_out_number);
+ output_visitor_test_add("/visitor/output/string",
+ &out_visitor_data, test_visitor_out_string);
+ output_visitor_test_add("/visitor/output/no-string",
+ &out_visitor_data, test_visitor_out_no_string);
+ output_visitor_test_add("/visitor/output/enum",
+ &out_visitor_data, test_visitor_out_enum);
+ output_visitor_test_add("/visitor/output/enum-errors",
+ &out_visitor_data, test_visitor_out_enum_errors);
+ output_visitor_test_add("/visitor/output/struct",
+ &out_visitor_data, test_visitor_out_struct);
+ output_visitor_test_add("/visitor/output/struct-nested",
+ &out_visitor_data, test_visitor_out_struct_nested);
+ output_visitor_test_add("/visitor/output/list",
+ &out_visitor_data, test_visitor_out_list);
+ output_visitor_test_add("/visitor/output/list-qapi-free",
+ &out_visitor_data, test_visitor_out_list_qapi_free);
+
+ g_test_run();
+
+ return 0;
+}
--
1.7.8.dirty
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 3/4] Introduce test-qmp-input-visitor
2011-12-05 14:45 [Qemu-devel] [PATCH v2 0/4]: Improve QMP visitor unit-tests Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 1/4] configure: Don't mix glib and libcheck tests Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 2/4] Introduce test-qmp-output-visitor Luiz Capitulino
@ 2011-12-05 14:45 ` Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 4/4] Drop test-visitor Luiz Capitulino
3 siblings, 0 replies; 5+ messages in thread
From: Luiz Capitulino @ 2011-12-05 14:45 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, mdroth
Contains unit-tests for the QMP input visitor implementation.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
Makefile | 5 +-
configure | 2 +-
test-qmp-input-visitor.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 275 insertions(+), 2 deletions(-)
create mode 100644 test-qmp-input-visitor.c
diff --git a/Makefile b/Makefile
index 206854a..c4884fc 100644
--- a/Makefile
+++ b/Makefile
@@ -169,7 +169,7 @@ test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y)
$(qapi-obj-y): $(GENERATED_HEADERS)
qapi-dir := $(BUILD_DIR)/qapi-generated
-test-qmp-output-visitor.o test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
+test-qmp-input-visitor.o test-qmp-output-visitor.o test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
$(qapi-dir)/test-qapi-types.c $(qapi-dir)/test-qapi-types.h :\
@@ -208,6 +208,9 @@ test-visitor: test-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qap
test-qmp-output-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
test-qmp-output-visitor: test-qmp-output-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+test-qmp-input-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
+test-qmp-input-visitor: test-qmp-input-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+
test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y)
test-qmp-commands: test-qmp-commands.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
diff --git a/configure b/configure
index ad403f7..4a958e2 100755
--- a/configure
+++ b/configure
@@ -2744,7 +2744,7 @@ if test "$softmmu" = yes ; then
checks="check-qint check-qstring check-qdict check-qlist"
checks="check-qfloat check-qjson $checks"
fi
- test_progs="$checks test-coroutine test-qmp-output-visitor"
+ test_progs="$checks test-coroutine test-qmp-output-visitor test-qmp-input-visitor"
fi
fi
diff --git a/test-qmp-input-visitor.c b/test-qmp-input-visitor.c
new file mode 100644
index 0000000..1f3ab03
--- /dev/null
+++ b/test-qmp-input-visitor.c
@@ -0,0 +1,270 @@
+/*
+ * QMP Input Visitor unit-tests.
+ *
+ * Copyright (C) 2011 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <stdarg.h>
+
+#include "qapi/qmp-input-visitor.h"
+#include "test-qapi-types.h"
+#include "test-qapi-visit.h"
+#include "qemu-objects.h"
+
+typedef struct TestInputVisitorData {
+ QObject *obj;
+ QmpInputVisitor *qiv;
+} TestInputVisitorData;
+
+static void visitor_input_teardown(TestInputVisitorData *data,
+ const void *unused)
+{
+ qobject_decref(data->obj);
+ data->obj = NULL;
+
+ if (data->qiv) {
+ qmp_input_visitor_cleanup(data->qiv);
+ data->qiv = NULL;
+ }
+}
+
+/* This is provided instead of a test setup function so that the JSON
+ string used by the tests are kept in the test functions (and not
+ int main()) */
+static Visitor *visitor_input_test_init(TestInputVisitorData *data,
+ const char *json_string, ...)
+{
+ Visitor *v;
+ va_list ap;
+
+ va_start(ap, json_string);
+ data->obj = qobject_from_jsonv(json_string, &ap);
+ va_end(ap);
+
+ g_assert(data->obj != NULL);
+
+ data->qiv = qmp_input_visitor_new(data->obj);
+ g_assert(data->qiv != NULL);
+
+ v = qmp_input_get_visitor(data->qiv);
+ g_assert(v != NULL);
+
+ return v;
+}
+
+static void test_visitor_in_int(TestInputVisitorData *data,
+ const void *unused)
+{
+ int64_t res = 0, value = -42;
+ Error *errp = NULL;
+ Visitor *v;
+
+ v = visitor_input_test_init(data, "%d", value);
+
+ visit_type_int(v, &res, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ g_assert_cmpint(res, ==, value);
+}
+
+static void test_visitor_in_bool(TestInputVisitorData *data,
+ const void *unused)
+{
+ Error *errp = NULL;
+ bool res = false;
+ Visitor *v;
+
+ v = visitor_input_test_init(data, "true");
+
+ visit_type_bool(v, &res, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ g_assert_cmpint(res, ==, true);
+}
+
+static void test_visitor_in_number(TestInputVisitorData *data,
+ const void *unused)
+{
+ double res = 0, value = 3.14;
+ Error *errp = NULL;
+ Visitor *v;
+
+ v = visitor_input_test_init(data, "%f", value);
+
+ visit_type_number(v, &res, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ g_assert_cmpfloat(res, ==, value);
+}
+
+static void test_visitor_in_string(TestInputVisitorData *data,
+ const void *unused)
+{
+ char *res = NULL, *value = (char *) "Q E M U";
+ Error *errp = NULL;
+ Visitor *v;
+
+ v = visitor_input_test_init(data, "%s", value);
+
+ visit_type_str(v, &res, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ g_assert_cmpstr(res, ==, value);
+
+ g_free(res);
+}
+
+static void test_visitor_in_enum(TestInputVisitorData *data,
+ const void *unused)
+{
+ Error *errp = NULL;
+ Visitor *v;
+ EnumOne i;
+
+ for (i = 0; EnumOne_lookup[i]; i++) {
+ EnumOne res = -1;
+
+ v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
+
+ visit_type_EnumOne(v, &res, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ g_assert_cmpint(i, ==, res);
+
+ visitor_input_teardown(data, NULL);
+ }
+
+ data->obj = NULL;
+ data->qiv = NULL;
+}
+
+typedef struct TestStruct
+{
+ int64_t integer;
+ bool boolean;
+ char *string;
+} TestStruct;
+
+static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
+ const char *name, Error **errp)
+{
+ visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
+ errp);
+
+ visit_type_int(v, &(*obj)->integer, "integer", errp);
+ visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
+ visit_type_str(v, &(*obj)->string, "string", errp);
+
+ visit_end_struct(v, errp);
+}
+
+static void test_visitor_in_struct(TestInputVisitorData *data,
+ const void *unused)
+{
+ TestStruct *p = NULL;
+ Error *errp = NULL;
+ Visitor *v;
+
+ v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
+
+ visit_type_TestStruct(v, &p, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ g_assert_cmpint(p->integer, ==, -42);
+ g_assert(p->boolean == true);
+ g_assert_cmpstr(p->string, ==, "foo");
+
+ g_free(p->string);
+ g_free(p);
+}
+
+static void check_and_free_str(char *str, const char *cmp)
+{
+ g_assert_cmpstr(str, ==, cmp);
+ g_free(str);
+}
+
+static void test_visitor_in_struct_nested(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefNested *udp = NULL;
+ Error *errp = NULL;
+ Visitor *v;
+
+ v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
+
+ visit_type_UserDefNested(v, &udp, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+
+ check_and_free_str(udp->string0, "string0");
+ check_and_free_str(udp->dict1.string1, "string1");
+ g_assert_cmpint(udp->dict1.dict2.userdef1->integer, ==, 42);
+ check_and_free_str(udp->dict1.dict2.userdef1->string, "string");
+ check_and_free_str(udp->dict1.dict2.string2, "string2");
+ g_assert(udp->dict1.has_dict3 == false);
+
+ g_free(udp->dict1.dict2.userdef1);
+ g_free(udp);
+}
+
+static void test_visitor_in_list(TestInputVisitorData *data,
+ const void *unused)
+{
+ UserDefOneList *item, *head = NULL;
+ Error *errp = NULL;
+ Visitor *v;
+ int i;
+
+ v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
+
+ visit_type_UserDefOneList(v, &head, NULL, &errp);
+ g_assert(!error_is_set(&errp));
+ g_assert(head != NULL);
+
+ for (i = 0, item = head; item; item = item->next, i++) {
+ char string[12];
+
+ snprintf(string, sizeof(string), "string%d", i);
+ g_assert_cmpstr(item->value->string, ==, string);
+ g_assert_cmpint(item->value->integer, ==, 42 + i);
+ }
+
+ qapi_free_UserDefOneList(head);
+}
+
+static void input_visitor_test_add(const char *testpath,
+ TestInputVisitorData *data,
+ void (*test_func)(TestInputVisitorData *data, const void *user_data))
+{
+ g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
+ visitor_input_teardown);
+}
+
+int main(int argc, char **argv)
+{
+ TestInputVisitorData in_visitor_data;
+
+ g_test_init(&argc, &argv, NULL);
+
+ input_visitor_test_add("/visitor/input/int",
+ &in_visitor_data, test_visitor_in_int);
+ input_visitor_test_add("/visitor/input/bool",
+ &in_visitor_data, test_visitor_in_bool);
+ input_visitor_test_add("/visitor/input/number",
+ &in_visitor_data, test_visitor_in_number);
+ input_visitor_test_add("/visitor/input/string",
+ &in_visitor_data, test_visitor_in_string);
+ input_visitor_test_add("/visitor/input/enum",
+ &in_visitor_data, test_visitor_in_enum);
+ input_visitor_test_add("/visitor/input/struct",
+ &in_visitor_data, test_visitor_in_struct);
+ input_visitor_test_add("/visitor/input/struct-nested",
+ &in_visitor_data, test_visitor_in_struct_nested);
+ input_visitor_test_add("/visitor/input/list",
+ &in_visitor_data, test_visitor_in_list);
+
+ g_test_run();
+
+ return 0;
+}
--
1.7.8.dirty
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 4/4] Drop test-visitor
2011-12-05 14:45 [Qemu-devel] [PATCH v2 0/4]: Improve QMP visitor unit-tests Luiz Capitulino
` (2 preceding siblings ...)
2011-12-05 14:45 ` [Qemu-devel] [PATCH 3/4] Introduce test-qmp-input-visitor Luiz Capitulino
@ 2011-12-05 14:45 ` Luiz Capitulino
3 siblings, 0 replies; 5+ messages in thread
From: Luiz Capitulino @ 2011-12-05 14:45 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, mdroth
It has been superseded by the two previous commits, which introduced
the test-qmp-output-visitor and test-qmp-input-visitor tests.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
Makefile | 5 +-
test-visitor.c | 338 --------------------------------------------------------
2 files changed, 1 insertions(+), 342 deletions(-)
delete mode 100644 test-visitor.c
diff --git a/Makefile b/Makefile
index c4884fc..2c03055 100644
--- a/Makefile
+++ b/Makefile
@@ -169,7 +169,7 @@ test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y)
$(qapi-obj-y): $(GENERATED_HEADERS)
qapi-dir := $(BUILD_DIR)/qapi-generated
-test-qmp-input-visitor.o test-qmp-output-visitor.o test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
+test-qmp-input-visitor.o test-qmp-output-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
$(qapi-dir)/test-qapi-types.c $(qapi-dir)/test-qapi-types.h :\
@@ -202,9 +202,6 @@ qmp-commands.h qmp-marshal.c :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -m -o "." < $<, " GEN $@")
-test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
-test-visitor: test-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
-
test-qmp-output-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
test-qmp-output-visitor: test-qmp-output-visitor.o $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
diff --git a/test-visitor.c b/test-visitor.c
deleted file mode 100644
index 847ce14..0000000
--- a/test-visitor.c
+++ /dev/null
@@ -1,338 +0,0 @@
-#include <glib.h>
-#include "qapi/qmp-output-visitor.h"
-#include "qapi/qmp-input-visitor.h"
-#include "test-qapi-types.h"
-#include "test-qapi-visit.h"
-#include "qemu-objects.h"
-
-typedef struct TestStruct
-{
- int64_t x;
- int64_t y;
-} TestStruct;
-
-typedef struct TestStructList
-{
- TestStruct *value;
- struct TestStructList *next;
-} TestStructList;
-
-static void visit_type_TestStruct(Visitor *v, TestStruct **obj, const char *name, Error **errp)
-{
- visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct), errp);
- visit_type_int(v, &(*obj)->x, "x", errp);
- visit_type_int(v, &(*obj)->y, "y", errp);
- visit_end_struct(v, errp);
-}
-
-static void visit_type_TestStructList(Visitor *m, TestStructList ** obj, const char *name, Error **errp)
-{
- GenericList *i, **head = (GenericList **)obj;
-
- visit_start_list(m, name, errp);
-
- for (*head = i = visit_next_list(m, head, errp); i; i = visit_next_list(m, &i, errp)) {
- TestStructList *native_i = (TestStructList *)i;
- visit_type_TestStruct(m, &native_i->value, NULL, errp);
- }
-
- visit_end_list(m, errp);
-}
-
-/* test core visitor methods */
-static void test_visitor_core(void)
-{
- QmpOutputVisitor *mo;
- QmpInputVisitor *mi;
- Visitor *v;
- TestStruct ts = { 42, 82 };
- TestStruct *pts = &ts;
- TestStructList *lts = NULL;
- Error *err = NULL;
- QObject *obj;
- QList *qlist;
- QDict *qdict;
- QString *str;
- int64_t value = 0;
-
- mo = qmp_output_visitor_new();
- v = qmp_output_get_visitor(mo);
-
- visit_type_TestStruct(v, &pts, NULL, &err);
-
- obj = qmp_output_get_qobject(mo);
-
- str = qobject_to_json(obj);
-
- printf("%s\n", qstring_get_str(str));
-
- QDECREF(str);
-
- obj = QOBJECT(qint_from_int(0x42));
-
- mi = qmp_input_visitor_new(obj);
- v = qmp_input_get_visitor(mi);
-
- visit_type_int(v, &value, NULL, &err);
- if (err) {
- g_error("%s", error_get_pretty(err));
- }
-
- g_assert(value == 0x42);
-
- qobject_decref(obj);
-
- obj = qobject_from_json("{'x': 42, 'y': 84}");
- mi = qmp_input_visitor_new(obj);
- v = qmp_input_get_visitor(mi);
-
- pts = NULL;
-
- visit_type_TestStruct(v, &pts, NULL, &err);
- if (err) {
- g_error("%s", error_get_pretty(err));
- }
-
- g_assert(pts != NULL);
- g_assert(pts->x == 42);
- g_assert(pts->y == 84);
-
- qobject_decref(obj);
- g_free(pts);
-
- /* test list input visitor */
- obj = qobject_from_json("[{'x': 42, 'y': 84}, {'x': 12, 'y': 24}]");
- mi = qmp_input_visitor_new(obj);
- v = qmp_input_get_visitor(mi);
-
- visit_type_TestStructList(v, <s, NULL, &err);
- if (err) {
- g_error("%s", error_get_pretty(err));
- }
-
- g_assert(lts != NULL);
- g_assert(lts->value->x == 42);
- g_assert(lts->value->y == 84);
-
- g_assert(lts->next != NULL);
- g_assert(lts->next->value->x == 12);
- g_assert(lts->next->value->y == 24);
- g_assert(lts->next->next == NULL);
-
- qobject_decref(obj);
-
- /* test list output visitor */
- mo = qmp_output_visitor_new();
- v = qmp_output_get_visitor(mo);
- visit_type_TestStructList(v, <s, NULL, &err);
- if (err) {
- g_error("%s", error_get_pretty(err));
- }
- obj = qmp_output_get_qobject(mo);
- g_print("obj: %s\n", qstring_get_str(qobject_to_json(obj)));
-
- qlist = qobject_to_qlist(obj);
- assert(qlist);
- obj = qlist_pop(qlist);
- qdict = qobject_to_qdict(obj);
- assert(qdict);
- assert(qdict_get_int(qdict, "x") == 42);
- assert(qdict_get_int(qdict, "y") == 84);
- qobject_decref(obj);
-
- obj = qlist_pop(qlist);
- qdict = qobject_to_qdict(obj);
- assert(qdict);
- assert(qdict_get_int(qdict, "x") == 12);
- assert(qdict_get_int(qdict, "y") == 24);
- qobject_decref(obj);
-
- qmp_output_visitor_cleanup(mo);
- QDECREF(qlist);
-}
-
-/* test deep nesting with refs to other user-defined types */
-static void test_nested_structs(void)
-{
- QmpOutputVisitor *mo;
- QmpInputVisitor *mi;
- Visitor *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_visitor_new();
- v = qmp_output_get_visitor(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_visitor_new();
- v = qmp_output_get_visitor(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_visitor_new(obj);
- v = qmp_input_get_visitor(mi);
- visit_type_UserDefTwo(v, &ud2c_p, NULL, &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));
-
- 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));
- g_free(ud1.string);
- g_free(ud2.string);
- g_free(ud2.dict.string);
- g_free(ud2.dict.dict.string);
- g_free(ud2.dict.dict2.string);
-
- qapi_free_UserDefTwo(ud2c_p);
-
- qobject_decref(obj);
-}
-
-/* test enum values */
-static void test_enums(void)
-{
- QmpOutputVisitor *mo;
- QmpInputVisitor *mi;
- Visitor *v;
- EnumOne enum1 = ENUM_ONE_VALUE2, enum1_cpy = ENUM_ONE_VALUE1;
- Error *err = NULL;
- QObject *obj;
- QString *str;
-
- /* C type -> QObject */
- mo = qmp_output_visitor_new();
- v = qmp_output_get_visitor(mo);
- visit_type_EnumOne(v, &enum1, "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);
- g_assert(g_strcmp0(qstring_get_str(qobject_to_qstring(obj)), "value2") == 0);
-
- /* QObject -> C type */
- mi = qmp_input_visitor_new(obj);
- v = qmp_input_get_visitor(mi);
- visit_type_EnumOne(v, &enum1_cpy, "unused", &err);
- if (err) {
- g_error("%s", error_get_pretty(err));
- }
- g_debug("enum1_cpy, enum1: %d, %d", enum1_cpy, enum1);
- g_assert(enum1_cpy == enum1);
-
- qobject_decref(obj);
-}
-
-/* test enum values nested in schema-defined structs */
-static void test_nested_enums(void)
-{
- QmpOutputVisitor *mo;
- QmpInputVisitor *mi;
- Visitor *v;
- NestedEnumsOne *nested_enums, *nested_enums_cpy = NULL;
- Error *err = NULL;
- QObject *obj;
- QString *str;
-
- nested_enums = g_malloc0(sizeof(NestedEnumsOne));
- nested_enums->enum1 = ENUM_ONE_VALUE1;
- nested_enums->enum2 = ENUM_ONE_VALUE2;
- nested_enums->enum3 = ENUM_ONE_VALUE3;
- nested_enums->enum4 = ENUM_ONE_VALUE3;
- nested_enums->has_enum2 = false;
- nested_enums->has_enum4 = true;
-
- /* C type -> QObject */
- mo = qmp_output_visitor_new();
- v = qmp_output_get_visitor(mo);
- visit_type_NestedEnumsOne(v, &nested_enums, NULL, &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 */
- mi = qmp_input_visitor_new(obj);
- v = qmp_input_get_visitor(mi);
- visit_type_NestedEnumsOne(v, &nested_enums_cpy, NULL, &err);
- if (err) {
- g_error("%s", error_get_pretty(err));
- }
- g_assert(nested_enums_cpy);
- g_assert(nested_enums_cpy->enum1 == nested_enums->enum1);
- g_assert(nested_enums_cpy->enum3 == nested_enums->enum3);
- g_assert(nested_enums_cpy->enum4 == nested_enums->enum4);
- g_assert(nested_enums_cpy->has_enum2 == false);
- g_assert(nested_enums_cpy->has_enum4 == true);
-
- qmp_output_visitor_cleanup(mo);
- qmp_input_visitor_cleanup(mi);
- qapi_free_NestedEnumsOne(nested_enums);
- qapi_free_NestedEnumsOne(nested_enums_cpy);
-}
-
-int main(int argc, char **argv)
-{
- g_test_init(&argc, &argv, NULL);
-
- g_test_add_func("/0.15/visitor_core", test_visitor_core);
- g_test_add_func("/0.15/nested_structs", test_nested_structs);
- g_test_add_func("/0.15/enums", test_enums);
- g_test_add_func("/0.15/nested_enums", test_nested_enums);
-
- g_test_run();
-
- return 0;
-}
--
1.7.8.dirty
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-12-05 14:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-05 14:45 [Qemu-devel] [PATCH v2 0/4]: Improve QMP visitor unit-tests Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 1/4] configure: Don't mix glib and libcheck tests Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 2/4] Introduce test-qmp-output-visitor Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 3/4] Introduce test-qmp-input-visitor Luiz Capitulino
2011-12-05 14:45 ` [Qemu-devel] [PATCH 4/4] Drop test-visitor Luiz Capitulino
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).