For every QOM type returned by qom-list-types, call qom-list-properties and verify that each property's qapi-type value (when present) maps to a valid entry in the query-qmp-schema introspection output.
The test is gated behind g_test_slow() since it iterates all registered QOM types. Signed-off-by: Marc-André Lureau <[email protected]> --- tests/qtest/qmp-cmd-test.c | 55 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c index 279a8f5614e9..acb7b0dd6a9f 100644 --- a/tests/qtest/qmp-cmd-test.c +++ b/tests/qtest/qmp-cmd-test.c @@ -15,6 +15,7 @@ #include "qapi/error.h" #include "qapi/qapi-visit-introspect.h" #include "qobject/qdict.h" +#include "qobject/qlist.h" #include "qapi/qobject-input-visitor.h" const char common_args[] = "-nodefaults -machine none"; @@ -131,6 +132,8 @@ typedef struct { GHashTable *hash; } QmpSchema; +static QmpSchema schema; + static void qmp_schema_init(QmpSchema *schema) { QDict *resp; @@ -343,9 +346,56 @@ static void test_object_add_failure_modes(void) qtest_quit(qts); } +static void test_qapi_type(void) +{ + QTestState *qts; + g_autoptr(QDict) resp = NULL; + QList *types; + QListEntry *type_entry, *prop_entry; + + qts = qtest_init(common_args); + + resp = qtest_qmp(qts, + "{ 'execute': 'qom-list-types'," + " 'arguments': { 'abstract': true } }"); + g_assert(qdict_haskey(resp, "return")); + types = qdict_get_qlist(resp, "return"); + + QLIST_FOREACH_ENTRY(types, type_entry) { + QDict *type = qobject_to(QDict, qlist_entry_obj(type_entry)); + const char *name = qdict_get_str(type, "name"); + g_autoptr(QDict) props_resp = NULL; + QList *props; + + props_resp = qtest_qmp(qts, + "{ 'execute': 'qom-list-properties'," + " 'arguments': { 'typename': %s } }", + name); + if (!qdict_haskey(props_resp, "return")) { + continue; + } + props = qdict_get_qlist(props_resp, "return"); + + QLIST_FOREACH_ENTRY(props, prop_entry) { + QDict *prop = qobject_to(QDict, qlist_entry_obj(prop_entry)); + const char *qapi_type = qdict_get_try_str(prop, "qapi-type"); + const char *propname = qdict_get_str(prop, "name"); + const char *ty = qdict_get_str(prop, "type"); + + if (qapi_type) { + g_assert_nonnull(qmp_schema_lookup(&schema, qapi_type)); + } else if (!g_str_has_prefix(ty, "child<") && + !g_str_has_prefix(ty, "link<")) { + g_test_message("%s.%s %s has no associated qapi-type", + name, propname, ty); + } + } + } + qtest_quit(qts); +} + int main(int argc, char *argv[]) { - QmpSchema schema; int ret; g_test_init(&argc, &argv, NULL); @@ -355,6 +405,9 @@ int main(int argc, char *argv[]) qtest_add_func("qmp/object-add-failure-modes", test_object_add_failure_modes); + if (g_test_slow()) { + qtest_add_func("qmp/qapi-type", test_qapi_type); + } ret = g_test_run(); -- 2.55.0.543.g5ebe2ebe4ea8
