1d93bb9d5SMarkus Armbruster /* 2d93bb9d5SMarkus Armbruster * QMP command test cases 3d93bb9d5SMarkus Armbruster * 4d93bb9d5SMarkus Armbruster * Copyright (c) 2017 Red Hat Inc. 5d93bb9d5SMarkus Armbruster * 6d93bb9d5SMarkus Armbruster * Authors: 7d93bb9d5SMarkus Armbruster * Markus Armbruster <armbru@redhat.com> 8d93bb9d5SMarkus Armbruster * 9d93bb9d5SMarkus Armbruster * This work is licensed under the terms of the GNU GPL, version 2 or later. 10d93bb9d5SMarkus Armbruster * See the COPYING file in the top-level directory. 11d93bb9d5SMarkus Armbruster */ 12d93bb9d5SMarkus Armbruster 13d93bb9d5SMarkus Armbruster #include "qemu/osdep.h" 14907b5105SMarc-André Lureau #include "libqtest.h" 15d93bb9d5SMarkus Armbruster #include "qapi/error.h" 16d93bb9d5SMarkus Armbruster #include "qapi/qapi-visit-introspect.h" 17d93bb9d5SMarkus Armbruster #include "qapi/qmp/qdict.h" 18d93bb9d5SMarkus Armbruster #include "qapi/qobject-input-visitor.h" 19d93bb9d5SMarkus Armbruster 20d93bb9d5SMarkus Armbruster const char common_args[] = "-nodefaults -machine none"; 21d93bb9d5SMarkus Armbruster 22d93bb9d5SMarkus Armbruster /* Query smoke tests */ 23d93bb9d5SMarkus Armbruster 24d93bb9d5SMarkus Armbruster static int query_error_class(const char *cmd) 25d93bb9d5SMarkus Armbruster { 26d93bb9d5SMarkus Armbruster static struct { 27d93bb9d5SMarkus Armbruster const char *cmd; 28d93bb9d5SMarkus Armbruster int err_class; 29d93bb9d5SMarkus Armbruster } fails[] = { 30d93bb9d5SMarkus Armbruster /* Success depends on build configuration: */ 31d93bb9d5SMarkus Armbruster #ifndef CONFIG_SPICE 32d93bb9d5SMarkus Armbruster { "query-spice", ERROR_CLASS_COMMAND_NOT_FOUND }, 33d93bb9d5SMarkus Armbruster #endif 349b1c9116SClaudio Fontana #ifndef CONFIG_TCG 359b1c9116SClaudio Fontana { "query-replay", ERROR_CLASS_COMMAND_NOT_FOUND }, 369b1c9116SClaudio Fontana #endif 37d93bb9d5SMarkus Armbruster #ifndef CONFIG_VNC 38d93bb9d5SMarkus Armbruster { "query-vnc", ERROR_CLASS_GENERIC_ERROR }, 39d93bb9d5SMarkus Armbruster { "query-vnc-servers", ERROR_CLASS_GENERIC_ERROR }, 40d93bb9d5SMarkus Armbruster #endif 41d93bb9d5SMarkus Armbruster #ifndef CONFIG_REPLICATION 42d93bb9d5SMarkus Armbruster { "query-xen-replication-status", ERROR_CLASS_COMMAND_NOT_FOUND }, 43d93bb9d5SMarkus Armbruster #endif 44d93bb9d5SMarkus Armbruster /* Likewise, and require special QEMU command-line arguments: */ 45d93bb9d5SMarkus Armbruster { "query-acpi-ospm-status", ERROR_CLASS_GENERIC_ERROR }, 46d93bb9d5SMarkus Armbruster { "query-balloon", ERROR_CLASS_DEVICE_NOT_ACTIVE }, 47d93bb9d5SMarkus Armbruster { "query-hotpluggable-cpus", ERROR_CLASS_GENERIC_ERROR }, 48d93bb9d5SMarkus Armbruster { "query-vm-generation-id", ERROR_CLASS_GENERIC_ERROR }, 4937087fdeSDaniel P. Berrangé #ifndef CONFIG_PROFILER 5037087fdeSDaniel P. Berrangé { "x-query-profile", ERROR_CLASS_GENERIC_ERROR }, 5137087fdeSDaniel P. Berrangé #endif 52fc309207SDaniel P. Berrangé /* Only valid with a USB bus added */ 53fc309207SDaniel P. Berrangé { "x-query-usb", ERROR_CLASS_GENERIC_ERROR }, 543a841ab5SDaniel P. Berrangé /* Only valid with accel=tcg */ 553a841ab5SDaniel P. Berrangé { "x-query-jit", ERROR_CLASS_GENERIC_ERROR }, 56b6a7f3e0SDaniel P. Berrangé { "x-query-opcount", ERROR_CLASS_GENERIC_ERROR }, 57*507cb64dSJoao Martins { "xen-event-list", ERROR_CLASS_GENERIC_ERROR }, 58d93bb9d5SMarkus Armbruster { NULL, -1 } 59d93bb9d5SMarkus Armbruster }; 60d93bb9d5SMarkus Armbruster int i; 61d93bb9d5SMarkus Armbruster 62d93bb9d5SMarkus Armbruster for (i = 0; fails[i].cmd; i++) { 63d93bb9d5SMarkus Armbruster if (!strcmp(cmd, fails[i].cmd)) { 64d93bb9d5SMarkus Armbruster return fails[i].err_class; 65d93bb9d5SMarkus Armbruster } 66d93bb9d5SMarkus Armbruster } 67d93bb9d5SMarkus Armbruster return -1; 68d93bb9d5SMarkus Armbruster } 69d93bb9d5SMarkus Armbruster 70d93bb9d5SMarkus Armbruster static void test_query(const void *data) 71d93bb9d5SMarkus Armbruster { 72d93bb9d5SMarkus Armbruster const char *cmd = data; 73d93bb9d5SMarkus Armbruster int expected_error_class = query_error_class(cmd); 74d93bb9d5SMarkus Armbruster QDict *resp, *error; 75d93bb9d5SMarkus Armbruster const char *error_class; 76da9cd2d0SThomas Huth QTestState *qts; 77d93bb9d5SMarkus Armbruster 78da9cd2d0SThomas Huth qts = qtest_init(common_args); 79d93bb9d5SMarkus Armbruster 80da9cd2d0SThomas Huth resp = qtest_qmp(qts, "{ 'execute': %s }", cmd); 81d93bb9d5SMarkus Armbruster error = qdict_get_qdict(resp, "error"); 82d93bb9d5SMarkus Armbruster error_class = error ? qdict_get_str(error, "class") : NULL; 83d93bb9d5SMarkus Armbruster 84d93bb9d5SMarkus Armbruster if (expected_error_class < 0) { 85d93bb9d5SMarkus Armbruster g_assert(qdict_haskey(resp, "return")); 86d93bb9d5SMarkus Armbruster } else { 87d93bb9d5SMarkus Armbruster g_assert(error); 88d93bb9d5SMarkus Armbruster g_assert_cmpint(qapi_enum_parse(&QapiErrorClass_lookup, error_class, 89d93bb9d5SMarkus Armbruster -1, &error_abort), 90d93bb9d5SMarkus Armbruster ==, expected_error_class); 91d93bb9d5SMarkus Armbruster } 92d93bb9d5SMarkus Armbruster qobject_unref(resp); 93d93bb9d5SMarkus Armbruster 94da9cd2d0SThomas Huth qtest_quit(qts); 95d93bb9d5SMarkus Armbruster } 96d93bb9d5SMarkus Armbruster 97d97b4b0dSThomas Huth static bool query_is_ignored(const char *cmd) 98d93bb9d5SMarkus Armbruster { 99d97b4b0dSThomas Huth const char *ignored[] = { 100d93bb9d5SMarkus Armbruster /* Not actually queries: */ 101d93bb9d5SMarkus Armbruster "add-fd", 102d93bb9d5SMarkus Armbruster /* Success depends on target arch: */ 103d93bb9d5SMarkus Armbruster "query-cpu-definitions", /* arm, i386, ppc, s390x */ 104d93bb9d5SMarkus Armbruster "query-gic-capabilities", /* arm */ 105d93bb9d5SMarkus Armbruster /* Success depends on target-specific build configuration: */ 106d93bb9d5SMarkus Armbruster "query-pci", /* CONFIG_PCI */ 107a5ebce38SLaurent Vivier "x-query-virtio", /* CONFIG_VIRTIO */ 108d93bb9d5SMarkus Armbruster /* Success depends on launching SEV guest */ 109d93bb9d5SMarkus Armbruster "query-sev-launch-measure", 110d93bb9d5SMarkus Armbruster /* Success depends on Host or Hypervisor SEV support */ 111d93bb9d5SMarkus Armbruster "query-sev", 112d93bb9d5SMarkus Armbruster "query-sev-capabilities", 11357d874c4SYang Zhong "query-sgx", 1140205c4faSYang Zhong "query-sgx-capabilities", 115f3b2e38cSHyman Huang(黄勇) /* Success depends on enabling dirty page rate limit */ 116f3b2e38cSHyman Huang(黄勇) "query-vcpu-dirty-limit", 117d93bb9d5SMarkus Armbruster NULL 118d93bb9d5SMarkus Armbruster }; 119d93bb9d5SMarkus Armbruster int i; 120d93bb9d5SMarkus Armbruster 121d97b4b0dSThomas Huth for (i = 0; ignored[i]; i++) { 122d97b4b0dSThomas Huth if (!strcmp(cmd, ignored[i])) { 123d93bb9d5SMarkus Armbruster return true; 124d93bb9d5SMarkus Armbruster } 125d93bb9d5SMarkus Armbruster } 126d93bb9d5SMarkus Armbruster return false; 127d93bb9d5SMarkus Armbruster } 128d93bb9d5SMarkus Armbruster 129d93bb9d5SMarkus Armbruster typedef struct { 130d93bb9d5SMarkus Armbruster SchemaInfoList *list; 131d93bb9d5SMarkus Armbruster GHashTable *hash; 132d93bb9d5SMarkus Armbruster } QmpSchema; 133d93bb9d5SMarkus Armbruster 134d93bb9d5SMarkus Armbruster static void qmp_schema_init(QmpSchema *schema) 135d93bb9d5SMarkus Armbruster { 136d93bb9d5SMarkus Armbruster QDict *resp; 137d93bb9d5SMarkus Armbruster Visitor *qiv; 138d93bb9d5SMarkus Armbruster SchemaInfoList *tail; 139da9cd2d0SThomas Huth QTestState *qts; 140d93bb9d5SMarkus Armbruster 141da9cd2d0SThomas Huth qts = qtest_init(common_args); 142da9cd2d0SThomas Huth 143da9cd2d0SThomas Huth resp = qtest_qmp(qts, "{ 'execute': 'query-qmp-schema' }"); 144d93bb9d5SMarkus Armbruster 145d93bb9d5SMarkus Armbruster qiv = qobject_input_visitor_new(qdict_get(resp, "return")); 146d93bb9d5SMarkus Armbruster visit_type_SchemaInfoList(qiv, NULL, &schema->list, &error_abort); 147d93bb9d5SMarkus Armbruster visit_free(qiv); 148d93bb9d5SMarkus Armbruster 149d93bb9d5SMarkus Armbruster qobject_unref(resp); 150da9cd2d0SThomas Huth qtest_quit(qts); 151d93bb9d5SMarkus Armbruster 152d93bb9d5SMarkus Armbruster schema->hash = g_hash_table_new(g_str_hash, g_str_equal); 153d93bb9d5SMarkus Armbruster 154d93bb9d5SMarkus Armbruster /* Build @schema: hash table mapping entity name to SchemaInfo */ 155d93bb9d5SMarkus Armbruster for (tail = schema->list; tail; tail = tail->next) { 156d93bb9d5SMarkus Armbruster g_hash_table_insert(schema->hash, tail->value->name, tail->value); 157d93bb9d5SMarkus Armbruster } 158d93bb9d5SMarkus Armbruster } 159d93bb9d5SMarkus Armbruster 160d93bb9d5SMarkus Armbruster static SchemaInfo *qmp_schema_lookup(QmpSchema *schema, const char *name) 161d93bb9d5SMarkus Armbruster { 162d93bb9d5SMarkus Armbruster return g_hash_table_lookup(schema->hash, name); 163d93bb9d5SMarkus Armbruster } 164d93bb9d5SMarkus Armbruster 165d93bb9d5SMarkus Armbruster static void qmp_schema_cleanup(QmpSchema *schema) 166d93bb9d5SMarkus Armbruster { 167d93bb9d5SMarkus Armbruster qapi_free_SchemaInfoList(schema->list); 168d93bb9d5SMarkus Armbruster g_hash_table_destroy(schema->hash); 169d93bb9d5SMarkus Armbruster } 170d93bb9d5SMarkus Armbruster 171d93bb9d5SMarkus Armbruster static bool object_type_has_mandatory_members(SchemaInfo *type) 172d93bb9d5SMarkus Armbruster { 173d93bb9d5SMarkus Armbruster SchemaInfoObjectMemberList *tail; 174d93bb9d5SMarkus Armbruster 175d93bb9d5SMarkus Armbruster g_assert(type->meta_type == SCHEMA_META_TYPE_OBJECT); 176d93bb9d5SMarkus Armbruster 177d93bb9d5SMarkus Armbruster for (tail = type->u.object.members; tail; tail = tail->next) { 1784b2fc7dbSMarkus Armbruster if (!tail->value->q_default) { 179d93bb9d5SMarkus Armbruster return true; 180d93bb9d5SMarkus Armbruster } 181d93bb9d5SMarkus Armbruster } 182d93bb9d5SMarkus Armbruster 183d93bb9d5SMarkus Armbruster return false; 184d93bb9d5SMarkus Armbruster } 185d93bb9d5SMarkus Armbruster 186d93bb9d5SMarkus Armbruster static void add_query_tests(QmpSchema *schema) 187d93bb9d5SMarkus Armbruster { 188d93bb9d5SMarkus Armbruster SchemaInfoList *tail; 189d93bb9d5SMarkus Armbruster SchemaInfo *si, *arg_type, *ret_type; 190d93bb9d5SMarkus Armbruster char *test_name; 191d93bb9d5SMarkus Armbruster 192d93bb9d5SMarkus Armbruster /* Test the query-like commands */ 193d93bb9d5SMarkus Armbruster for (tail = schema->list; tail; tail = tail->next) { 194d93bb9d5SMarkus Armbruster si = tail->value; 195d93bb9d5SMarkus Armbruster if (si->meta_type != SCHEMA_META_TYPE_COMMAND) { 196d93bb9d5SMarkus Armbruster continue; 197d93bb9d5SMarkus Armbruster } 198d93bb9d5SMarkus Armbruster 199d97b4b0dSThomas Huth if (query_is_ignored(si->name)) { 200d93bb9d5SMarkus Armbruster continue; 201d93bb9d5SMarkus Armbruster } 202d93bb9d5SMarkus Armbruster 203d93bb9d5SMarkus Armbruster arg_type = qmp_schema_lookup(schema, si->u.command.arg_type); 204d93bb9d5SMarkus Armbruster if (object_type_has_mandatory_members(arg_type)) { 205d93bb9d5SMarkus Armbruster continue; 206d93bb9d5SMarkus Armbruster } 207d93bb9d5SMarkus Armbruster 208d93bb9d5SMarkus Armbruster ret_type = qmp_schema_lookup(schema, si->u.command.ret_type); 209d93bb9d5SMarkus Armbruster if (ret_type->meta_type == SCHEMA_META_TYPE_OBJECT 210d93bb9d5SMarkus Armbruster && !ret_type->u.object.members) { 211d93bb9d5SMarkus Armbruster continue; 212d93bb9d5SMarkus Armbruster } 213d93bb9d5SMarkus Armbruster 214d93bb9d5SMarkus Armbruster test_name = g_strdup_printf("qmp/%s", si->name); 215d93bb9d5SMarkus Armbruster qtest_add_data_func(test_name, si->name, test_query); 216d93bb9d5SMarkus Armbruster g_free(test_name); 217d93bb9d5SMarkus Armbruster } 218d93bb9d5SMarkus Armbruster } 219d93bb9d5SMarkus Armbruster 2205b88849eSEric Auger static void test_object_add_failure_modes(void) 221442b09b8SMarc-André Lureau { 222442b09b8SMarc-André Lureau QTestState *qts; 223442b09b8SMarc-André Lureau QDict *resp; 224442b09b8SMarc-André Lureau 2255b88849eSEric Auger /* attempt to create an object without props */ 226442b09b8SMarc-André Lureau qts = qtest_init(common_args); 227442b09b8SMarc-André Lureau resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 228442b09b8SMarc-André Lureau " {'qom-type': 'memory-backend-ram', 'id': 'ram1' } }"); 229442b09b8SMarc-André Lureau g_assert_nonnull(resp); 2303bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 231442b09b8SMarc-André Lureau 2325b88849eSEric Auger /* attempt to create an object without qom-type */ 2339fc719b8SEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 2345b88849eSEric Auger " {'id': 'ram1' } }"); 2355b88849eSEric Auger g_assert_nonnull(resp); 2363bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 2375b88849eSEric Auger 2385b88849eSEric Auger /* attempt to delete an object that does not exist */ 2395b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" 2405b88849eSEric Auger " {'id': 'ram1' } }"); 2415b88849eSEric Auger g_assert_nonnull(resp); 2423bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 2435b88849eSEric Auger 2445b88849eSEric Auger /* attempt to create 2 objects with duplicate id */ 2455b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 2465b88849eSEric Auger " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," 2479695c3afSKevin Wolf " 'size': 1048576 } }"); 2489fc719b8SEric Auger g_assert_nonnull(resp); 2499fc719b8SEric Auger g_assert(qdict_haskey(resp, "return")); 25015c51f72SLi Qiang qobject_unref(resp); 25115c51f72SLi Qiang 2529fc719b8SEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 2535b88849eSEric Auger " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," 2549695c3afSKevin Wolf " 'size': 1048576 } }"); 2559fc719b8SEric Auger g_assert_nonnull(resp); 2563bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 2575b88849eSEric Auger 2585b88849eSEric Auger /* delete ram1 object */ 2595b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" 2605b88849eSEric Auger " {'id': 'ram1' } }"); 2615b88849eSEric Auger g_assert_nonnull(resp); 2625b88849eSEric Auger g_assert(qdict_haskey(resp, "return")); 26315c51f72SLi Qiang qobject_unref(resp); 2645b88849eSEric Auger 2655b88849eSEric Auger /* attempt to create an object with a property of a wrong type */ 2665b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 2675b88849eSEric Auger " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," 2689695c3afSKevin Wolf " 'size': '1048576' } }"); 2695b88849eSEric Auger g_assert_nonnull(resp); 2705b88849eSEric Auger /* now do it right */ 2713bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 27215c51f72SLi Qiang 2735b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 2745b88849eSEric Auger " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," 2759695c3afSKevin Wolf " 'size': 1048576 } }"); 2765b88849eSEric Auger g_assert_nonnull(resp); 2775b88849eSEric Auger g_assert(qdict_haskey(resp, "return")); 27815c51f72SLi Qiang qobject_unref(resp); 2795b88849eSEric Auger 2805b88849eSEric Auger /* delete ram1 object */ 2815b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" 2825b88849eSEric Auger " {'id': 'ram1' } }"); 2835b88849eSEric Auger g_assert_nonnull(resp); 2845b88849eSEric Auger g_assert(qdict_haskey(resp, "return")); 28515c51f72SLi Qiang qobject_unref(resp); 2865b88849eSEric Auger 2875b88849eSEric Auger /* attempt to create an object without the id */ 2885b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 2895b88849eSEric Auger " {'qom-type': 'memory-backend-ram'," 2909695c3afSKevin Wolf " 'size': 1048576 } }"); 2915b88849eSEric Auger g_assert_nonnull(resp); 2923bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 29315c51f72SLi Qiang 2945b88849eSEric Auger /* now do it right */ 2955b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 2965b88849eSEric Auger " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," 2979695c3afSKevin Wolf " 'size': 1048576 } }"); 2985b88849eSEric Auger g_assert_nonnull(resp); 2995b88849eSEric Auger g_assert(qdict_haskey(resp, "return")); 30015c51f72SLi Qiang qobject_unref(resp); 3015b88849eSEric Auger 3025b88849eSEric Auger /* delete ram1 object */ 3035b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" 3045b88849eSEric Auger " {'id': 'ram1' } }"); 3055b88849eSEric Auger g_assert_nonnull(resp); 3065b88849eSEric Auger g_assert(qdict_haskey(resp, "return")); 30715c51f72SLi Qiang qobject_unref(resp); 3085b88849eSEric Auger 3095b88849eSEric Auger /* attempt to set a non existing property */ 3105b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 3115b88849eSEric Auger " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," 3129695c3afSKevin Wolf " 'sized': 1048576 } }"); 3135b88849eSEric Auger g_assert_nonnull(resp); 3143bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 31515c51f72SLi Qiang 3165b88849eSEric Auger /* now do it right */ 3175b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':" 3185b88849eSEric Auger " {'qom-type': 'memory-backend-ram', 'id': 'ram1'," 3199695c3afSKevin Wolf " 'size': 1048576 } }"); 3205b88849eSEric Auger g_assert_nonnull(resp); 3215b88849eSEric Auger g_assert(qdict_haskey(resp, "return")); 32215c51f72SLi Qiang qobject_unref(resp); 3235b88849eSEric Auger 3245b88849eSEric Auger /* delete ram1 object without id */ 3255b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" 3265b88849eSEric Auger " {'ida': 'ram1' } }"); 3275b88849eSEric Auger g_assert_nonnull(resp); 32815c51f72SLi Qiang qobject_unref(resp); 3295b88849eSEric Auger 3305b88849eSEric Auger /* delete ram1 object */ 3315b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" 3325b88849eSEric Auger " {'id': 'ram1' } }"); 3335b88849eSEric Auger g_assert_nonnull(resp); 3345b88849eSEric Auger g_assert(qdict_haskey(resp, "return")); 33515c51f72SLi Qiang qobject_unref(resp); 3365b88849eSEric Auger 3375b88849eSEric Auger /* delete ram1 object that does not exist anymore*/ 3385b88849eSEric Auger resp = qtest_qmp(qts, "{'execute': 'object-del', 'arguments':" 3395b88849eSEric Auger " {'id': 'ram1' } }"); 3405b88849eSEric Auger g_assert_nonnull(resp); 3413bc1b8eeSMarkus Armbruster qmp_expect_error_and_unref(resp, "GenericError"); 3425b88849eSEric Auger 3439fc719b8SEric Auger qtest_quit(qts); 3449fc719b8SEric Auger } 3459fc719b8SEric Auger 346d93bb9d5SMarkus Armbruster int main(int argc, char *argv[]) 347d93bb9d5SMarkus Armbruster { 348d93bb9d5SMarkus Armbruster QmpSchema schema; 349d93bb9d5SMarkus Armbruster int ret; 350d93bb9d5SMarkus Armbruster 351d93bb9d5SMarkus Armbruster g_test_init(&argc, &argv, NULL); 352d93bb9d5SMarkus Armbruster 353d93bb9d5SMarkus Armbruster qmp_schema_init(&schema); 354d93bb9d5SMarkus Armbruster add_query_tests(&schema); 355442b09b8SMarc-André Lureau 3565b88849eSEric Auger qtest_add_func("qmp/object-add-failure-modes", 3575b88849eSEric Auger test_object_add_failure_modes); 358442b09b8SMarc-André Lureau 359d93bb9d5SMarkus Armbruster ret = g_test_run(); 360d93bb9d5SMarkus Armbruster 361d93bb9d5SMarkus Armbruster qmp_schema_cleanup(&schema); 362d93bb9d5SMarkus Armbruster return ret; 363d93bb9d5SMarkus Armbruster } 364