diff --git a/tests/Makefile.am b/tests/Makefile.am index fc516376b4..f5766a7790 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -570,7 +570,7 @@ qemuxml2argvtest_SOURCES = \ testutils.c testutils.h \ virfilewrapper.c virfilewrapper.h \ $(NULL) -qemuxml2argvtest_LDADD = libqemutestdriver.la \ +qemuxml2argvtest_LDADD = libqemutestdriver.la libqemumonitortestutils.la \ $(LDADDS) $(LIBXML_LIBS) libqemuxml2argvmock_la_SOURCES = \ diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 5123580ee2..4f613e8f1a 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -18,6 +18,7 @@ # include "qemu/qemu_migration.h" # include "qemu/qemu_process.h" # include "qemu/qemu_slirp.h" +# include "qemu/qemu_qapi.h" # include "datatypes.h" # include "conf/storage_conf.h" # include "cpu/cpu_map.h" @@ -26,6 +27,8 @@ # include "virmock.h" # include "virfilewrapper.h" # include "configmake.h" +# include "testutilsqemuschema.h" +# include "qemu/qemu_monitor_json.h" # define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW # include "qemu/qemu_capspriv.h" @@ -477,6 +480,76 @@ testCompareXMLToArgvCreateArgs(virQEMUDriverPtr drv, } +static int +testCompareXMLToArgvValidateSchema(virQEMUDriverPtr drv, + virDomainObjPtr vm, + const char *migrateURI, + struct testQemuInfo *info, + unsigned int flags) +{ + VIR_AUTOSTRINGLIST args = NULL; + size_t nargs = 0; + size_t i; + g_autoptr(virHashTable) schema = NULL; + g_autoptr(virCommand) cmd = NULL; + + if (info->schemafile) + schema = testQEMUSchemaLoad(info->schemafile); + + /* comment out with line comment to enable schema checking for non _CAPS tests + if (!schema) + schema = testQEMUSchemaLoadLatest(virArchToString(info->arch)); + // */ + + if (!schema) + return 0; + + if (!(cmd = testCompareXMLToArgvCreateArgs(drv, vm, migrateURI, info, flags, + true))) + return -1; + + if (virCommandGetArgList(cmd, &args, &nargs) < 0) + return -1; + + for (i = 0; i < nargs; i++) { + g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER; + g_autoptr(virJSONValue) jsonargs = NULL; + + if (STREQ(args[i], "-blockdev")) { + if (!(jsonargs = virJSONValueFromString(args[i + 1]))) + return -1; + + if (testQEMUSchemaValidateCommand("blockdev-add", jsonargs, + schema, false, false, &debug) < 0) { + VIR_TEST_VERBOSE("failed to validate -blockdev '%s' against QAPI schema: %s", + args[i + 1], virBufferCurrentContent(&debug)); + return -1; + } + + i++; + } else if (STREQ(args[i], "-netdev")) { + if (!(jsonargs = virJSONValueFromString(args[i + 1]))) + return -1; + + /* skip the validation for pre-QAPIfication cases */ + if (virQEMUQAPISchemaPathExists("netdev_add/arg-type/type/!string", schema)) + continue; + + if (testQEMUSchemaValidateCommand("netdev_add", jsonargs, + schema, false, false, &debug) < 0) { + VIR_TEST_VERBOSE("failed to validate -netdev '%s' against QAPI schema: %s", + args[i + 1], virBufferCurrentContent(&debug)); + return -1; + } + + i++; + } + } + + return 0; +} + + static int testCompareXMLToArgv(const void *data) { @@ -578,6 +651,9 @@ testCompareXMLToArgv(const void *data) goto cleanup; } + if (testCompareXMLToArgvValidateSchema(&driver, vm, migrateURI, info, flags) < 0) + goto cleanup; + if (!(actualargv = virCommandToString(cmd, false))) goto cleanup; diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index f36e49744f..4dcc3089dd 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -770,6 +770,10 @@ testQemuInfoSetArgs(struct testQemuInfo *info, if (stripmachinealiases) virQEMUCapsStripMachineAliases(qemuCaps); info->flags |= FLAG_REAL_CAPS; + + /* provide path to the replies file for schema testing */ + capsfile[strlen(capsfile) - 3] = '\0'; + info->schemafile = g_strdup_printf("%sreplies", capsfile); } if (!qemuCaps) { @@ -796,5 +800,6 @@ testQemuInfoClear(struct testQemuInfo *info) { VIR_FREE(info->infile); VIR_FREE(info->outfile); + VIR_FREE(info->schemafile); virObjectUnref(info->qemuCaps); } diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h index edee6e450c..e7c5032012 100644 --- a/tests/testutilsqemu.h +++ b/tests/testutilsqemu.h @@ -64,6 +64,7 @@ struct testQemuInfo { unsigned int flags; unsigned int parseFlags; virArch arch; + char *schemafile; }; virCapsPtr testQemuCapsInit(void);