[libvirt] [PATCH 0/4] Introduction of qemucapabilitiestest

So far, we are testing our capabilities code only from the --help output. Which is sufficient for ancient qemus, but not sufficient for 99% of qemus, where the QMP is used. So far, only one (example) test case is being added. If the patch set is accepted, we can add much more test cases. Michal Privoznik (4): qemu_capabilities: Introduce virQEMUCapsInitQMPMonitor tests: Learn qemuMonitorTestNew optional greeting qemuMonitorTest: Make check for monitor command match optional tests: Introduce qemucapabilitiestest .gitignore | 1 + src/qemu/qemu_capabilities.c | 144 +- src/qemu/qemu_capabilities.h | 3 + tests/Makefile.am | 12 +- tests/qemucapabilitiesdata/caps_default.caps | 132 ++ tests/qemucapabilitiesdata/caps_default.replies | 2519 +++++++++++++++++++++++ tests/qemucapabilitiestest.c | 231 +++ tests/qemuhotplugtest.c | 2 +- tests/qemumonitortestutils.c | 23 +- tests/qemumonitortestutils.h | 5 +- 10 files changed, 2994 insertions(+), 78 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_default.caps create mode 100644 tests/qemucapabilitiesdata/caps_default.replies create mode 100644 tests/qemucapabilitiestest.c -- 1.8.1.5

This basically covers the talking-to-monitor part of virQEMUCapsInitQMP. The patch itself has no real value, but it creates an entity to be tested in the next patches. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_capabilities.c | 144 ++++++++++++++++++++++++------------------- src/qemu/qemu_capabilities.h | 3 + 2 files changed, 83 insertions(+), 64 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d830e2a..b09f1a5 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2491,6 +2491,85 @@ cleanup: return ret; } +int +virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, + qemuMonitorPtr mon) +{ + int ret = -1; + int major, minor, micro; + char *package = NULL; + + /* @mon is supposed to be locked by callee */ + + if (qemuMonitorSetCapabilities(mon) < 0) { + virErrorPtr err = virGetLastError(); + VIR_DEBUG("Failed to set monitor capabilities %s", + err ? err->message : "<unknown problem>"); + ret = 0; + goto cleanup; + } + + if (qemuMonitorGetVersion(mon, + &major, &minor, µ, + &package) < 0) { + virErrorPtr err = virGetLastError(); + VIR_DEBUG("Failed to query monitor version %s", + err ? err->message : "<unknown problem>"); + ret = 0; + goto cleanup; + } + + VIR_DEBUG("Got version %d.%d.%d (%s)", + major, minor, micro, NULLSTR(package)); + + if (major < 1 || (major == 1 && minor < 2)) { + VIR_DEBUG("Not new enough for QMP capabilities detection"); + ret = 0; + goto cleanup; + } + + qemuCaps->version = major * 1000000 + minor * 1000 + micro; + qemuCaps->usedQMP = true; + + virQEMUCapsInitQMPBasic(qemuCaps); + + if (virQEMUCapsInitArchQMPBasic(qemuCaps, mon) < 0) + goto cleanup; + + /* USB option is supported v1.3.0 onwards */ + if (qemuCaps->version >= 1003000) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT); + + /* WebSockets were introduced between 1.3.0 and 1.3.1 */ + if (qemuCaps->version >= 1003001) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET); + + if (qemuCaps->version >= 1006000) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); + + if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) + goto cleanup; + if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0) + goto cleanup; + if (virQEMUCapsProbeQMPObjects(qemuCaps, mon) < 0) + goto cleanup; + if (virQEMUCapsProbeQMPMachineTypes(qemuCaps, mon) < 0) + goto cleanup; + if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon) < 0) + goto cleanup; + if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0) + goto cleanup; + if (virQEMUCapsProbeQMPTPM(qemuCaps, mon) < 0) + goto cleanup; + if (virQEMUCapsProbeQMPCommandLine(qemuCaps, mon) < 0) + goto cleanup; + + ret = 0; +cleanup: + VIR_FREE(package); + return ret; +} + static int virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps, const char *libDir, @@ -2500,8 +2579,6 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps, int ret = -1; virCommandPtr cmd = NULL; qemuMonitorPtr mon = NULL; - int major, minor, micro; - char *package = NULL; int status = 0; virDomainChrSourceDef config; char *monarg = NULL; @@ -2581,67 +2658,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps, virObjectLock(mon); - if (qemuMonitorSetCapabilities(mon) < 0) { - virErrorPtr err = virGetLastError(); - VIR_DEBUG("Failed to set monitor capabilities %s", - err ? err->message : "<unknown problem>"); - ret = 0; - goto cleanup; - } - - if (qemuMonitorGetVersion(mon, - &major, &minor, µ, - &package) < 0) { - virErrorPtr err = virGetLastError(); - VIR_DEBUG("Failed to query monitor version %s", - err ? err->message : "<unknown problem>"); - ret = 0; - goto cleanup; - } - - VIR_DEBUG("Got version %d.%d.%d (%s)", - major, minor, micro, NULLSTR(package)); - - if (major < 1 || (major == 1 && minor < 2)) { - VIR_DEBUG("Not new enough for QMP capabilities detection"); - ret = 0; - goto cleanup; - } - - qemuCaps->version = major * 1000000 + minor * 1000 + micro; - qemuCaps->usedQMP = true; - - virQEMUCapsInitQMPBasic(qemuCaps); - - if (virQEMUCapsInitArchQMPBasic(qemuCaps, mon) < 0) - goto cleanup; - - /* USB option is supported v1.3.0 onwards */ - if (qemuCaps->version >= 1003000) - virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT); - - /* WebSockets were introduced between 1.3.0 and 1.3.1 */ - if (qemuCaps->version >= 1003001) - virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET); - - if (qemuCaps->version >= 1006000) - virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); - - if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) - goto cleanup; - if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0) - goto cleanup; - if (virQEMUCapsProbeQMPObjects(qemuCaps, mon) < 0) - goto cleanup; - if (virQEMUCapsProbeQMPMachineTypes(qemuCaps, mon) < 0) - goto cleanup; - if (virQEMUCapsProbeQMPCPUDefinitions(qemuCaps, mon) < 0) - goto cleanup; - if (virQEMUCapsProbeQMPKVMState(qemuCaps, mon) < 0) - goto cleanup; - if (virQEMUCapsProbeQMPTPM(qemuCaps, mon) < 0) - goto cleanup; - if (virQEMUCapsProbeQMPCommandLine(qemuCaps, mon) < 0) + if (virQEMUCapsInitQMPMonitor(qemuCaps, mon) < 0) goto cleanup; ret = 0; @@ -2654,7 +2671,6 @@ cleanup: virCommandFree(cmd); VIR_FREE(monarg); VIR_FREE(monpath); - VIR_FREE(package); if (pid != 0) { char ebuf[1024]; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f3c8fa8..128f525 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -213,6 +213,9 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(const char *binary, uid_t runUid, gid_t runGid); +int virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, + qemuMonitorPtr mon); + int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon); -- 1.8.1.5

On 09/23/2013 06:58 AM, Michal Privoznik wrote:
This basically covers the talking-to-monitor part of virQEMUCapsInitQMP. The patch itself has no real value, but it creates an entity to be tested in the next patches.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_capabilities.c | 144 ++++++++++++++++++++++++------------------- src/qemu/qemu_capabilities.h | 3 + 2 files changed, 83 insertions(+), 64 deletions(-)
ACK; just a refactoring to split one function into two. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Currently, when creating a new mocked monitor, the greeting can't be chosen. This is crucial for next patches, because some info as qemu version is obtained in the greeting message. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemuhotplugtest.c | 2 +- tests/qemumonitortestutils.c | 10 ++++++---- tests/qemumonitortestutils.h | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 89480af..5148a21 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -250,7 +250,7 @@ testQemuHotplug(const void *data) /* Now is the best time to feed the spoofed monitor with predefined * replies. */ - if (!(test_mon = qemuMonitorTestNew(true, driver.xmlopt, vm, &driver))) + if (!(test_mon = qemuMonitorTestNew(true, driver.xmlopt, vm, &driver, NULL))) goto cleanup; tmp = test->mon; diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 486d72f..6400f27 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -872,7 +872,8 @@ qemuMonitorTestPtr qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt, virDomainObjPtr vm, - virQEMUDriverPtr driver) + virQEMUDriverPtr driver, + const char *greeting) { qemuMonitorTestPtr test = NULL; virDomainChrSourceDef src; @@ -890,9 +891,10 @@ qemuMonitorTestNew(bool json, virObjectLock(test->mon); - if (qemuMonitorTestAddReponse(test, json ? - QEMU_JSON_GREETING : - QEMU_TEXT_GREETING) < 0) + if (!greeting) + greeting = json ? QEMU_JSON_GREETING : QEMU_TEXT_GREETING; + + if (qemuMonitorTestAddReponse(test, greeting) < 0) goto error; if (qemuMonitorCommonTestInit(test) < 0) diff --git a/tests/qemumonitortestutils.h b/tests/qemumonitortestutils.h index 9e39795..3f07f65 100644 --- a/tests/qemumonitortestutils.h +++ b/tests/qemumonitortestutils.h @@ -61,12 +61,13 @@ int qemuMonitorTestAddItemParams(qemuMonitorTestPtr test, ATTRIBUTE_SENTINEL; # define qemuMonitorTestNewSimple(json, xmlopt) \ - qemuMonitorTestNew(json, xmlopt, NULL, NULL) + qemuMonitorTestNew(json, xmlopt, NULL, NULL, NULL) qemuMonitorTestPtr qemuMonitorTestNew(bool json, virDomainXMLOptionPtr xmlopt, virDomainObjPtr vm, - virQEMUDriverPtr driver); + virQEMUDriverPtr driver, + const char *greeting); qemuMonitorTestPtr qemuMonitorTestNewAgent(virDomainXMLOptionPtr xmlopt); -- 1.8.1.5

On 09/23/2013 06:58 AM, Michal Privoznik wrote:
Currently, when creating a new mocked monitor, the greeting can't be chosen. This is crucial for next patches, because some info as qemu version is obtained in the greeting message.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemuhotplugtest.c | 2 +- tests/qemumonitortestutils.c | 10 ++++++---- tests/qemumonitortestutils.h | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-)
ACK -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

In a few cases we might want to not care if monitor command executed on the mocked monitor matches the one we have reply for. Sounds crazy, but if we just want monitor to return certain values (e.g. read from a file) there is no need to care about command match. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitortestutils.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 6400f27..c3242d5 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -485,7 +485,7 @@ qemuMonitorTestProcessCommandDefault(qemuMonitorTestPtr test, *tmp = '\0'; } - if (STRNEQ(data->command_name, cmdname)) + if (data->command_name && STRNEQ(data->command_name, cmdname)) ret = qemuMonitorTestAddUnexpectedErrorResponse(test); else ret = qemuMonitorTestAddReponse(test, data->response); @@ -604,7 +604,8 @@ qemuMonitorTestProcessCommandWithArgs(qemuMonitorTestPtr test, goto cleanup; } - if (STRNEQ(data->command_name, cmdname)) { + if (data->command_name && + STRNEQ(data->command_name, cmdname)) { ret = qemuMonitorTestAddUnexpectedErrorResponse(test); goto cleanup; } @@ -612,7 +613,7 @@ qemuMonitorTestProcessCommandWithArgs(qemuMonitorTestPtr test, if (!(args = virJSONValueObjectGet(val, "arguments"))) { ret = qemuMonitorReportError(test, "Missing arguments section for command '%s'", - data->command_name); + NULLSTR(data->command_name)); goto cleanup; } @@ -622,7 +623,8 @@ qemuMonitorTestProcessCommandWithArgs(qemuMonitorTestPtr test, if (!(argobj = virJSONValueObjectGet(args, arg->argname))) { ret = qemuMonitorReportError(test, "Missing argument '%s' for command '%s'", - arg->argname, data->command_name); + arg->argname, + NULLSTR(data->command_name)); goto cleanup; } @@ -636,7 +638,8 @@ qemuMonitorTestProcessCommandWithArgs(qemuMonitorTestPtr test, "Invalid value of argument '%s' " "of command '%s': " "expected '%s' got '%s'", - arg->argname, data->command_name, + arg->argname, + NULLSTR(data->command_name), arg->argval, argstr); goto cleanup; } -- 1.8.1.5

On 09/23/2013 06:58 AM, Michal Privoznik wrote:
In a few cases we might want to not care if monitor command executed on the mocked monitor matches the one we have reply for. Sounds crazy, but if we just want monitor to return certain values (e.g. read from a file) there is no need to care about command match.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitortestutils.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
ACK. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

This test is there to ensure that our capabilities detection code isn't broken somehow. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- .gitignore | 1 + tests/Makefile.am | 12 +- tests/qemucapabilitiesdata/caps_default.caps | 132 ++ tests/qemucapabilitiesdata/caps_default.replies | 2519 +++++++++++++++++++++++ tests/qemucapabilitiestest.c | 231 +++ 5 files changed, 2893 insertions(+), 2 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_default.caps create mode 100644 tests/qemucapabilitiesdata/caps_default.replies create mode 100644 tests/qemucapabilitiestest.c diff --git a/.gitignore b/.gitignore index edd5d26..b5824dc 100644 --- a/.gitignore +++ b/.gitignore @@ -176,6 +176,7 @@ /tests/openvzutilstest /tests/qemuagenttest /tests/qemuargv2xmltest +/tests/qemucapabilitiestest /tests/qemuhelptest /tests/qemuhotplugtest /tests/qemumonitorjsontest diff --git a/tests/Makefile.am b/tests/Makefile.am index fe36810..60ef50c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -82,6 +82,7 @@ EXTRA_DIST = \ nwfilterxml2xmlin \ nwfilterxml2xmlout \ oomtrace.pl \ + qemucapabilitiesdata \ qemuhelpdata \ qemuhotplugtestdata \ qemuxml2argvdata \ @@ -170,7 +171,7 @@ if WITH_QEMU test_programs += qemuxml2argvtest qemuxml2xmltest qemuxmlnstest \ qemuargv2xmltest qemuhelptest domainsnapshotxml2xmltest \ qemumonitortest qemumonitorjsontest qemuhotplugtest \ - qemuagenttest + qemuagenttest qemucapabilitiestest endif WITH_QEMU if WITH_LXC @@ -436,6 +437,13 @@ qemumonitorjsontest_SOURCES = \ $(NULL) qemumonitorjsontest_LDADD = libqemumonitortestutils.la $(qemu_LDADDS) +qemucapabilitiestest_SOURCES = \ + qemucapabilitiestest.c \ + testutils.c testutils.h \ + testutilsqemu.c testutilsqemu.h \ + $(NULL) +qemucapabilitiestest_LDADD = libqemumonitortestutils.la $(qemu_LDADDS) + qemuagenttest_SOURCES = \ qemuagenttest.c \ testutils.c testutils.h \ @@ -459,7 +467,7 @@ EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c \ qemuxmlnstest.c qemuhelptest.c domainsnapshotxml2xmltest.c \ qemumonitortest.c testutilsqemu.c testutilsqemu.h \ qemumonitorjsontest.c qemuhotplugtest.c \ - qemuagenttest.c \ + qemuagenttest.c qemucapabilitiestest.c \ $(QEMUMONITORTESTUTILS_SOURCES) endif ! WITH_QEMU diff --git a/tests/qemucapabilitiesdata/caps_default.caps b/tests/qemucapabilitiesdata/caps_default.caps new file mode 100644 index 0000000..bf8a43c --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_default.caps @@ -0,0 +1,132 @@ + <qemuCaps> + <flag name='vnc-colon'/> + <flag name='no-reboot'/> + <flag name='drive'/> + <flag name='name'/> + <flag name='uuid'/> + <flag name='vnet-hdr'/> + <flag name='migrate-qemu-tcp'/> + <flag name='migrate-qemu-exec'/> + <flag name='drive-cache-v2'/> + <flag name='drive-format'/> + <flag name='vga'/> + <flag name='0.10'/> + <flag name='mem-path'/> + <flag name='drive-serial'/> + <flag name='migrate-qemu-unix'/> + <flag name='chardev'/> + <flag name='enable-kvm'/> + <flag name='monitor-json'/> + <flag name='balloon'/> + <flag name='device'/> + <flag name='sdl'/> + <flag name='smp-topology'/> + <flag name='netdev'/> + <flag name='rtc'/> + <flag name='vhost-net'/> + <flag name='no-hpet'/> + <flag name='no-kvm-pit'/> + <flag name='pci-configfd'/> + <flag name='nodefconfig'/> + <flag name='boot-menu'/> + <flag name='fsdev'/> + <flag name='name-process'/> + <flag name='drive-readonly'/> + <flag name='smbios-type'/> + <flag name='vga-qxl'/> + <flag name='spice'/> + <flag name='vga-none'/> + <flag name='migrate-qemu-fd'/> + <flag name='boot-index'/> + <flag name='hda-duplex'/> + <flag name='drive-aio'/> + <flag name='pci-multibus'/> + <flag name='pci-bootindex'/> + <flag name='ccid-passthru'/> + <flag name='chardev-spicevmc'/> + <flag name='virtio-tx-alg'/> + <flag name='device-qxl-vga'/> + <flag name='pci-multifunction'/> + <flag name='virtio-blk-pci.ioeventfd'/> + <flag name='sga'/> + <flag name='virtio-blk-pci.event_idx'/> + <flag name='virtio-net-pci.event_idx'/> + <flag name='cache-directsync'/> + <flag name='piix3-usb-uhci'/> + <flag name='piix4-usb-uhci'/> + <flag name='usb-ehci'/> + <flag name='ich9-usb-ehci1'/> + <flag name='vt82c686b-usb-uhci'/> + <flag name='pci-ohci'/> + <flag name='usb-hub'/> + <flag name='no-shutdown'/> + <flag name='cache-unsafe'/> + <flag name='rombar'/> + <flag name='ich9-ahci'/> + <flag name='no-acpi'/> + <flag name='fsdev-readonly'/> + <flag name='virtio-blk-pci.scsi'/> + <flag name='blk-sg-io'/> + <flag name='drive-copy-on-read'/> + <flag name='cpu-host'/> + <flag name='fsdev-writeout'/> + <flag name='drive-iotune'/> + <flag name='system_wakeup'/> + <flag name='scsi-disk.channel'/> + <flag name='scsi-block'/> + <flag name='transaction'/> + <flag name='block-job-async'/> + <flag name='scsi-cd'/> + <flag name='ide-cd'/> + <flag name='no-user-config'/> + <flag name='hda-micro'/> + <flag name='dump-guest-memory'/> + <flag name='nec-usb-xhci'/> + <flag name='balloon-event'/> + <flag name='bridge'/> + <flag name='lsi'/> + <flag name='virtio-scsi-pci'/> + <flag name='blockio'/> + <flag name='disable-s3'/> + <flag name='disable-s4'/> + <flag name='ide-drive.wwn'/> + <flag name='scsi-disk.wwn'/> + <flag name='seccomp-sandbox'/> + <flag name='dump-guest-core'/> + <flag name='seamless-migration'/> + <flag name='block-commit'/> + <flag name='vnc'/> + <flag name='drive-mirror'/> + <flag name='usb-host.bootindex'/> + <flag name='blockdev-snapshot-sync'/> + <flag name='qxl'/> + <flag name='VGA'/> + <flag name='cirrus-vga'/> + <flag name='vmware-svga'/> + <flag name='usb-serial'/> + <flag name='usb-net'/> + <flag name='add-fd'/> + <flag name='nbd-server'/> + <flag name='virtio-rng'/> + <flag name='rng-random'/> + <flag name='rng-egd'/> + <flag name='dtb'/> + <flag name='megasas'/> + <flag name='ipv6-migration'/> + <flag name='machine-opt'/> + <flag name='machine-usb-opt'/> + <flag name='pci-bridge'/> + <flag name='vfio-pci'/> + <flag name='vfio-pci.bootindex'/> + <flag name='scsi-generic'/> + <flag name='scsi-generic.bootindex'/> + <flag name='mem-merge'/> + <flag name='vnc-websocket'/> + <flag name='drive-discard'/> + <flag name='mlock'/> + <flag name='vnc-share-policy'/> + <flag name='device-del-event'/> + <flag name='dmi-to-pci-bridge'/> + <flag name='usb-storage'/> + <flag name='usb-storage.removable'/> + </qemuCaps> diff --git a/tests/qemucapabilitiesdata/caps_default.replies b/tests/qemucapabilitiesdata/caps_default.replies new file mode 100644 index 0000000..8ff17ce --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_default.replies @@ -0,0 +1,2519 @@ +{ + "QMP": { + "version": { + "qemu": { + "micro": 3, + "minor": 5, + "major": 1 + }, + "package": "" + }, + "capabilities": [ + ] + } +} + +{ + "return": { + }, + "id": "libvirt-1" +} + +{ + "return": { + "qemu": { + "micro": 3, + "minor": 5, + "major": 1 + }, + "package": "" + }, + "id": "libvirt-2" +} + +{ + "return": { + "arch": "x86_64" + }, + "id": "libvirt-3" +} + +{ + "return": [ + { + "name": "chardev-remove" + }, + { + "name": "chardev-add" + }, + { + "name": "query-tpm-types" + }, + { + "name": "query-tpm-models" + }, + { + "name": "query-tpm" + }, + { + "name": "query-target" + }, + { + "name": "query-cpu-definitions" + }, + { + "name": "query-machines" + }, + { + "name": "device-list-properties" + }, + { + "name": "qom-list-types" + }, + { + "name": "change-vnc-password" + }, + { + "name": "nbd-server-stop" + }, + { + "name": "nbd-server-add" + }, + { + "name": "nbd-server-start" + }, + { + "name": "qom-get" + }, + { + "name": "qom-set" + }, + { + "name": "qom-list" + }, + { + "name": "query-block-jobs" + }, + { + "name": "query-balloon" + }, + { + "name": "query-migrate-capabilities" + }, + { + "name": "migrate-set-capabilities" + }, + { + "name": "query-migrate" + }, + { + "name": "query-command-line-options" + }, + { + "name": "query-uuid" + }, + { + "name": "query-name" + }, + { + "name": "query-spice" + }, + { + "name": "query-vnc" + }, + { + "name": "query-mice" + }, + { + "name": "query-status" + }, + { + "name": "query-kvm" + }, + { + "name": "query-pci" + }, + { + "name": "query-cpus" + }, + { + "name": "query-blockstats" + }, + { + "name": "query-block" + }, + { + "name": "query-chardev" + }, + { + "name": "query-events" + }, + { + "name": "query-commands" + }, + { + "name": "query-version" + }, + { + "name": "human-monitor-command" + }, + { + "name": "qmp_capabilities" + }, + { + "name": "add_client" + }, + { + "name": "expire_password" + }, + { + "name": "set_password" + }, + { + "name": "block_set_io_throttle" + }, + { + "name": "block_passwd" + }, + { + "name": "query-fdsets" + }, + { + "name": "remove-fd" + }, + { + "name": "add-fd" + }, + { + "name": "closefd" + }, + { + "name": "getfd" + }, + { + "name": "set_link" + }, + { + "name": "balloon" + }, + { + "name": "drive-mirror" + }, + { + "name": "blockdev-snapshot-sync" + }, + { + "name": "transaction" + }, + { + "name": "block-job-complete" + }, + { + "name": "block-job-resume" + }, + { + "name": "block-job-pause" + }, + { + "name": "block-job-cancel" + }, + { + "name": "block-job-set-speed" + }, + { + "name": "block-commit" + }, + { + "name": "block-stream" + }, + { + "name": "block_resize" + }, + { + "name": "netdev_del" + }, + { + "name": "netdev_add" + }, + { + "name": "dump-guest-memory" + }, + { + "name": "client_migrate_info" + }, + { + "name": "migrate_set_downtime" + }, + { + "name": "migrate_set_speed" + }, + { + "name": "query-migrate-cache-size" + }, + { + "name": "migrate-set-cache-size" + }, + { + "name": "migrate_cancel" + }, + { + "name": "migrate" + }, + { + "name": "xen-set-global-dirty-log" + }, + { + "name": "xen-save-devices-state" + }, + { + "name": "ringbuf-read" + }, + { + "name": "ringbuf-write" + }, + { + "name": "inject-nmi" + }, + { + "name": "pmemsave" + }, + { + "name": "memsave" + }, + { + "name": "cpu-add" + }, + { + "name": "cpu" + }, + { + "name": "send-key" + }, + { + "name": "device_del" + }, + { + "name": "device_add" + }, + { + "name": "system_powerdown" + }, + { + "name": "system_reset" + }, + { + "name": "system_wakeup" + }, + { + "name": "cont" + }, + { + "name": "stop" + }, + { + "name": "screendump" + }, + { + "name": "change" + }, + { + "name": "eject" + }, + { + "name": "quit" + } + ], + "id": "libvirt-4" +} + +{ + "return": { + "fd": 10, + "fdset-id": 0 + }, + "id": "libvirt-5" +} + +{ + "return": [ + { + "name": "GUEST_PANICKED" + }, + { + "name": "SPICE_MIGRATE_COMPLETED" + }, + { + "name": "BALLOON_CHANGE" + }, + { + "name": "WAKEUP" + }, + { + "name": "SUSPEND_DISK" + }, + { + "name": "SUSPEND" + }, + { + "name": "DEVICE_TRAY_MOVED" + }, + { + "name": "DEVICE_DELETED" + }, + { + "name": "BLOCK_JOB_READY" + }, + { + "name": "BLOCK_JOB_ERROR" + }, + { + "name": "BLOCK_JOB_CANCELLED" + }, + { + "name": "BLOCK_JOB_COMPLETED" + }, + { + "name": "SPICE_DISCONNECTED" + }, + { + "name": "SPICE_INITIALIZED" + }, + { + "name": "SPICE_CONNECTED" + }, + { + "name": "WATCHDOG" + }, + { + "name": "RTC_CHANGE" + }, + { + "name": "BLOCK_IO_ERROR" + }, + { + "name": "VNC_DISCONNECTED" + }, + { + "name": "VNC_INITIALIZED" + }, + { + "name": "VNC_CONNECTED" + }, + { + "name": "RESUME" + }, + { + "name": "STOP" + }, + { + "name": "POWERDOWN" + }, + { + "name": "RESET" + }, + { + "name": "SHUTDOWN" + } + ], + "id": "libvirt-6" +} + +{ + "return": [ + { + "name": "ICH9 LPC" + }, + { + "name": "x86_64-cpu" + }, + { + "name": "port92" + }, + { + "name": "virtio-net-pci" + }, + { + "name": "virtio-scsi-device" + }, + { + "name": "apic" + }, + { + "name": "pc-testdev" + }, + { + "name": "virtio-blk-device" + }, + { + "name": "virtio-scsi-pci" + }, + { + "name": "exynos4210-ehci-usb" + }, + { + "name": "i6300esb" + }, + { + "name": "usb-host" + }, + { + "name": "ich9-usb-ehci2" + }, + { + "name": "usb-ehci" + }, + { + "name": "ich9-ahci" + }, + { + "name": "ich9-usb-ehci1" + }, + { + "name": "isa-ide" + }, + { + "name": "ICH9 SMB" + }, + { + "name": "virtio-balloon-pci" + }, + { + "name": "vt82c686b-usb-uhci" + }, + { + "name": "i82558b" + }, + { + "name": "i82558a" + }, + { + "name": "isa-fdc" + }, + { + "name": "isabus-bridge" + }, + { + "name": "pvpanic" + }, + { + "name": "i2c-bus" + }, + { + "name": "piix3-ide" + }, + { + "name": "ioapic" + }, + { + "name": "pci-bridge" + }, + { + "name": "HDA" + }, + { + "name": "am53c974" + }, + { + "name": "xlnx,ps7-usb" + }, + { + "name": "vmmouse" + }, + { + "name": "sb16" + }, + { + "name": "i82801b11-bridge" + }, + { + "name": "vmxnet3" + }, + { + "name": "isa-cirrus-vga" + }, + { + "name": "dc390" + }, + { + "name": "vmware-svga" + }, + { + "name": "smbus-eeprom" + }, + { + "name": "piix4-usb-uhci" + }, + { + "name": "ccid-card-passthru" + }, + { + "name": "i82801" + }, + { + "name": "fw_cfg" + }, + { + "name": "qxl" + }, + { + "name": "piix3-usb-uhci" + }, + { + "name": "ib700" + }, + { + "name": "usb-audio" + }, + { + "name": "i82557c" + }, + { + "name": "i82557b" + }, + { + "name": "i82557a" + }, + { + "name": "IndustryPack" + }, + { + "name": "hpet" + }, + { + "name": "pvscsi" + }, + { + "name": "rtl8139" + }, + { + "name": "isa-applesmc" + }, + { + "name": "kvm-pci-assign" + }, + { + "name": "container" + }, + { + "name": "cfi.pflash01" + }, + { + "name": "usb-kbd" + }, + { + "name": "vfio-pci" + }, + { + "name": "isa-vga" + }, + { + "name": "pci-testdev" + }, + { + "name": "usb-tablet" + }, + { + "name": "vmport" + }, + { + "name": "virtio-rng-pci" + }, + { + "name": "kvmvapic" + }, + { + "name": "usb-bt-dongle" + }, + { + "name": "sysbus-fdc" + }, + { + "name": "piix4-ide" + }, + { + "name": "e1000" + }, + { + "name": "AC97" + }, + { + "name": "ipoctal232" + }, + { + "name": "mch" + }, + { + "name": "mc146818rtc" + }, + { + "name": "ivshmem" + }, + { + "name": "usb-ccid" + }, + { + "name": "sysbus-ahci" + }, + { + "name": "kvmclock" + }, + { + "name": "i82562" + }, + { + "name": "hda-output" + }, + { + "name": "pci-serial-4x" + }, + { + "name": "ccid-bus" + }, + { + "name": "i82559er" + }, + { + "name": "virtio-balloon-device" + }, + { + "name": "i8042" + }, + { + "name": "megasas" + }, + { + "name": "intel-hda" + }, + { + "name": "hda-duplex" + }, + { + "name": "virtio-serial-pci" + }, + { + "name": "ne2k_pci" + }, + { + "name": "ich9-usb-uhci6" + }, + { + "name": "ich9-usb-uhci5" + }, + { + "name": "ich9-usb-uhci3" + }, + { + "name": "virtconsole" + }, + { + "name": "ich9-usb-uhci4" + }, + { + "name": "isa-parallel" + }, + { + "name": "pci-serial" + }, + { + "name": "ich9-usb-uhci2" + }, + { + "name": "ich9-usb-uhci1" + }, + { + "name": "PCI" + }, + { + "name": "adlib" + }, + { + "name": "SUNW,fdtwo" + }, + { + "name": "ide-cd" + }, + { + "name": "isa-debugcon" + }, + { + "name": "usb-bot" + }, + { + "name": "i82551" + }, + { + "name": "i82550" + }, + { + "name": "isa-serial" + }, + { + "name": "PCIE" + }, + { + "name": "kvm-ioapic" + }, + { + "name": "nec-usb-xhci" + }, + { + "name": "System" + }, + { + "name": "kvm-apic" + }, + { + "name": "ich9-intel-hda" + }, + { + "name": "virtio-net-device" + }, + { + "name": "usb-wacom-tablet" + }, + { + "name": "PIIX4_PM" + }, + { + "name": "kvm-i8259" + }, + { + "name": "q35-pcihost" + }, + { + "name": "scsi-cd" + }, + { + "name": "pci-ohci" + }, + { + "name": "i440FX" + }, + { + "name": "usb-braille" + }, + { + "name": "virtserialport" + }, + { + "name": "pci-serial-2x" + }, + { + "name": "xio3130-downstream" + }, + { + "name": "rng-random" + }, + { + "name": "hda-micro" + }, + { + "name": "scsi-disk" + }, + { + "name": "vhost-scsi" + }, + { + "name": "lsi53c895a" + }, + { + "name": "qxl-vga" + }, + { + "name": "SCSI" + }, + { + "name": "pcnet" + }, + { + "name": "scsi-generic" + }, + { + "name": "virtio-scsi-common" + }, + { + "name": "virtio-serial-device" + }, + { + "name": "virtio-serial-bus" + }, + { + "name": "icc-bridge" + }, + { + "name": "usb-bus" + }, + { + "name": "ne2k_isa" + }, + { + "name": "IDE" + }, + { + "name": "usb-net" + }, + { + "name": "usb-hub" + }, + { + "name": "i440FX-pcihost" + }, + { + "name": "usb-mouse" + }, + { + "name": "isa-i8259" + }, + { + "name": "ISA" + }, + { + "name": "cs4231a" + }, + { + "name": "usb-serial" + }, + { + "name": "pc-sysfw" + }, + { + "name": "scsi-block" + }, + { + "name": "sga" + }, + { + "name": "isa-debug-exit" + }, + { + "name": "virtio-rng-device" + }, + { + "name": "ioh3420" + }, + { + "name": "ES1370" + }, + { + "name": "PIIX3" + }, + { + "name": "isa-pcspk" + }, + { + "name": "ide-hd" + }, + { + "name": "rng-egd" + }, + { + "name": "cirrus-vga" + }, + { + "name": "kvm-pit" + }, + { + "name": "qemu-console" + }, + { + "name": "icc-bus" + }, + { + "name": "ide-drive" + }, + { + "name": "x3130-upstream" + }, + { + "name": "virtio-pci-bus" + }, + { + "name": "usb-uas" + }, + { + "name": "vhost-scsi-pci" + }, + { + "name": "virtio-blk-pci" + }, + { + "name": "sysbus-ohci" + }, + { + "name": "esp" + }, + { + "name": "piix3-ide-xen" + }, + { + "name": "i82559c" + }, + { + "name": "i82559b" + }, + { + "name": "i82559a" + }, + { + "name": "scsi-hd" + }, + { + "name": "PIIX3-xen" + }, + { + "name": "usb-storage" + }, + { + "name": "isa-pit" + }, + { + "name": "tpci200" + }, + { + "name": "gus" + }, + { + "name": "VGA" + } + ], + "id": "libvirt-7" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "scsi", + "type": "on/off" + }, + { + "name": "config-wce", + "type": "on/off" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "secs", + "type": "uint32" + }, + { + "name": "heads", + "type": "uint32" + }, + { + "name": "cyls", + "type": "uint32" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + }, + { + "name": "event_idx", + "type": "on/off" + }, + { + "name": "indirect_desc", + "type": "on/off" + }, + { + "name": "x-data-plane", + "type": "on/off" + }, + { + "name": "vectors", + "type": "uint32" + }, + { + "name": "ioeventfd", + "type": "on/off" + }, + { + "name": "class", + "type": "hex32" + } + ], + "id": "libvirt-8" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "tx", + "type": "string" + }, + { + "name": "x-txburst", + "type": "int32" + }, + { + "name": "x-txtimer", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "netdev", + "type": "netdev" + }, + { + "name": "vlan", + "type": "vlan" + }, + { + "name": "mac", + "type": "macaddr" + }, + { + "name": "mq", + "type": "on/off" + }, + { + "name": "ctrl_mac_addr", + "type": "on/off" + }, + { + "name": "ctrl_rx_extra", + "type": "on/off" + }, + { + "name": "ctrl_vlan", + "type": "on/off" + }, + { + "name": "ctrl_rx", + "type": "on/off" + }, + { + "name": "ctrl_vq", + "type": "on/off" + }, + { + "name": "status", + "type": "on/off" + }, + { + "name": "mrg_rxbuf", + "type": "on/off" + }, + { + "name": "host_ufo", + "type": "on/off" + }, + { + "name": "host_ecn", + "type": "on/off" + }, + { + "name": "host_tso6", + "type": "on/off" + }, + { + "name": "host_tso4", + "type": "on/off" + }, + { + "name": "guest_ufo", + "type": "on/off" + }, + { + "name": "guest_ecn", + "type": "on/off" + }, + { + "name": "guest_tso6", + "type": "on/off" + }, + { + "name": "guest_tso4", + "type": "on/off" + }, + { + "name": "gso", + "type": "on/off" + }, + { + "name": "guest_csum", + "type": "on/off" + }, + { + "name": "csum", + "type": "on/off" + }, + { + "name": "event_idx", + "type": "on/off" + }, + { + "name": "indirect_desc", + "type": "on/off" + }, + { + "name": "vectors", + "type": "uint32" + }, + { + "name": "ioeventfd", + "type": "on/off" + } + ], + "id": "libvirt-9" +} + +{ + "id": "libvirt-10", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-blk-ccw' not found" + } +} + +{ + "id": "libvirt-11", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-net-ccw' not found" + } +} + +{ + "id": "libvirt-12", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-blk-s390' not found" + } +} + +{ + "id": "libvirt-13", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-net-s390' not found" + } +} + +{ + "id": "libvirt-14", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'pci-assign' not found" + } +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "configfd", + "type": "string" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "share_intx", + "type": "on/off" + }, + { + "name": "prefer_msi", + "type": "on/off" + }, + { + "name": "host", + "type": "pci-host-devaddr" + } + ], + "id": "libvirt-15" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "x-vga", + "type": "on/off" + }, + { + "name": "x-intx-mmap-timeout-ms", + "type": "uint32" + }, + { + "name": "host", + "type": "pci-host-devaddr" + } + ], + "id": "libvirt-16" +} + +{ + "return": [ + { + "name": "lun", + "type": "uint32" + }, + { + "name": "scsi-id", + "type": "uint32" + }, + { + "name": "channel", + "type": "uint32" + }, + { + "name": "wwn", + "type": "hex64" + }, + { + "name": "dpofua", + "type": "on/off" + }, + { + "name": "removable", + "type": "on/off" + }, + { + "name": "product", + "type": "string" + }, + { + "name": "vendor", + "type": "string" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "ver", + "type": "string" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-17" +} + +{ + "return": [ + { + "name": "unit", + "type": "uint32" + }, + { + "name": "model", + "type": "string" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "wwn", + "type": "hex64" + }, + { + "name": "ver", + "type": "string" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-18" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "s4_val", + "type": "uint8" + }, + { + "name": "disable_s4", + "type": "uint8" + }, + { + "name": "disable_s3", + "type": "uint8" + }, + { + "name": "smb_io_base", + "type": "uint32" + } + ], + "id": "libvirt-19" +} + +{ + "id": "libvirt-20", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'usb-redir' not found" + } +} + +{ + "return": [ + { + "name": "full-path", + "type": "on/off" + }, + { + "name": "port", + "type": "string" + }, + { + "name": "pipeline", + "type": "on/off" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "isobufs", + "type": "uint32" + }, + { + "name": "productid", + "type": "hex32" + }, + { + "name": "vendorid", + "type": "hex32" + }, + { + "name": "hostport", + "type": "string" + }, + { + "name": "hostaddr", + "type": "uint32" + }, + { + "name": "hostbus", + "type": "uint32" + } + ], + "id": "libvirt-21" +} + +{ + "return": [ + { + "name": "lun", + "type": "uint32" + }, + { + "name": "scsi-id", + "type": "uint32" + }, + { + "name": "channel", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-22" +} + +{ + "return": [ + ], + "id": "libvirt-23" +} + +{ + "return": [ + { + "name": "MCFG", + "type": "uint64" + } + ], + "id": "libvirt-24" +} + +{ + "return": [ + { + "name": "full-path", + "type": "on/off" + }, + { + "name": "port", + "type": "string" + }, + { + "name": "removable", + "type": "on/off" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-25" +} + +{ + "return": [ + { + "name": "pc-q35-1.4", + "cpu-max": 255 + }, + { + "name": "pc-q35-1.5", + "cpu-max": 255, + "alias": "q35" + }, + { + "name": "isapc", + "cpu-max": 1 + }, + { + "name": "pc-0.10", + "cpu-max": 255 + }, + { + "name": "pc-0.11", + "cpu-max": 255 + }, + { + "name": "pc-0.12", + "cpu-max": 255 + }, + { + "name": "pc-0.13", + "cpu-max": 255 + }, + { + "name": "pc-0.14", + "cpu-max": 255 + }, + { + "name": "pc-0.15", + "cpu-max": 255 + }, + { + "name": "pc-1.0", + "cpu-max": 255 + }, + { + "name": "pc-1.1", + "cpu-max": 255 + }, + { + "name": "pc-1.2", + "cpu-max": 255 + }, + { + "name": "pc-1.3", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-1.4", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-1.5", + "is-default": true, + "cpu-max": 255, + "alias": "pc" + }, + { + "name": "none", + "cpu-max": 1 + } + ], + "id": "libvirt-26" +} + +{ + "return": [ + { + "name": "Opteron_G5" + }, + { + "name": "Opteron_G4" + }, + { + "name": "Opteron_G3" + }, + { + "name": "Opteron_G2" + }, + { + "name": "Opteron_G1" + }, + { + "name": "Haswell" + }, + { + "name": "SandyBridge" + }, + { + "name": "Westmere" + }, + { + "name": "Nehalem" + }, + { + "name": "Penryn" + }, + { + "name": "Conroe" + }, + { + "name": "n270" + }, + { + "name": "athlon" + }, + { + "name": "pentium3" + }, + { + "name": "pentium2" + }, + { + "name": "pentium" + }, + { + "name": "486" + }, + { + "name": "coreduo" + }, + { + "name": "kvm32" + }, + { + "name": "qemu32" + }, + { + "name": "kvm64" + }, + { + "name": "core2duo" + }, + { + "name": "phenom" + }, + { + "name": "qemu64" + } + ], + "id": "libvirt-27" +} + +{ + "return": { + "enabled": false, + "present": true + }, + "id": "libvirt-28" +} + +{ + "return": [ + ], + "id": "libvirt-29" +} + +{ + "return": [ + ], + "id": "libvirt-30" +} + +{ + "return": [ + { + "parameters": [ + { + "name": "seamless-migration", + "type": "boolean" + }, + { + "name": "playback-compression", + "type": "boolean" + }, + { + "name": "agent-mouse", + "type": "boolean" + }, + { + "name": "streaming-video", + "type": "string" + }, + { + "name": "zlib-glz-wan-compression", + "type": "string" + }, + { + "name": "jpeg-wan-compression", + "type": "string" + }, + { + "name": "image-compression", + "type": "string" + }, + { + "name": "plaintext-channel", + "type": "string" + }, + { + "name": "tls-channel", + "type": "string" + }, + { + "name": "tls-ciphers", + "type": "string" + }, + { + "name": "x509-dh-key-file", + "type": "string" + }, + { + "name": "x509-cacert-file", + "type": "string" + }, + { + "name": "x509-cert-file", + "type": "string" + }, + { + "name": "x509-key-password", + "type": "string" + }, + { + "name": "x509-key-file", + "type": "string" + }, + { + "name": "x509-dir", + "type": "string" + }, + { + "name": "sasl", + "type": "boolean" + }, + { + "name": "disable-copy-paste", + "type": "boolean" + }, + { + "name": "disable-ticketing", + "type": "boolean" + }, + { + "name": "password", + "type": "string" + }, + { + "name": "ipv6", + "type": "boolean" + }, + { + "name": "ipv4", + "type": "boolean" + }, + { + "name": "addr", + "type": "string" + }, + { + "name": "tls-port", + "type": "number" + }, + { + "name": "port", + "type": "number" + } + ], + "option": "spice" + }, + { + "parameters": [ + ], + "option": "acpi" + }, + { + "parameters": [ + { + "name": "sock_fd", + "type": "number" + }, + { + "name": "socket", + "type": "string" + }, + { + "name": "readonly", + "type": "boolean" + }, + { + "name": "writeout", + "type": "string" + }, + { + "name": "security_model", + "type": "string" + }, + { + "name": "mount_tag", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "fsdriver", + "type": "string" + } + ], + "option": "virtfs" + }, + { + "parameters": [ + { + "name": "sock_fd", + "type": "number" + }, + { + "name": "socket", + "type": "string" + }, + { + "name": "readonly", + "type": "boolean" + }, + { + "name": "writeout", + "type": "string" + }, + { + "name": "security_model", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "fsdriver", + "type": "string" + } + ], + "option": "fsdev" + }, + { + "parameters": [ + { + "name": "mlock", + "type": "boolean" + } + ], + "option": "realtime" + }, + { + "parameters": [ + ], + "option": "tpmdev" + }, + { + "parameters": [ + ], + "option": "object" + }, + { + "parameters": [ + { + "name": "opaque", + "help": "free-form string used to describe fd", + "type": "string" + }, + { + "name": "set", + "help": "ID of the fd set to add fd to", + "type": "number" + }, + { + "name": "fd", + "help": "file descriptor of which a duplicate is added to fd set", + "type": "number" + } + ], + "option": "add-fd" + }, + { + "parameters": [ + { + "name": "enable", + "type": "boolean" + } + ], + "option": "sandbox" + }, + { + "parameters": [ + { + "name": "strict", + "type": "string" + }, + { + "name": "reboot-timeout", + "type": "string" + }, + { + "name": "splash-time", + "type": "string" + }, + { + "name": "splash", + "type": "string" + }, + { + "name": "menu", + "type": "string" + }, + { + "name": "once", + "type": "string" + }, + { + "name": "order", + "type": "string" + } + ], + "option": "boot-opts" + }, + { + "parameters": [ + { + "name": "usb", + "help": "Set on/off to enable/disable usb", + "type": "boolean" + }, + { + "name": "mem-merge", + "help": "enable/disable memory merge support", + "type": "boolean" + }, + { + "name": "dump-guest-core", + "help": "Include guest memory in a core dump", + "type": "boolean" + }, + { + "name": "dt_compatible", + "help": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "phandle_start", + "help": "The first phandle ID we may generate dynamically", + "type": "string" + }, + { + "name": "dumpdtb", + "help": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "dtb", + "help": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "append", + "help": "Linux kernel command line", + "type": "string" + }, + { + "name": "initrd", + "help": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "kernel", + "help": "Linux kernel image file", + "type": "string" + }, + { + "name": "kvm_shadow_mem", + "help": "KVM shadow MMU size", + "type": "size" + }, + { + "name": "kernel_irqchip", + "help": "use KVM in-kernel irqchip", + "type": "boolean" + }, + { + "name": "accel", + "help": "accelerator list", + "type": "string" + }, + { + "name": "type", + "help": "emulated machine", + "type": "string" + } + ], + "option": "machine" + }, + { + "parameters": [ + { + "name": "romfile", + "type": "string" + }, + { + "name": "bootindex", + "type": "number" + } + ], + "option": "option-rom" + }, + { + "parameters": [ + { + "name": "file", + "type": "string" + }, + { + "name": "events", + "type": "string" + } + ], + "option": "trace" + }, + { + "parameters": [ + { + "name": "pretty", + "type": "boolean" + }, + { + "name": "default", + "type": "boolean" + }, + { + "name": "chardev", + "type": "string" + }, + { + "name": "mode", + "type": "string" + } + ], + "option": "mon" + }, + { + "parameters": [ + { + "name": "value", + "type": "string" + }, + { + "name": "property", + "type": "string" + }, + { + "name": "driver", + "type": "string" + } + ], + "option": "global" + }, + { + "parameters": [ + { + "name": "driftfix", + "type": "string" + }, + { + "name": "clock", + "type": "string" + }, + { + "name": "base", + "type": "string" + } + ], + "option": "rtc" + }, + { + "parameters": [ + ], + "option": "net" + }, + { + "parameters": [ + ], + "option": "netdev" + }, + { + "parameters": [ + ], + "option": "device" + }, + { + "parameters": [ + { + "name": "size", + "type": "size" + }, + { + "name": "debug", + "type": "number" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "signal", + "type": "boolean" + }, + { + "name": "mux", + "type": "boolean" + }, + { + "name": "rows", + "type": "number" + }, + { + "name": "cols", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "telnet", + "type": "boolean" + }, + { + "name": "delay", + "type": "boolean" + }, + { + "name": "server", + "type": "boolean" + }, + { + "name": "wait", + "type": "boolean" + }, + { + "name": "ipv6", + "type": "boolean" + }, + { + "name": "ipv4", + "type": "boolean" + }, + { + "name": "to", + "type": "number" + }, + { + "name": "localport", + "type": "string" + }, + { + "name": "localaddr", + "type": "string" + }, + { + "name": "port", + "type": "string" + }, + { + "name": "host", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "backend", + "type": "string" + } + ], + "option": "chardev" + }, + { + "parameters": [ + { + "name": "boot", + "help": "(deprecated, ignored)", + "type": "boolean" + }, + { + "name": "copy-on-read", + "help": "copy read data from backing file into image file", + "type": "boolean" + }, + { + "name": "bps_wr", + "help": "limit write bytes per second", + "type": "number" + }, + { + "name": "bps_rd", + "help": "limit read bytes per second", + "type": "number" + }, + { + "name": "bps", + "help": "limit total bytes per second", + "type": "number" + }, + { + "name": "iops_wr", + "help": "limit write operations per second", + "type": "number" + }, + { + "name": "iops_rd", + "help": "limit read operations per second", + "type": "number" + }, + { + "name": "iops", + "help": "limit total I/O operations per second", + "type": "number" + }, + { + "name": "readonly", + "help": "open drive file as read-only", + "type": "boolean" + }, + { + "name": "addr", + "help": "pci address (virtio only)", + "type": "string" + }, + { + "name": "werror", + "help": "write error action", + "type": "string" + }, + { + "name": "rerror", + "help": "read error action", + "type": "string" + }, + { + "name": "serial", + "help": "disk serial number", + "type": "string" + }, + { + "name": "format", + "help": "disk format (raw, qcow2, ...)", + "type": "string" + }, + { + "name": "aio", + "help": "host AIO implementation (threads, native)", + "type": "string" + }, + { + "name": "cache", + "help": "host cache usage (none, writeback, writethrough, directsync, unsafe)", + "type": "string" + }, + { + "name": "discard", + "help": "discard operation (ignore/off, unmap/on)", + "type": "string" + }, + { + "name": "file", + "help": "disk image", + "type": "string" + }, + { + "name": "snapshot", + "help": "enable/disable snapshot mode", + "type": "boolean" + }, + { + "name": "media", + "help": "media type (disk, cdrom)", + "type": "string" + }, + { + "name": "trans", + "help": "chs translation (auto, lba. none)", + "type": "string" + }, + { + "name": "secs", + "help": "number of sectors (ide disk geometry)", + "type": "number" + }, + { + "name": "heads", + "help": "number of heads (ide disk geometry)", + "type": "number" + }, + { + "name": "cyls", + "help": "number of cylinders (ide disk geometry)", + "type": "number" + }, + { + "name": "index", + "help": "index number", + "type": "number" + }, + { + "name": "if", + "help": "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)", + "type": "string" + }, + { + "name": "unit", + "help": "unit number (i.e. lun for scsi)", + "type": "number" + }, + { + "name": "bus", + "help": "bus number", + "type": "number" + } + ], + "option": "drive" + } + ], + "id": "libvirt-31" +} diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c new file mode 100644 index 0000000..97f7585 --- /dev/null +++ b/tests/qemucapabilitiestest.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2011-2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <config.h> + +#include "testutils.h" +#include "testutilsqemu.h" +#include "qemumonitortestutils.h" + + +#define VIR_FROM_THIS VIR_FROM_NONE + +typedef struct _testQemuData testQemuData; +typedef testQemuData * testQemuDataPtr; +struct _testQemuData { + virDomainXMLOptionPtr xmlopt; + const char *base; +}; + +static qemuMonitorTestPtr +testQemuFeedMonitor(char *replies, + virDomainXMLOptionPtr xmlopt) +{ + qemuMonitorTestPtr test = NULL; + char *token, *saveptr = NULL; + char *tmp = replies; + + /* Our JSON parser is stupid. It doesn't ignore whitespaces even though it + * should. Hence, a reply needs to be on a single line. However, the + * replies in the file are separated by a single empty line. So we must + * preprocess the file prior splitting it into set of replies. */ + while ((tmp = strchr(tmp, '\n'))) { + if (*(tmp + 1) != '\n') { + *tmp = ' '; + tmp++; + } else { + tmp += 2; + } + } + + token = strtok_r(replies, "\n", &saveptr); + while (token) { + if (test) { + if (qemuMonitorTestAddItem(test, NULL, token) < 0) + goto error; + } else { + /* Create new mocked monitor with our greeting */ + if (!(test = qemuMonitorTestNew(true, xmlopt, NULL, NULL, token))) + goto error; + } + token = strtok_r(NULL, "\n", &saveptr); + } + + return test; + +error: + qemuMonitorTestFree(test); + return NULL; +} + +static virQEMUCapsPtr +testQemuGetCaps(char *caps) +{ + virQEMUCapsPtr qemuCaps = NULL; + xmlDocPtr xml; + xmlXPathContextPtr ctxt = NULL; + ssize_t i, n; + xmlNodePtr *nodes = NULL; + + if (!(xml = virXMLParseStringCtxt(caps, "(test caps)", &ctxt))) + goto error; + + if ((n = virXPathNodeSet("/qemuCaps/flag", ctxt, &nodes)) < 0) { + fprintf(stderr, "failed to parse qemu capabilities flags"); + goto error; + } + + if (n > 0) { + if (!(qemuCaps = virQEMUCapsNew())) + goto error; + + for (i = 0; i < n; i++) { + char *str = virXMLPropString(nodes[i], "name"); + if (str) { + int flag = virQEMUCapsTypeFromString(str); + if (flag < 0) { + fprintf(stderr, "Unknown qemu capabilities flag %s", str); + VIR_FREE(str); + goto error; + } + VIR_FREE(str); + virQEMUCapsSet(qemuCaps, flag); + } + } + } + + VIR_FREE(nodes); + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + return qemuCaps; + +error: + VIR_FREE(nodes); + virObjectUnref(qemuCaps); + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + return NULL; +} + +static int +testQemuCapsCompare(virQEMUCapsPtr capsProvided, + virQEMUCapsPtr capsComputed) +{ + int ret = 0; + size_t i; + + for (i = 0; i < QEMU_CAPS_LAST; i++) { + if (virQEMUCapsGet(capsProvided, i) && + !virQEMUCapsGet(capsComputed, i)) { + fprintf(stderr, "Caps mismatch: capsComputed is missing %s\n", + virQEMUCapsTypeToString(i)); + ret = -1; + } + + if (virQEMUCapsGet(capsComputed, i) && + !virQEMUCapsGet(capsProvided, i)) { + fprintf(stderr, "Caps mismatch: capsProvided is missing %s\n", + virQEMUCapsTypeToString(i)); + ret = -1; + } + } + + return ret; +} + +static int +testQemuCaps(const void *opaque) +{ + int ret = -1; + const testQemuDataPtr data = (const testQemuDataPtr) opaque; + char *repliesFile = NULL, *capsFile = NULL; + char *replies = NULL, *caps = NULL; + qemuMonitorTestPtr mon = NULL; + virQEMUCapsPtr capsProvided = NULL, capsComputed = NULL; + + if (virAsprintf(&repliesFile, "%s/qemucapabilitiesdata/%s.replies", + abs_srcdir, data->base) < 0 || + virAsprintf(&capsFile, "%s/qemucapabilitiesdata/%s.caps", + abs_srcdir, data->base) < 0) + goto cleanup; + + if (virtTestLoadFile(repliesFile, &replies) < 0 || + virtTestLoadFile(capsFile, &caps) < 0) + goto cleanup; + + if (!(mon = testQemuFeedMonitor(replies, data->xmlopt))) + goto cleanup; + + if (!(capsProvided = testQemuGetCaps(caps))) + goto cleanup; + + if (!(capsComputed = virQEMUCapsNew())) + goto cleanup; + + if (virQEMUCapsInitQMPMonitor(capsComputed, + qemuMonitorTestGetMonitor(mon)) < 0) + goto cleanup; + + if (testQemuCapsCompare(capsProvided, capsComputed) < 0) + goto cleanup; + + ret = 0; +cleanup: + VIR_FREE(repliesFile); + VIR_FREE(capsFile); + VIR_FREE(replies); + VIR_FREE(caps); + qemuMonitorTestFree(mon); + virObjectUnref(capsProvided); + virObjectUnref(capsComputed); + return ret; +} + +static int +mymain(void) +{ + int ret = 0; + virDomainXMLOptionPtr xmlopt; + testQemuData data; + +#if !WITH_YAJL + fputs("libvirt not compiled with yajl, skipping this test\n", stderr); + return EXIT_AM_SKIP; +#endif + + if (virThreadInitialize() < 0 || + !(xmlopt = virQEMUDriverCreateXMLConf(NULL))) + return EXIT_FAILURE; + + virEventRegisterDefaultImpl(); + + data.xmlopt = xmlopt; + +#define DO_TEST(name) \ + data.base = name; \ + if (virtTestRun(name, 1, testQemuCaps, &data) < 0) \ + ret = -1 + + DO_TEST("caps_default"); + + virObjectUnref(xmlopt); + return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN(mymain) -- 1.8.1.5

On 09/23/2013 06:58 AM, Michal Privoznik wrote:
This test is there to ensure that our capabilities detection code isn't broken somehow.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- .gitignore | 1 + tests/Makefile.am | 12 +- tests/qemucapabilitiesdata/caps_default.caps | 132 ++ tests/qemucapabilitiesdata/caps_default.replies | 2519 +++++++++++++++++++++++
Big, but it has to be. Can you please document in the commit message how you captured the contents of this file, so that next time we add a file for another version, we can do the same sort of capturing? Also, does the file name need to be named after a particular qemu version?
+++ b/tests/qemucapabilitiesdata/caps_default.replies @@ -0,0 +1,2519 @@ +{ + "QMP": { + "version": { + "qemu": { + "micro": 3, + "minor": 5, + "major": 1
So this is based on qemu 1.5.3; notice how we have named files under tests/qemuhelpdata to make it obvious which version of qemu we captured data from.
+++ b/tests/qemucapabilitiestest.c
+ +static qemuMonitorTestPtr +testQemuFeedMonitor(char *replies, + virDomainXMLOptionPtr xmlopt) +{ + qemuMonitorTestPtr test = NULL; + char *token, *saveptr = NULL; + char *tmp = replies; + + /* Our JSON parser is stupid. It doesn't ignore whitespaces even though it + * should. Hence, a reply needs to be on a single line. However, the + * replies in the file are separated by a single empty line. So we must + * preprocess the file prior splitting it into set of replies. */
Yuck. We should probably fix that as a pre-requisite patch. There's no guarantee that future qemu will always output single-line JSON objects.
+ while ((tmp = strchr(tmp, '\n'))) { + if (*(tmp + 1) != '\n') { + *tmp = ' '; + tmp++; + } else { + tmp += 2; + } + }
Why are you tokenizing the file yourself...
+ + token = strtok_r(replies, "\n", &saveptr); + while (token) {
...only to repeat the tokenization via strtok_r? Since you already know that your file consists of entries separated by two newlines, why not turn the second \n into NUL and add the items yourself on your first pass through? Besides, if you fix the JSON parser to allow multiline input, then strtok_r won't help you find the doubled newlines very efficiently. Overall, I like where this is headed. Looking forward to v2 and to subsequent captures from more than just qemu 1.5.3. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 23.09.2013 18:57, Eric Blake wrote:
On 09/23/2013 06:58 AM, Michal Privoznik wrote:
This test is there to ensure that our capabilities detection code isn't broken somehow.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- .gitignore | 1 + tests/Makefile.am | 12 +- tests/qemucapabilitiesdata/caps_default.caps | 132 ++ tests/qemucapabilitiesdata/caps_default.replies | 2519 +++++++++++++++++++++++
Big, but it has to be. Can you please document in the commit message how you captured the contents of this file, so that next time we add a file for another version, we can do the same sort of capturing? Also, does the file name need to be named after a particular qemu version?
+++ b/tests/qemucapabilitiesdata/caps_default.replies @@ -0,0 +1,2519 @@ +{ + "QMP": { + "version": { + "qemu": { + "micro": 3, + "minor": 5, + "major": 1
So this is based on qemu 1.5.3; notice how we have named files under tests/qemuhelpdata to make it obvious which version of qemu we captured data from.
This is kind of tricky; The qemu capabilities (of any version) rely on configure options passed during the build. Hence, my 1.5.3 differs (in general) to yours 1.5.3; But I think we can name the files like caps_1.5.3-1, caps_1.5.3-2 (similar to RHEL package naming).
+++ b/tests/qemucapabilitiestest.c
+ +static qemuMonitorTestPtr +testQemuFeedMonitor(char *replies, + virDomainXMLOptionPtr xmlopt) +{ + qemuMonitorTestPtr test = NULL; + char *token, *saveptr = NULL; + char *tmp = replies; + + /* Our JSON parser is stupid. It doesn't ignore whitespaces even though it + * should. Hence, a reply needs to be on a single line. However, the + * replies in the file are separated by a single empty line. So we must + * preprocess the file prior splitting it into set of replies. */
Yuck. We should probably fix that as a pre-requisite patch. There's no guarantee that future qemu will always output single-line JSON objects.
I am not sure. I mean, we would have to count the matching { } to cut the reply into pieces. For instance, if we get a reply among with an event on the QMP monitor, it looks like this currently: {"return": ...}\n {"timestamp": ...}\n (I've added '\n' intentionally to stress the line break after each reply) And here comes the tricky part - we would have to parse json in order to parse json (I guess bare search for matching { } isn't enough - consider: {"return": {"blah": "}"}} ). Moreover, if we find that JSON snippet from qemu is not valid - there should be a restart character that would reset our JSON parser and translate it to START state so we can continue reading another reply. Something like we have for qemu-ga. Michal

This test is there to ensure that our capabilities detection code isn't broken somehow. How to gather test data: Firstly, the data is split into two separate files. The former (with suffix .replies) contains all the qemu replies. This is very fragile as introducing a new device can mean yet another monitor command and hence edit of this file in the future. But there's no better way of doing this. To get this data simply turn on debug logs and copy all the QEMU_MONITOR_IO_PROCESS lines. But be careful to not copy incomplete ones (yeah, we report some incomplete lines too). Long story short, at the libvirtd startup, a dummy qemu is spawn to get all the capabilities. The latter (with suffix .caps) contains capabilities XML. Just start a domain and copy the corresponding part from its state XML file. Including <qemuCaps> tag. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- .gitignore | 1 + tests/Makefile.am | 12 +- tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 133 ++ tests/qemucapabilitiesdata/caps_1.5.3-1.replies | 2519 +++++++++++++++++++++++ tests/qemucapabilitiestest.c | 241 +++ 5 files changed, 2904 insertions(+), 2 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_1.5.3-1.caps create mode 100644 tests/qemucapabilitiesdata/caps_1.5.3-1.replies create mode 100644 tests/qemucapabilitiestest.c diff --git a/.gitignore b/.gitignore index edd5d26..b5824dc 100644 --- a/.gitignore +++ b/.gitignore @@ -176,6 +176,7 @@ /tests/openvzutilstest /tests/qemuagenttest /tests/qemuargv2xmltest +/tests/qemucapabilitiestest /tests/qemuhelptest /tests/qemuhotplugtest /tests/qemumonitorjsontest diff --git a/tests/Makefile.am b/tests/Makefile.am index 777758f..8597b49 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -82,6 +82,7 @@ EXTRA_DIST = \ nwfilterxml2xmlin \ nwfilterxml2xmlout \ oomtrace.pl \ + qemucapabilitiesdata \ qemuhelpdata \ qemuhotplugtestdata \ qemuxml2argvdata \ @@ -170,7 +171,7 @@ if WITH_QEMU test_programs += qemuxml2argvtest qemuxml2xmltest qemuxmlnstest \ qemuargv2xmltest qemuhelptest domainsnapshotxml2xmltest \ qemumonitortest qemumonitorjsontest qemuhotplugtest \ - qemuagenttest + qemuagenttest qemucapabilitiestest endif WITH_QEMU if WITH_LXC @@ -437,6 +438,13 @@ qemumonitorjsontest_SOURCES = \ $(NULL) qemumonitorjsontest_LDADD = libqemumonitortestutils.la $(qemu_LDADDS) +qemucapabilitiestest_SOURCES = \ + qemucapabilitiestest.c \ + testutils.c testutils.h \ + testutilsqemu.c testutilsqemu.h \ + $(NULL) +qemucapabilitiestest_LDADD = libqemumonitortestutils.la $(qemu_LDADDS) + qemuagenttest_SOURCES = \ qemuagenttest.c \ testutils.c testutils.h \ @@ -460,7 +468,7 @@ EXTRA_DIST += qemuxml2argvtest.c qemuxml2xmltest.c qemuargv2xmltest.c \ qemuxmlnstest.c qemuhelptest.c domainsnapshotxml2xmltest.c \ qemumonitortest.c testutilsqemu.c testutilsqemu.h \ qemumonitorjsontest.c qemuhotplugtest.c \ - qemuagenttest.c \ + qemuagenttest.c qemucapabilitiestest.c \ $(QEMUMONITORTESTUTILS_SOURCES) endif ! WITH_QEMU diff --git a/tests/qemucapabilitiesdata/caps_1.5.3-1.caps b/tests/qemucapabilitiesdata/caps_1.5.3-1.caps new file mode 100644 index 0000000..323ac82 --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_1.5.3-1.caps @@ -0,0 +1,133 @@ + <qemuCaps> + <flag name='vnc-colon'/> + <flag name='no-reboot'/> + <flag name='drive'/> + <flag name='name'/> + <flag name='uuid'/> + <flag name='vnet-hdr'/> + <flag name='migrate-qemu-tcp'/> + <flag name='migrate-qemu-exec'/> + <flag name='drive-cache-v2'/> + <flag name='drive-format'/> + <flag name='vga'/> + <flag name='0.10'/> + <flag name='mem-path'/> + <flag name='drive-serial'/> + <flag name='migrate-qemu-unix'/> + <flag name='chardev'/> + <flag name='enable-kvm'/> + <flag name='monitor-json'/> + <flag name='balloon'/> + <flag name='device'/> + <flag name='sdl'/> + <flag name='smp-topology'/> + <flag name='netdev'/> + <flag name='rtc'/> + <flag name='vhost-net'/> + <flag name='no-hpet'/> + <flag name='no-kvm-pit'/> + <flag name='pci-configfd'/> + <flag name='nodefconfig'/> + <flag name='boot-menu'/> + <flag name='fsdev'/> + <flag name='name-process'/> + <flag name='drive-readonly'/> + <flag name='smbios-type'/> + <flag name='vga-qxl'/> + <flag name='spice'/> + <flag name='vga-none'/> + <flag name='migrate-qemu-fd'/> + <flag name='boot-index'/> + <flag name='hda-duplex'/> + <flag name='drive-aio'/> + <flag name='pci-multibus'/> + <flag name='pci-bootindex'/> + <flag name='ccid-passthru'/> + <flag name='chardev-spicevmc'/> + <flag name='virtio-tx-alg'/> + <flag name='device-qxl-vga'/> + <flag name='pci-multifunction'/> + <flag name='virtio-blk-pci.ioeventfd'/> + <flag name='sga'/> + <flag name='virtio-blk-pci.event_idx'/> + <flag name='virtio-net-pci.event_idx'/> + <flag name='cache-directsync'/> + <flag name='piix3-usb-uhci'/> + <flag name='piix4-usb-uhci'/> + <flag name='usb-ehci'/> + <flag name='ich9-usb-ehci1'/> + <flag name='vt82c686b-usb-uhci'/> + <flag name='pci-ohci'/> + <flag name='usb-hub'/> + <flag name='no-shutdown'/> + <flag name='cache-unsafe'/> + <flag name='rombar'/> + <flag name='ich9-ahci'/> + <flag name='no-acpi'/> + <flag name='fsdev-readonly'/> + <flag name='virtio-blk-pci.scsi'/> + <flag name='blk-sg-io'/> + <flag name='drive-copy-on-read'/> + <flag name='cpu-host'/> + <flag name='fsdev-writeout'/> + <flag name='drive-iotune'/> + <flag name='system_wakeup'/> + <flag name='scsi-disk.channel'/> + <flag name='scsi-block'/> + <flag name='transaction'/> + <flag name='block-job-async'/> + <flag name='scsi-cd'/> + <flag name='ide-cd'/> + <flag name='no-user-config'/> + <flag name='hda-micro'/> + <flag name='dump-guest-memory'/> + <flag name='nec-usb-xhci'/> + <flag name='balloon-event'/> + <flag name='bridge'/> + <flag name='lsi'/> + <flag name='virtio-scsi-pci'/> + <flag name='blockio'/> + <flag name='disable-s3'/> + <flag name='disable-s4'/> + <flag name='ide-drive.wwn'/> + <flag name='scsi-disk.wwn'/> + <flag name='seccomp-sandbox'/> + <flag name='dump-guest-core'/> + <flag name='seamless-migration'/> + <flag name='block-commit'/> + <flag name='vnc'/> + <flag name='drive-mirror'/> + <flag name='usb-host.bootindex'/> + <flag name='blockdev-snapshot-sync'/> + <flag name='qxl'/> + <flag name='VGA'/> + <flag name='cirrus-vga'/> + <flag name='vmware-svga'/> + <flag name='usb-serial'/> + <flag name='usb-net'/> + <flag name='add-fd'/> + <flag name='nbd-server'/> + <flag name='virtio-rng'/> + <flag name='rng-random'/> + <flag name='rng-egd'/> + <flag name='dtb'/> + <flag name='megasas'/> + <flag name='ipv6-migration'/> + <flag name='machine-opt'/> + <flag name='machine-usb-opt'/> + <flag name='pci-bridge'/> + <flag name='vfio-pci'/> + <flag name='vfio-pci.bootindex'/> + <flag name='scsi-generic'/> + <flag name='scsi-generic.bootindex'/> + <flag name='mem-merge'/> + <flag name='vnc-websocket'/> + <flag name='drive-discard'/> + <flag name='mlock'/> + <flag name='vnc-share-policy'/> + <flag name='device-del-event'/> + <flag name='dmi-to-pci-bridge'/> + <flag name='usb-storage'/> + <flag name='usb-storage.removable'/> + <flag name='ich9-intel-hda'/> + </qemuCaps> diff --git a/tests/qemucapabilitiesdata/caps_1.5.3-1.replies b/tests/qemucapabilitiesdata/caps_1.5.3-1.replies new file mode 100644 index 0000000..8ff17ce --- /dev/null +++ b/tests/qemucapabilitiesdata/caps_1.5.3-1.replies @@ -0,0 +1,2519 @@ +{ + "QMP": { + "version": { + "qemu": { + "micro": 3, + "minor": 5, + "major": 1 + }, + "package": "" + }, + "capabilities": [ + ] + } +} + +{ + "return": { + }, + "id": "libvirt-1" +} + +{ + "return": { + "qemu": { + "micro": 3, + "minor": 5, + "major": 1 + }, + "package": "" + }, + "id": "libvirt-2" +} + +{ + "return": { + "arch": "x86_64" + }, + "id": "libvirt-3" +} + +{ + "return": [ + { + "name": "chardev-remove" + }, + { + "name": "chardev-add" + }, + { + "name": "query-tpm-types" + }, + { + "name": "query-tpm-models" + }, + { + "name": "query-tpm" + }, + { + "name": "query-target" + }, + { + "name": "query-cpu-definitions" + }, + { + "name": "query-machines" + }, + { + "name": "device-list-properties" + }, + { + "name": "qom-list-types" + }, + { + "name": "change-vnc-password" + }, + { + "name": "nbd-server-stop" + }, + { + "name": "nbd-server-add" + }, + { + "name": "nbd-server-start" + }, + { + "name": "qom-get" + }, + { + "name": "qom-set" + }, + { + "name": "qom-list" + }, + { + "name": "query-block-jobs" + }, + { + "name": "query-balloon" + }, + { + "name": "query-migrate-capabilities" + }, + { + "name": "migrate-set-capabilities" + }, + { + "name": "query-migrate" + }, + { + "name": "query-command-line-options" + }, + { + "name": "query-uuid" + }, + { + "name": "query-name" + }, + { + "name": "query-spice" + }, + { + "name": "query-vnc" + }, + { + "name": "query-mice" + }, + { + "name": "query-status" + }, + { + "name": "query-kvm" + }, + { + "name": "query-pci" + }, + { + "name": "query-cpus" + }, + { + "name": "query-blockstats" + }, + { + "name": "query-block" + }, + { + "name": "query-chardev" + }, + { + "name": "query-events" + }, + { + "name": "query-commands" + }, + { + "name": "query-version" + }, + { + "name": "human-monitor-command" + }, + { + "name": "qmp_capabilities" + }, + { + "name": "add_client" + }, + { + "name": "expire_password" + }, + { + "name": "set_password" + }, + { + "name": "block_set_io_throttle" + }, + { + "name": "block_passwd" + }, + { + "name": "query-fdsets" + }, + { + "name": "remove-fd" + }, + { + "name": "add-fd" + }, + { + "name": "closefd" + }, + { + "name": "getfd" + }, + { + "name": "set_link" + }, + { + "name": "balloon" + }, + { + "name": "drive-mirror" + }, + { + "name": "blockdev-snapshot-sync" + }, + { + "name": "transaction" + }, + { + "name": "block-job-complete" + }, + { + "name": "block-job-resume" + }, + { + "name": "block-job-pause" + }, + { + "name": "block-job-cancel" + }, + { + "name": "block-job-set-speed" + }, + { + "name": "block-commit" + }, + { + "name": "block-stream" + }, + { + "name": "block_resize" + }, + { + "name": "netdev_del" + }, + { + "name": "netdev_add" + }, + { + "name": "dump-guest-memory" + }, + { + "name": "client_migrate_info" + }, + { + "name": "migrate_set_downtime" + }, + { + "name": "migrate_set_speed" + }, + { + "name": "query-migrate-cache-size" + }, + { + "name": "migrate-set-cache-size" + }, + { + "name": "migrate_cancel" + }, + { + "name": "migrate" + }, + { + "name": "xen-set-global-dirty-log" + }, + { + "name": "xen-save-devices-state" + }, + { + "name": "ringbuf-read" + }, + { + "name": "ringbuf-write" + }, + { + "name": "inject-nmi" + }, + { + "name": "pmemsave" + }, + { + "name": "memsave" + }, + { + "name": "cpu-add" + }, + { + "name": "cpu" + }, + { + "name": "send-key" + }, + { + "name": "device_del" + }, + { + "name": "device_add" + }, + { + "name": "system_powerdown" + }, + { + "name": "system_reset" + }, + { + "name": "system_wakeup" + }, + { + "name": "cont" + }, + { + "name": "stop" + }, + { + "name": "screendump" + }, + { + "name": "change" + }, + { + "name": "eject" + }, + { + "name": "quit" + } + ], + "id": "libvirt-4" +} + +{ + "return": { + "fd": 10, + "fdset-id": 0 + }, + "id": "libvirt-5" +} + +{ + "return": [ + { + "name": "GUEST_PANICKED" + }, + { + "name": "SPICE_MIGRATE_COMPLETED" + }, + { + "name": "BALLOON_CHANGE" + }, + { + "name": "WAKEUP" + }, + { + "name": "SUSPEND_DISK" + }, + { + "name": "SUSPEND" + }, + { + "name": "DEVICE_TRAY_MOVED" + }, + { + "name": "DEVICE_DELETED" + }, + { + "name": "BLOCK_JOB_READY" + }, + { + "name": "BLOCK_JOB_ERROR" + }, + { + "name": "BLOCK_JOB_CANCELLED" + }, + { + "name": "BLOCK_JOB_COMPLETED" + }, + { + "name": "SPICE_DISCONNECTED" + }, + { + "name": "SPICE_INITIALIZED" + }, + { + "name": "SPICE_CONNECTED" + }, + { + "name": "WATCHDOG" + }, + { + "name": "RTC_CHANGE" + }, + { + "name": "BLOCK_IO_ERROR" + }, + { + "name": "VNC_DISCONNECTED" + }, + { + "name": "VNC_INITIALIZED" + }, + { + "name": "VNC_CONNECTED" + }, + { + "name": "RESUME" + }, + { + "name": "STOP" + }, + { + "name": "POWERDOWN" + }, + { + "name": "RESET" + }, + { + "name": "SHUTDOWN" + } + ], + "id": "libvirt-6" +} + +{ + "return": [ + { + "name": "ICH9 LPC" + }, + { + "name": "x86_64-cpu" + }, + { + "name": "port92" + }, + { + "name": "virtio-net-pci" + }, + { + "name": "virtio-scsi-device" + }, + { + "name": "apic" + }, + { + "name": "pc-testdev" + }, + { + "name": "virtio-blk-device" + }, + { + "name": "virtio-scsi-pci" + }, + { + "name": "exynos4210-ehci-usb" + }, + { + "name": "i6300esb" + }, + { + "name": "usb-host" + }, + { + "name": "ich9-usb-ehci2" + }, + { + "name": "usb-ehci" + }, + { + "name": "ich9-ahci" + }, + { + "name": "ich9-usb-ehci1" + }, + { + "name": "isa-ide" + }, + { + "name": "ICH9 SMB" + }, + { + "name": "virtio-balloon-pci" + }, + { + "name": "vt82c686b-usb-uhci" + }, + { + "name": "i82558b" + }, + { + "name": "i82558a" + }, + { + "name": "isa-fdc" + }, + { + "name": "isabus-bridge" + }, + { + "name": "pvpanic" + }, + { + "name": "i2c-bus" + }, + { + "name": "piix3-ide" + }, + { + "name": "ioapic" + }, + { + "name": "pci-bridge" + }, + { + "name": "HDA" + }, + { + "name": "am53c974" + }, + { + "name": "xlnx,ps7-usb" + }, + { + "name": "vmmouse" + }, + { + "name": "sb16" + }, + { + "name": "i82801b11-bridge" + }, + { + "name": "vmxnet3" + }, + { + "name": "isa-cirrus-vga" + }, + { + "name": "dc390" + }, + { + "name": "vmware-svga" + }, + { + "name": "smbus-eeprom" + }, + { + "name": "piix4-usb-uhci" + }, + { + "name": "ccid-card-passthru" + }, + { + "name": "i82801" + }, + { + "name": "fw_cfg" + }, + { + "name": "qxl" + }, + { + "name": "piix3-usb-uhci" + }, + { + "name": "ib700" + }, + { + "name": "usb-audio" + }, + { + "name": "i82557c" + }, + { + "name": "i82557b" + }, + { + "name": "i82557a" + }, + { + "name": "IndustryPack" + }, + { + "name": "hpet" + }, + { + "name": "pvscsi" + }, + { + "name": "rtl8139" + }, + { + "name": "isa-applesmc" + }, + { + "name": "kvm-pci-assign" + }, + { + "name": "container" + }, + { + "name": "cfi.pflash01" + }, + { + "name": "usb-kbd" + }, + { + "name": "vfio-pci" + }, + { + "name": "isa-vga" + }, + { + "name": "pci-testdev" + }, + { + "name": "usb-tablet" + }, + { + "name": "vmport" + }, + { + "name": "virtio-rng-pci" + }, + { + "name": "kvmvapic" + }, + { + "name": "usb-bt-dongle" + }, + { + "name": "sysbus-fdc" + }, + { + "name": "piix4-ide" + }, + { + "name": "e1000" + }, + { + "name": "AC97" + }, + { + "name": "ipoctal232" + }, + { + "name": "mch" + }, + { + "name": "mc146818rtc" + }, + { + "name": "ivshmem" + }, + { + "name": "usb-ccid" + }, + { + "name": "sysbus-ahci" + }, + { + "name": "kvmclock" + }, + { + "name": "i82562" + }, + { + "name": "hda-output" + }, + { + "name": "pci-serial-4x" + }, + { + "name": "ccid-bus" + }, + { + "name": "i82559er" + }, + { + "name": "virtio-balloon-device" + }, + { + "name": "i8042" + }, + { + "name": "megasas" + }, + { + "name": "intel-hda" + }, + { + "name": "hda-duplex" + }, + { + "name": "virtio-serial-pci" + }, + { + "name": "ne2k_pci" + }, + { + "name": "ich9-usb-uhci6" + }, + { + "name": "ich9-usb-uhci5" + }, + { + "name": "ich9-usb-uhci3" + }, + { + "name": "virtconsole" + }, + { + "name": "ich9-usb-uhci4" + }, + { + "name": "isa-parallel" + }, + { + "name": "pci-serial" + }, + { + "name": "ich9-usb-uhci2" + }, + { + "name": "ich9-usb-uhci1" + }, + { + "name": "PCI" + }, + { + "name": "adlib" + }, + { + "name": "SUNW,fdtwo" + }, + { + "name": "ide-cd" + }, + { + "name": "isa-debugcon" + }, + { + "name": "usb-bot" + }, + { + "name": "i82551" + }, + { + "name": "i82550" + }, + { + "name": "isa-serial" + }, + { + "name": "PCIE" + }, + { + "name": "kvm-ioapic" + }, + { + "name": "nec-usb-xhci" + }, + { + "name": "System" + }, + { + "name": "kvm-apic" + }, + { + "name": "ich9-intel-hda" + }, + { + "name": "virtio-net-device" + }, + { + "name": "usb-wacom-tablet" + }, + { + "name": "PIIX4_PM" + }, + { + "name": "kvm-i8259" + }, + { + "name": "q35-pcihost" + }, + { + "name": "scsi-cd" + }, + { + "name": "pci-ohci" + }, + { + "name": "i440FX" + }, + { + "name": "usb-braille" + }, + { + "name": "virtserialport" + }, + { + "name": "pci-serial-2x" + }, + { + "name": "xio3130-downstream" + }, + { + "name": "rng-random" + }, + { + "name": "hda-micro" + }, + { + "name": "scsi-disk" + }, + { + "name": "vhost-scsi" + }, + { + "name": "lsi53c895a" + }, + { + "name": "qxl-vga" + }, + { + "name": "SCSI" + }, + { + "name": "pcnet" + }, + { + "name": "scsi-generic" + }, + { + "name": "virtio-scsi-common" + }, + { + "name": "virtio-serial-device" + }, + { + "name": "virtio-serial-bus" + }, + { + "name": "icc-bridge" + }, + { + "name": "usb-bus" + }, + { + "name": "ne2k_isa" + }, + { + "name": "IDE" + }, + { + "name": "usb-net" + }, + { + "name": "usb-hub" + }, + { + "name": "i440FX-pcihost" + }, + { + "name": "usb-mouse" + }, + { + "name": "isa-i8259" + }, + { + "name": "ISA" + }, + { + "name": "cs4231a" + }, + { + "name": "usb-serial" + }, + { + "name": "pc-sysfw" + }, + { + "name": "scsi-block" + }, + { + "name": "sga" + }, + { + "name": "isa-debug-exit" + }, + { + "name": "virtio-rng-device" + }, + { + "name": "ioh3420" + }, + { + "name": "ES1370" + }, + { + "name": "PIIX3" + }, + { + "name": "isa-pcspk" + }, + { + "name": "ide-hd" + }, + { + "name": "rng-egd" + }, + { + "name": "cirrus-vga" + }, + { + "name": "kvm-pit" + }, + { + "name": "qemu-console" + }, + { + "name": "icc-bus" + }, + { + "name": "ide-drive" + }, + { + "name": "x3130-upstream" + }, + { + "name": "virtio-pci-bus" + }, + { + "name": "usb-uas" + }, + { + "name": "vhost-scsi-pci" + }, + { + "name": "virtio-blk-pci" + }, + { + "name": "sysbus-ohci" + }, + { + "name": "esp" + }, + { + "name": "piix3-ide-xen" + }, + { + "name": "i82559c" + }, + { + "name": "i82559b" + }, + { + "name": "i82559a" + }, + { + "name": "scsi-hd" + }, + { + "name": "PIIX3-xen" + }, + { + "name": "usb-storage" + }, + { + "name": "isa-pit" + }, + { + "name": "tpci200" + }, + { + "name": "gus" + }, + { + "name": "VGA" + } + ], + "id": "libvirt-7" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "scsi", + "type": "on/off" + }, + { + "name": "config-wce", + "type": "on/off" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "secs", + "type": "uint32" + }, + { + "name": "heads", + "type": "uint32" + }, + { + "name": "cyls", + "type": "uint32" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + }, + { + "name": "event_idx", + "type": "on/off" + }, + { + "name": "indirect_desc", + "type": "on/off" + }, + { + "name": "x-data-plane", + "type": "on/off" + }, + { + "name": "vectors", + "type": "uint32" + }, + { + "name": "ioeventfd", + "type": "on/off" + }, + { + "name": "class", + "type": "hex32" + } + ], + "id": "libvirt-8" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "tx", + "type": "string" + }, + { + "name": "x-txburst", + "type": "int32" + }, + { + "name": "x-txtimer", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "netdev", + "type": "netdev" + }, + { + "name": "vlan", + "type": "vlan" + }, + { + "name": "mac", + "type": "macaddr" + }, + { + "name": "mq", + "type": "on/off" + }, + { + "name": "ctrl_mac_addr", + "type": "on/off" + }, + { + "name": "ctrl_rx_extra", + "type": "on/off" + }, + { + "name": "ctrl_vlan", + "type": "on/off" + }, + { + "name": "ctrl_rx", + "type": "on/off" + }, + { + "name": "ctrl_vq", + "type": "on/off" + }, + { + "name": "status", + "type": "on/off" + }, + { + "name": "mrg_rxbuf", + "type": "on/off" + }, + { + "name": "host_ufo", + "type": "on/off" + }, + { + "name": "host_ecn", + "type": "on/off" + }, + { + "name": "host_tso6", + "type": "on/off" + }, + { + "name": "host_tso4", + "type": "on/off" + }, + { + "name": "guest_ufo", + "type": "on/off" + }, + { + "name": "guest_ecn", + "type": "on/off" + }, + { + "name": "guest_tso6", + "type": "on/off" + }, + { + "name": "guest_tso4", + "type": "on/off" + }, + { + "name": "gso", + "type": "on/off" + }, + { + "name": "guest_csum", + "type": "on/off" + }, + { + "name": "csum", + "type": "on/off" + }, + { + "name": "event_idx", + "type": "on/off" + }, + { + "name": "indirect_desc", + "type": "on/off" + }, + { + "name": "vectors", + "type": "uint32" + }, + { + "name": "ioeventfd", + "type": "on/off" + } + ], + "id": "libvirt-9" +} + +{ + "id": "libvirt-10", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-blk-ccw' not found" + } +} + +{ + "id": "libvirt-11", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-net-ccw' not found" + } +} + +{ + "id": "libvirt-12", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-blk-s390' not found" + } +} + +{ + "id": "libvirt-13", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'virtio-net-s390' not found" + } +} + +{ + "id": "libvirt-14", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'pci-assign' not found" + } +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "configfd", + "type": "string" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "share_intx", + "type": "on/off" + }, + { + "name": "prefer_msi", + "type": "on/off" + }, + { + "name": "host", + "type": "pci-host-devaddr" + } + ], + "id": "libvirt-15" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "x-vga", + "type": "on/off" + }, + { + "name": "x-intx-mmap-timeout-ms", + "type": "uint32" + }, + { + "name": "host", + "type": "pci-host-devaddr" + } + ], + "id": "libvirt-16" +} + +{ + "return": [ + { + "name": "lun", + "type": "uint32" + }, + { + "name": "scsi-id", + "type": "uint32" + }, + { + "name": "channel", + "type": "uint32" + }, + { + "name": "wwn", + "type": "hex64" + }, + { + "name": "dpofua", + "type": "on/off" + }, + { + "name": "removable", + "type": "on/off" + }, + { + "name": "product", + "type": "string" + }, + { + "name": "vendor", + "type": "string" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "ver", + "type": "string" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-17" +} + +{ + "return": [ + { + "name": "unit", + "type": "uint32" + }, + { + "name": "model", + "type": "string" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "wwn", + "type": "hex64" + }, + { + "name": "ver", + "type": "string" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-18" +} + +{ + "return": [ + { + "name": "command_serr_enable", + "type": "on/off" + }, + { + "name": "multifunction", + "type": "on/off" + }, + { + "name": "rombar", + "type": "uint32" + }, + { + "name": "romfile", + "type": "string" + }, + { + "name": "addr", + "type": "pci-devfn" + }, + { + "name": "s4_val", + "type": "uint8" + }, + { + "name": "disable_s4", + "type": "uint8" + }, + { + "name": "disable_s3", + "type": "uint8" + }, + { + "name": "smb_io_base", + "type": "uint32" + } + ], + "id": "libvirt-19" +} + +{ + "id": "libvirt-20", + "error": { + "class": "DeviceNotFound", + "desc": "Device 'usb-redir' not found" + } +} + +{ + "return": [ + { + "name": "full-path", + "type": "on/off" + }, + { + "name": "port", + "type": "string" + }, + { + "name": "pipeline", + "type": "on/off" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "isobufs", + "type": "uint32" + }, + { + "name": "productid", + "type": "hex32" + }, + { + "name": "vendorid", + "type": "hex32" + }, + { + "name": "hostport", + "type": "string" + }, + { + "name": "hostaddr", + "type": "uint32" + }, + { + "name": "hostbus", + "type": "uint32" + } + ], + "id": "libvirt-21" +} + +{ + "return": [ + { + "name": "lun", + "type": "uint32" + }, + { + "name": "scsi-id", + "type": "uint32" + }, + { + "name": "channel", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-22" +} + +{ + "return": [ + ], + "id": "libvirt-23" +} + +{ + "return": [ + { + "name": "MCFG", + "type": "uint64" + } + ], + "id": "libvirt-24" +} + +{ + "return": [ + { + "name": "full-path", + "type": "on/off" + }, + { + "name": "port", + "type": "string" + }, + { + "name": "removable", + "type": "on/off" + }, + { + "name": "serial", + "type": "string" + }, + { + "name": "discard_granularity", + "type": "uint32" + }, + { + "name": "bootindex", + "type": "int32" + }, + { + "name": "opt_io_size", + "type": "uint32" + }, + { + "name": "min_io_size", + "type": "uint16" + }, + { + "name": "physical_block_size", + "type": "blocksize" + }, + { + "name": "logical_block_size", + "type": "blocksize" + }, + { + "name": "drive", + "type": "drive" + } + ], + "id": "libvirt-25" +} + +{ + "return": [ + { + "name": "pc-q35-1.4", + "cpu-max": 255 + }, + { + "name": "pc-q35-1.5", + "cpu-max": 255, + "alias": "q35" + }, + { + "name": "isapc", + "cpu-max": 1 + }, + { + "name": "pc-0.10", + "cpu-max": 255 + }, + { + "name": "pc-0.11", + "cpu-max": 255 + }, + { + "name": "pc-0.12", + "cpu-max": 255 + }, + { + "name": "pc-0.13", + "cpu-max": 255 + }, + { + "name": "pc-0.14", + "cpu-max": 255 + }, + { + "name": "pc-0.15", + "cpu-max": 255 + }, + { + "name": "pc-1.0", + "cpu-max": 255 + }, + { + "name": "pc-1.1", + "cpu-max": 255 + }, + { + "name": "pc-1.2", + "cpu-max": 255 + }, + { + "name": "pc-1.3", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-1.4", + "cpu-max": 255 + }, + { + "name": "pc-i440fx-1.5", + "is-default": true, + "cpu-max": 255, + "alias": "pc" + }, + { + "name": "none", + "cpu-max": 1 + } + ], + "id": "libvirt-26" +} + +{ + "return": [ + { + "name": "Opteron_G5" + }, + { + "name": "Opteron_G4" + }, + { + "name": "Opteron_G3" + }, + { + "name": "Opteron_G2" + }, + { + "name": "Opteron_G1" + }, + { + "name": "Haswell" + }, + { + "name": "SandyBridge" + }, + { + "name": "Westmere" + }, + { + "name": "Nehalem" + }, + { + "name": "Penryn" + }, + { + "name": "Conroe" + }, + { + "name": "n270" + }, + { + "name": "athlon" + }, + { + "name": "pentium3" + }, + { + "name": "pentium2" + }, + { + "name": "pentium" + }, + { + "name": "486" + }, + { + "name": "coreduo" + }, + { + "name": "kvm32" + }, + { + "name": "qemu32" + }, + { + "name": "kvm64" + }, + { + "name": "core2duo" + }, + { + "name": "phenom" + }, + { + "name": "qemu64" + } + ], + "id": "libvirt-27" +} + +{ + "return": { + "enabled": false, + "present": true + }, + "id": "libvirt-28" +} + +{ + "return": [ + ], + "id": "libvirt-29" +} + +{ + "return": [ + ], + "id": "libvirt-30" +} + +{ + "return": [ + { + "parameters": [ + { + "name": "seamless-migration", + "type": "boolean" + }, + { + "name": "playback-compression", + "type": "boolean" + }, + { + "name": "agent-mouse", + "type": "boolean" + }, + { + "name": "streaming-video", + "type": "string" + }, + { + "name": "zlib-glz-wan-compression", + "type": "string" + }, + { + "name": "jpeg-wan-compression", + "type": "string" + }, + { + "name": "image-compression", + "type": "string" + }, + { + "name": "plaintext-channel", + "type": "string" + }, + { + "name": "tls-channel", + "type": "string" + }, + { + "name": "tls-ciphers", + "type": "string" + }, + { + "name": "x509-dh-key-file", + "type": "string" + }, + { + "name": "x509-cacert-file", + "type": "string" + }, + { + "name": "x509-cert-file", + "type": "string" + }, + { + "name": "x509-key-password", + "type": "string" + }, + { + "name": "x509-key-file", + "type": "string" + }, + { + "name": "x509-dir", + "type": "string" + }, + { + "name": "sasl", + "type": "boolean" + }, + { + "name": "disable-copy-paste", + "type": "boolean" + }, + { + "name": "disable-ticketing", + "type": "boolean" + }, + { + "name": "password", + "type": "string" + }, + { + "name": "ipv6", + "type": "boolean" + }, + { + "name": "ipv4", + "type": "boolean" + }, + { + "name": "addr", + "type": "string" + }, + { + "name": "tls-port", + "type": "number" + }, + { + "name": "port", + "type": "number" + } + ], + "option": "spice" + }, + { + "parameters": [ + ], + "option": "acpi" + }, + { + "parameters": [ + { + "name": "sock_fd", + "type": "number" + }, + { + "name": "socket", + "type": "string" + }, + { + "name": "readonly", + "type": "boolean" + }, + { + "name": "writeout", + "type": "string" + }, + { + "name": "security_model", + "type": "string" + }, + { + "name": "mount_tag", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "fsdriver", + "type": "string" + } + ], + "option": "virtfs" + }, + { + "parameters": [ + { + "name": "sock_fd", + "type": "number" + }, + { + "name": "socket", + "type": "string" + }, + { + "name": "readonly", + "type": "boolean" + }, + { + "name": "writeout", + "type": "string" + }, + { + "name": "security_model", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "fsdriver", + "type": "string" + } + ], + "option": "fsdev" + }, + { + "parameters": [ + { + "name": "mlock", + "type": "boolean" + } + ], + "option": "realtime" + }, + { + "parameters": [ + ], + "option": "tpmdev" + }, + { + "parameters": [ + ], + "option": "object" + }, + { + "parameters": [ + { + "name": "opaque", + "help": "free-form string used to describe fd", + "type": "string" + }, + { + "name": "set", + "help": "ID of the fd set to add fd to", + "type": "number" + }, + { + "name": "fd", + "help": "file descriptor of which a duplicate is added to fd set", + "type": "number" + } + ], + "option": "add-fd" + }, + { + "parameters": [ + { + "name": "enable", + "type": "boolean" + } + ], + "option": "sandbox" + }, + { + "parameters": [ + { + "name": "strict", + "type": "string" + }, + { + "name": "reboot-timeout", + "type": "string" + }, + { + "name": "splash-time", + "type": "string" + }, + { + "name": "splash", + "type": "string" + }, + { + "name": "menu", + "type": "string" + }, + { + "name": "once", + "type": "string" + }, + { + "name": "order", + "type": "string" + } + ], + "option": "boot-opts" + }, + { + "parameters": [ + { + "name": "usb", + "help": "Set on/off to enable/disable usb", + "type": "boolean" + }, + { + "name": "mem-merge", + "help": "enable/disable memory merge support", + "type": "boolean" + }, + { + "name": "dump-guest-core", + "help": "Include guest memory in a core dump", + "type": "boolean" + }, + { + "name": "dt_compatible", + "help": "Overrides the \"compatible\" property of the dt root node", + "type": "string" + }, + { + "name": "phandle_start", + "help": "The first phandle ID we may generate dynamically", + "type": "string" + }, + { + "name": "dumpdtb", + "help": "Dump current dtb to a file and quit", + "type": "string" + }, + { + "name": "dtb", + "help": "Linux kernel device tree file", + "type": "string" + }, + { + "name": "append", + "help": "Linux kernel command line", + "type": "string" + }, + { + "name": "initrd", + "help": "Linux initial ramdisk file", + "type": "string" + }, + { + "name": "kernel", + "help": "Linux kernel image file", + "type": "string" + }, + { + "name": "kvm_shadow_mem", + "help": "KVM shadow MMU size", + "type": "size" + }, + { + "name": "kernel_irqchip", + "help": "use KVM in-kernel irqchip", + "type": "boolean" + }, + { + "name": "accel", + "help": "accelerator list", + "type": "string" + }, + { + "name": "type", + "help": "emulated machine", + "type": "string" + } + ], + "option": "machine" + }, + { + "parameters": [ + { + "name": "romfile", + "type": "string" + }, + { + "name": "bootindex", + "type": "number" + } + ], + "option": "option-rom" + }, + { + "parameters": [ + { + "name": "file", + "type": "string" + }, + { + "name": "events", + "type": "string" + } + ], + "option": "trace" + }, + { + "parameters": [ + { + "name": "pretty", + "type": "boolean" + }, + { + "name": "default", + "type": "boolean" + }, + { + "name": "chardev", + "type": "string" + }, + { + "name": "mode", + "type": "string" + } + ], + "option": "mon" + }, + { + "parameters": [ + { + "name": "value", + "type": "string" + }, + { + "name": "property", + "type": "string" + }, + { + "name": "driver", + "type": "string" + } + ], + "option": "global" + }, + { + "parameters": [ + { + "name": "driftfix", + "type": "string" + }, + { + "name": "clock", + "type": "string" + }, + { + "name": "base", + "type": "string" + } + ], + "option": "rtc" + }, + { + "parameters": [ + ], + "option": "net" + }, + { + "parameters": [ + ], + "option": "netdev" + }, + { + "parameters": [ + ], + "option": "device" + }, + { + "parameters": [ + { + "name": "size", + "type": "size" + }, + { + "name": "debug", + "type": "number" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "signal", + "type": "boolean" + }, + { + "name": "mux", + "type": "boolean" + }, + { + "name": "rows", + "type": "number" + }, + { + "name": "cols", + "type": "number" + }, + { + "name": "height", + "type": "number" + }, + { + "name": "width", + "type": "number" + }, + { + "name": "telnet", + "type": "boolean" + }, + { + "name": "delay", + "type": "boolean" + }, + { + "name": "server", + "type": "boolean" + }, + { + "name": "wait", + "type": "boolean" + }, + { + "name": "ipv6", + "type": "boolean" + }, + { + "name": "ipv4", + "type": "boolean" + }, + { + "name": "to", + "type": "number" + }, + { + "name": "localport", + "type": "string" + }, + { + "name": "localaddr", + "type": "string" + }, + { + "name": "port", + "type": "string" + }, + { + "name": "host", + "type": "string" + }, + { + "name": "path", + "type": "string" + }, + { + "name": "backend", + "type": "string" + } + ], + "option": "chardev" + }, + { + "parameters": [ + { + "name": "boot", + "help": "(deprecated, ignored)", + "type": "boolean" + }, + { + "name": "copy-on-read", + "help": "copy read data from backing file into image file", + "type": "boolean" + }, + { + "name": "bps_wr", + "help": "limit write bytes per second", + "type": "number" + }, + { + "name": "bps_rd", + "help": "limit read bytes per second", + "type": "number" + }, + { + "name": "bps", + "help": "limit total bytes per second", + "type": "number" + }, + { + "name": "iops_wr", + "help": "limit write operations per second", + "type": "number" + }, + { + "name": "iops_rd", + "help": "limit read operations per second", + "type": "number" + }, + { + "name": "iops", + "help": "limit total I/O operations per second", + "type": "number" + }, + { + "name": "readonly", + "help": "open drive file as read-only", + "type": "boolean" + }, + { + "name": "addr", + "help": "pci address (virtio only)", + "type": "string" + }, + { + "name": "werror", + "help": "write error action", + "type": "string" + }, + { + "name": "rerror", + "help": "read error action", + "type": "string" + }, + { + "name": "serial", + "help": "disk serial number", + "type": "string" + }, + { + "name": "format", + "help": "disk format (raw, qcow2, ...)", + "type": "string" + }, + { + "name": "aio", + "help": "host AIO implementation (threads, native)", + "type": "string" + }, + { + "name": "cache", + "help": "host cache usage (none, writeback, writethrough, directsync, unsafe)", + "type": "string" + }, + { + "name": "discard", + "help": "discard operation (ignore/off, unmap/on)", + "type": "string" + }, + { + "name": "file", + "help": "disk image", + "type": "string" + }, + { + "name": "snapshot", + "help": "enable/disable snapshot mode", + "type": "boolean" + }, + { + "name": "media", + "help": "media type (disk, cdrom)", + "type": "string" + }, + { + "name": "trans", + "help": "chs translation (auto, lba. none)", + "type": "string" + }, + { + "name": "secs", + "help": "number of sectors (ide disk geometry)", + "type": "number" + }, + { + "name": "heads", + "help": "number of heads (ide disk geometry)", + "type": "number" + }, + { + "name": "cyls", + "help": "number of cylinders (ide disk geometry)", + "type": "number" + }, + { + "name": "index", + "help": "index number", + "type": "number" + }, + { + "name": "if", + "help": "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)", + "type": "string" + }, + { + "name": "unit", + "help": "unit number (i.e. lun for scsi)", + "type": "number" + }, + { + "name": "bus", + "help": "bus number", + "type": "number" + } + ], + "option": "drive" + } + ], + "id": "libvirt-31" +} diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c new file mode 100644 index 0000000..acdc92d --- /dev/null +++ b/tests/qemucapabilitiestest.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2011-2013 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <config.h> + +#include "testutils.h" +#include "testutilsqemu.h" +#include "qemumonitortestutils.h" + + +#define VIR_FROM_THIS VIR_FROM_NONE + +typedef struct _testQemuData testQemuData; +typedef testQemuData * testQemuDataPtr; +struct _testQemuData { + virDomainXMLOptionPtr xmlopt; + const char *base; +}; + +static qemuMonitorTestPtr +testQemuFeedMonitor(char *replies, + virDomainXMLOptionPtr xmlopt) +{ + qemuMonitorTestPtr test = NULL; + char *tmp = replies; + char *singleReply = tmp; + + /* Our JSON parser expects replies to be separated by a newline character. + * Hence we must preprocess the file a bit. */ + while ((tmp = strchr(tmp, '\n'))) { + /* It is safe to touch (tmp + 1) since all strings ends with '\0'. */ + bool eof = *(tmp + 1) == '\0'; + + if (*(tmp + 1) != '\n') { + *tmp = ' '; + tmp++; + } else { + /* Cut off a single reply. */ + *(tmp + 1) = '\0'; + + if (test) { + if (qemuMonitorTestAddItem(test, NULL, singleReply) < 0) + goto error; + } else { + /* Create new mocked monitor with our greeting */ + if (!(test = qemuMonitorTestNew(true, xmlopt, NULL, NULL, singleReply))) + goto error; + } + + if (!eof) { + /* Move the @tmp and @singleReply. */ + tmp += 2; + singleReply = tmp; + } + } + + if (eof) + break; + } + + if (test && qemuMonitorTestAddItem(test, NULL, singleReply) < 0) + goto error; + + return test; + +error: + qemuMonitorTestFree(test); + return NULL; +} + +static virQEMUCapsPtr +testQemuGetCaps(char *caps) +{ + virQEMUCapsPtr qemuCaps = NULL; + xmlDocPtr xml; + xmlXPathContextPtr ctxt = NULL; + ssize_t i, n; + xmlNodePtr *nodes = NULL; + + if (!(xml = virXMLParseStringCtxt(caps, "(test caps)", &ctxt))) + goto error; + + if ((n = virXPathNodeSet("/qemuCaps/flag", ctxt, &nodes)) < 0) { + fprintf(stderr, "failed to parse qemu capabilities flags"); + goto error; + } + + if (n > 0) { + if (!(qemuCaps = virQEMUCapsNew())) + goto error; + + for (i = 0; i < n; i++) { + char *str = virXMLPropString(nodes[i], "name"); + if (str) { + int flag = virQEMUCapsTypeFromString(str); + if (flag < 0) { + fprintf(stderr, "Unknown qemu capabilities flag %s", str); + VIR_FREE(str); + goto error; + } + VIR_FREE(str); + virQEMUCapsSet(qemuCaps, flag); + } + } + } + + VIR_FREE(nodes); + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + return qemuCaps; + +error: + VIR_FREE(nodes); + virObjectUnref(qemuCaps); + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + return NULL; +} + +static int +testQemuCapsCompare(virQEMUCapsPtr capsProvided, + virQEMUCapsPtr capsComputed) +{ + int ret = 0; + size_t i; + + for (i = 0; i < QEMU_CAPS_LAST; i++) { + if (virQEMUCapsGet(capsProvided, i) && + !virQEMUCapsGet(capsComputed, i)) { + fprintf(stderr, "Caps mismatch: capsComputed is missing %s\n", + virQEMUCapsTypeToString(i)); + ret = -1; + } + + if (virQEMUCapsGet(capsComputed, i) && + !virQEMUCapsGet(capsProvided, i)) { + fprintf(stderr, "Caps mismatch: capsProvided is missing %s\n", + virQEMUCapsTypeToString(i)); + ret = -1; + } + } + + return ret; +} + +static int +testQemuCaps(const void *opaque) +{ + int ret = -1; + const testQemuDataPtr data = (const testQemuDataPtr) opaque; + char *repliesFile = NULL, *capsFile = NULL; + char *replies = NULL, *caps = NULL; + qemuMonitorTestPtr mon = NULL; + virQEMUCapsPtr capsProvided = NULL, capsComputed = NULL; + + if (virAsprintf(&repliesFile, "%s/qemucapabilitiesdata/%s.replies", + abs_srcdir, data->base) < 0 || + virAsprintf(&capsFile, "%s/qemucapabilitiesdata/%s.caps", + abs_srcdir, data->base) < 0) + goto cleanup; + + if (virtTestLoadFile(repliesFile, &replies) < 0 || + virtTestLoadFile(capsFile, &caps) < 0) + goto cleanup; + + if (!(mon = testQemuFeedMonitor(replies, data->xmlopt))) + goto cleanup; + + if (!(capsProvided = testQemuGetCaps(caps))) + goto cleanup; + + if (!(capsComputed = virQEMUCapsNew())) + goto cleanup; + + if (virQEMUCapsInitQMPMonitor(capsComputed, + qemuMonitorTestGetMonitor(mon)) < 0) + goto cleanup; + + if (testQemuCapsCompare(capsProvided, capsComputed) < 0) + goto cleanup; + + ret = 0; +cleanup: + VIR_FREE(repliesFile); + VIR_FREE(capsFile); + VIR_FREE(replies); + VIR_FREE(caps); + qemuMonitorTestFree(mon); + virObjectUnref(capsProvided); + virObjectUnref(capsComputed); + return ret; +} + +static int +mymain(void) +{ + int ret = 0; + virDomainXMLOptionPtr xmlopt; + testQemuData data; + +#if !WITH_YAJL + fputs("libvirt not compiled with yajl, skipping this test\n", stderr); + return EXIT_AM_SKIP; +#endif + + if (virThreadInitialize() < 0 || + !(xmlopt = virQEMUDriverCreateXMLConf(NULL))) + return EXIT_FAILURE; + + virEventRegisterDefaultImpl(); + + data.xmlopt = xmlopt; + +#define DO_TEST(name) \ + data.base = name; \ + if (virtTestRun(name, 1, testQemuCaps, &data) < 0) \ + ret = -1 + + DO_TEST("caps_1.5.3-1"); + + virObjectUnref(xmlopt); + return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN(mymain) -- 1.8.1.5

On 09/27/2013 04:25 AM, Michal Privoznik wrote:
This test is there to ensure that our capabilities detection code isn't broken somehow.
How to gather test data:
Firstly, the data is split into two separate files. The former (with suffix .replies) contains all the qemu replies. This is very fragile as introducing a new device can mean yet another monitor command and hence edit of this file in the future. But there's no better way of doing this. To get this data simply turn on debug logs and copy all the QEMU_MONITOR_IO_PROCESS lines. But be careful to not copy incomplete ones (yeah, we report some incomplete lines too). Long story short, at the libvirtd startup, a dummy qemu is spawn to get all the capabilities.
The latter (with suffix .caps) contains capabilities XML. Just start a domain and copy the corresponding part from its state XML file. Including <qemuCaps> tag.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- .gitignore | 1 + tests/Makefile.am | 12 +- tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 133 ++ tests/qemucapabilitiesdata/caps_1.5.3-1.replies | 2519 +++++++++++++++++++++++ tests/qemucapabilitiestest.c | 241 +++ 5 files changed, 2904 insertions(+), 2 deletions(-) create mode 100644 tests/qemucapabilitiesdata/caps_1.5.3-1.caps create mode 100644 tests/qemucapabilitiesdata/caps_1.5.3-1.replies create mode 100644 tests/qemucapabilitiestest.c
+static qemuMonitorTestPtr +testQemuFeedMonitor(char *replies, + virDomainXMLOptionPtr xmlopt) +{ + qemuMonitorTestPtr test = NULL; + char *tmp = replies; + char *singleReply = tmp; + + /* Our JSON parser expects replies to be separated by a newline character. + * Hence we must preprocess the file a bit. */ + while ((tmp = strchr(tmp, '\n'))) { + /* It is safe to touch (tmp + 1) since all strings ends with '\0'. */ + bool eof = *(tmp + 1) == '\0';
More compact as: bool eof = !tmp[1]; but that's not worth a respin :) ACK - as this just touches the testsuite, I'm fine with including it in 1.1.3 rather than waiting. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Michal Privoznik