diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2026-09-08 10:57:00 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2026-09-08 10:57:00 +0100 |
| commit | 55347990687e7bc5b6b0d624f290025726e8fbfa (patch) | |
| tree | 2411660c49d320cc998cc03c83935d9632429984 /tests | |
| parent | 9b0c50785c9f8f21a152261e7c5ec223771651f3 (diff) | |
| parent | 7e72db1dd160628f2b806d5a3fe25125f5aee823 (diff) | |
| download | qemu-master.tar.gz qemu-master.zip | |
Make HMP optional - follow-up
Fix left-overs tests failing when --disable-hmp
# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmqf2qkACgkQ2ujhCXWW
# nOWeMxAAoTlqczxh8myMSu/V/TbwrLEljhvxChtbjd5qVhULgUEieH9/8ufSwZYq
# IHW1tMRy4oUZc46sPvTp6SsjLlDl4sxNp22glMqrf2Bva7cpkoByAUq1dLwOU/kX
# IUIP0B87vYB6MKCvPXWno56BRd22bqAt13FifQ0BV+hfx2d56ot8MnHNpJhwSn4i
# YBrh414LBdj7Slp9rCDlq60TBueH0aNnlWD+Ihm8V6JMpCpNdBTwkZOLQNASruKP
# 78A7o4QJ8re+Q3A754A7UK+TbiyjKGYyVXuOKzYuaHPWcqq6UExzmPNwADSbNNlV
# L9gngjiphIRcyjr4RQuTFlwK1JRXSvvW5UBDnGMdtYoRoJKEdOx6eAjZBOAGxJ0C
# pNhGQk319XAapNJBGX9fRIRn9p/tIbGfdz0ZO0j9bHH5q4y0SEVGO8uokMvVuuiR
# RaWuzAWyI0eZFtJHbWydkBu7s/VHLtPNe13sjqoGzRvswDweiV8BgmAaLgF6okQt
# Nk2h8KSduufTHiPHLFRI0tOcoScEj/LqzO5dEnDpfDEJujTlHC2FaaP/Z9CyBY4B
# N0r+ZuwwugfAl99Gx/8tvONRm86lxAQmk5IADLCA8bG06AkGiOKS1PoNLtR2hIUU
# +9iQFFwwWBqS+WvH9jPCCEKuvNBCREU/rjR2Qzb5TJeVOAoz3Kk=
# =3G/P
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Sep 8 10:51:37 2026 BST
# gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full]
# gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full]
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5
* tag 'nohmp-pr-v1' of https://gitlab.com/marcandre.lureau/qemu:
tests: fix qemu:func-hexagon-linters
qtest: compile out HMP helper when !CONFIG_HMP
tests/drive_del-test: compile out HMP-dependent tests when !CONFIG_HMP
tests/ide-test: convert to QMP
tests/qtest: add qtest_qmp_job_wait()
tests/ahci-test: replace HMP usage with QMP
tests/functional/s390x: use QMP for balloon
tests/functional: skip some tests that require HMP
tests/functional: add skipTestIfNoHMP() helper
tests/functional: replace HMP with QMP
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
| -rwxr-xr-x | tests/functional/arm/test_integratorcp.py | 13 | ||||
| -rwxr-xr-x | tests/functional/hexagon/test_systests.py | 6 | ||||
| -rwxr-xr-x | tests/functional/m68k/test_nextcube.py | 12 | ||||
| -rwxr-xr-x | tests/functional/mips64el/test_malta.py | 13 | ||||
| -rwxr-xr-x | tests/functional/ppc/test_ppe42.py | 1 | ||||
| -rw-r--r-- | tests/functional/qemu_test/testcase.py | 6 | ||||
| -rwxr-xr-x | tests/functional/s390x/test_ccw_virtio.py | 4 | ||||
| -rw-r--r-- | tests/qtest/ahci-test.c | 5 | ||||
| -rw-r--r-- | tests/qtest/drive_del-test.c | 47 | ||||
| -rw-r--r-- | tests/qtest/ide-test.c | 37 | ||||
| -rw-r--r-- | tests/qtest/libqtest.c | 39 | ||||
| -rw-r--r-- | tests/qtest/libqtest.h | 13 |
12 files changed, 140 insertions, 56 deletions
diff --git a/tests/functional/arm/test_integratorcp.py b/tests/functional/arm/test_integratorcp.py index 23ae919359..b79e813935 100755 --- a/tests/functional/arm/test_integratorcp.py +++ b/tests/functional/arm/test_integratorcp.py @@ -14,6 +14,7 @@ import logging +from qemu.qmp.qmp_client import ExecuteError from qemu_test import QemuSystemTest, Asset from qemu_test import wait_for_console_pattern from qemu_test import skipIfMissingImports, skipUntrustedTest @@ -72,11 +73,13 @@ class IntegratorMachine(QemuSystemTest): self.boot_integratorcp() framebuffer_ready = 'Console: switching to colour frame buffer device' wait_for_console_pattern(self, framebuffer_ready) - self.vm.cmd('human-monitor-command', command_line='stop') - res = self.vm.cmd('human-monitor-command', - command_line='screendump %s' % screendump_path) - if 'unknown command' in res: - self.skipTest('screendump not available') + self.vm.cmd('stop') + try: + self.vm.cmd('screendump', filename=screendump_path) + except ExecuteError as e: + if e.error_class == 'CommandNotFound': + self.skipTest('screendump command not found') + raise cpu_count = 1 match_threshold = 0.92 diff --git a/tests/functional/hexagon/test_systests.py b/tests/functional/hexagon/test_systests.py index 983ee1672c..2779efa917 100755 --- a/tests/functional/hexagon/test_systests.py +++ b/tests/functional/hexagon/test_systests.py @@ -65,14 +65,14 @@ class SysTestsStandaloneTests(QemuSystemTest): import tempfile # The fopen binary has a short cmdline buffer; use a short path. dummy = os.path.join(tempfile.gettempdir(), "qemu_fopen_test.so") - with open(dummy, "w") as f: + with open(dummy, "w", encoding="utf-8") as f: f.write("valid\n") self.run_exit_zero("fopen", "-append", dummy) def test_ftrunc(self): """ftrunc truncates _testfile_ftrunc from 6 bytes to 1 byte.""" ftrunc_path = self.scratch_file("_testfile_ftrunc") - with open(ftrunc_path, "w") as f: + with open(ftrunc_path, "w", encoding="utf-8") as f: f.write("valid\n") # Sleep 1 s so mtime change is observable time.sleep(1) @@ -83,7 +83,7 @@ class SysTestsStandaloneTests(QemuSystemTest): def test_access(self): """access checks R_OK|W_OK on _testfile_access.""" testfile = self.scratch_file("_testfile_access") - with open(testfile, "w") as f: + with open(testfile, "w", encoding="utf-8") as f: f.write("valid\n") self.run_exit_zero("access", "-append", testfile) diff --git a/tests/functional/m68k/test_nextcube.py b/tests/functional/m68k/test_nextcube.py index d917cf5424..e7fca50292 100755 --- a/tests/functional/m68k/test_nextcube.py +++ b/tests/functional/m68k/test_nextcube.py @@ -9,6 +9,7 @@ import time +from qemu.qmp.qmp_client import ExecuteError from qemu_test import QemuSystemTest, Asset from qemu_test import skipIfMissingImports, skipIfMissingCommands from qemu_test.tesseract import tesseract_ocr @@ -27,6 +28,7 @@ class NextCubeMachine(QemuSystemTest): self.vm.add_args('-bios', rom_path) self.vm.launch() + self.skipTestIfNoHMP() # FIXME: QMP x-query-registers self.log.info('VM launched, waiting for display') # Wait for the FPU test to finish, then the display is available, too: @@ -39,10 +41,12 @@ class NextCubeMachine(QemuSystemTest): break time.sleep(0.1) - res = self.vm.cmd('human-monitor-command', - command_line=f"screendump {screenshot_path}") - if 'unknown command' in res: - self.skipTest('screendump not available') + try: + self.vm.cmd('screendump', filename=screenshot_path) + except ExecuteError as e: + if e.error_class == 'CommandNotFound': + self.skipTest('screendump command not found') + raise @skipIfMissingImports("PIL") def test_bootrom_framebuffer_size(self): diff --git a/tests/functional/mips64el/test_malta.py b/tests/functional/mips64el/test_malta.py index 163bbaf5ca..4544f950d9 100755 --- a/tests/functional/mips64el/test_malta.py +++ b/tests/functional/mips64el/test_malta.py @@ -11,6 +11,7 @@ import os +from qemu.qmp.qmp_client import ExecuteError from qemu_test import LinuxKernelTest, Asset from qemu_test import exec_command_and_wait_for_pattern from qemu_test import skipIfMissingImports, skipFlakyTest, skipUntrustedTest @@ -154,11 +155,13 @@ class MaltaMachineFramebuffer(LinuxKernelTest): self.vm.launch() framebuffer_ready = 'Console: switching to colour frame buffer device' self.wait_for_console_pattern(framebuffer_ready) - self.vm.cmd('human-monitor-command', command_line='stop') - res = self.vm.cmd('human-monitor-command', - command_line=f'screendump {screendump_path}') - if 'unknown command' in res: - self.skipTest('screendump not available') + self.vm.cmd('stop') + try: + self.vm.cmd('screendump', filename=screendump_path) + except ExecuteError as e: + if e.error_class == 'CommandNotFound': + self.skipTest('screendump command not found') + raise match_threshold = 0.95 screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR) diff --git a/tests/functional/ppc/test_ppe42.py b/tests/functional/ppc/test_ppe42.py index 53958a7938..a9c154f673 100755 --- a/tests/functional/ppc/test_ppe42.py +++ b/tests/functional/ppc/test_ppe42.py @@ -72,6 +72,7 @@ class Ppe42Machine(QemuSystemTest): self.vm.add_args('-device', 'loader,addr=0xfff80040,cpu-num=0') self.vm.add_args('-action', 'panic=pause') self.vm.launch() + self.skipTestIfNoHMP() # FIXME: QMP x-query-registers self._wait_pass_fail(self.timeout) if __name__ == '__main__': diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index 69d3d06cc0..bf2dc1dc10 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -369,6 +369,12 @@ class QemuSystemTest(QemuBaseTest): self.skipTest("%s accelerator does not seem to be " "available" % accelerator) + def skipTestIfNoHMP(self): + commands = self.vm.cmd('query-commands') + if not any(cmd['name'] == 'human-monitor-command' + for cmd in commands): + self.skipTest('HMP support is not available') + def require_netdev(self, netdevname): helptxt = run([self.qemu_bin, '-M', 'none', '-netdev', 'help'], capture_output=True, check=True, encoding='utf8').stdout diff --git a/tests/functional/s390x/test_ccw_virtio.py b/tests/functional/s390x/test_ccw_virtio.py index 1d4958bbe2..f816b1e201 100755 --- a/tests/functional/s390x/test_ccw_virtio.py +++ b/tests/functional/s390x/test_ccw_virtio.py @@ -162,10 +162,10 @@ class S390CCWVirtioMachine(QemuSystemTest): # test the virtio-balloon device exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', 'MemTotal: 115640 kB') - self.vm.cmd('human-monitor-command', command_line='balloon 96') + self.vm.cmd('balloon', value=96 * 1024 * 1024) exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', 'MemTotal: 82872 kB') - self.vm.cmd('human-monitor-command', command_line='balloon 128') + self.vm.cmd('balloon', value=128 * 1024 * 1024) exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', 'MemTotal: 115640 kB') diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c index 3406ca884f..eb8d239997 100644 --- a/tests/qtest/ahci-test.c +++ b/tests/qtest/ahci-test.c @@ -1900,8 +1900,7 @@ static void test_write_engine_stop_in_flight(void) ahci_io(ahci, port, CMD_WRITE_DMA, rx, AHCI_SECTOR_SIZE, 1); /* Suspend the backend write so the first sector stays in flight. */ - g_free(qtest_hmp(ahci->parent->qts, - "qemu-io drive0 \"break write_aio wr\"")); + qtest_qemu_io(ahci->parent->qts, "drive0", "break write_aio wr"); cmd = ahci_command_create(CMD_WRITE_PIO); ahci_command_adjust(cmd, 0, ptr, bufsize, 0); @@ -1911,7 +1910,7 @@ static void test_write_engine_stop_in_flight(void) /* Drop the command list while the write is still outstanding. */ ahci_px_clr(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST); - g_free(qtest_hmp(ahci->parent->qts, "qemu-io drive0 \"resume wr\"")); + qtest_qemu_io(ahci->parent->qts, "drive0", "resume wr"); /* Round-trip through the device to confirm qemu is still alive. */ ahci_px_rreg(ahci, port, AHCI_PX_TFD); diff --git a/tests/qtest/drive_del-test.c b/tests/qtest/drive_del-test.c index cc52c2d879..cbf94d5b9f 100644 --- a/tests/qtest/drive_del-test.c +++ b/tests/qtest/drive_del-test.c @@ -87,6 +87,7 @@ static void blockdev_add_with_media(QTestState *qts) g_assert(has_blockdev(qts)); } +#ifdef CONFIG_HMP static void drive_add(QTestState *qts) { char *resp = qtest_hmp(qts, "drive_add 0 if=none,id=drive0"); @@ -117,6 +118,7 @@ static void drive_del(QTestState *qts) g_assert(!has_drive(qts)); g_free(resp); } +#endif /* * qvirtio_get_dev_type: @@ -165,13 +167,9 @@ static void device_del(QTestState *qts, bool and_reset) static void test_drive_without_dev(void) { +#ifdef CONFIG_HMP QTestState *qts; -#ifndef CONFIG_HMP - g_test_skip("HMP not enabled"); - return; -#endif - /* Start with an empty drive */ qts = qtest_init("-drive if=none,id=drive0 -M none"); @@ -184,19 +182,18 @@ static void test_drive_without_dev(void) drive_add(qts); qtest_quit(qts); +#else + g_test_skip("HMP not enabled"); +#endif } static void test_after_failed_device_add(void) { +#ifdef CONFIG_HMP char driver[32]; QDict *response; QTestState *qts; -#ifndef CONFIG_HMP - g_test_skip("HMP not enabled"); - return; -#endif - if (!has_device_builtin("virtio-blk")) { g_test_skip("Device virtio-blk is not available"); return; @@ -227,17 +224,16 @@ static void test_after_failed_device_add(void) drive_add(qts); qtest_quit(qts); +#else + g_test_skip("HMP not enabled"); +#endif } static void test_drive_del_device_del(void) { +#ifdef CONFIG_HMP QTestState *qts; -#ifndef CONFIG_HMP - g_test_skip("HMP not enabled"); - return; -#endif - if (!has_device_builtin("virtio-scsi")) { g_test_skip("Device virtio-scsi is not available"); return; @@ -259,6 +255,9 @@ static void test_drive_del_device_del(void) g_assert(!has_drive(qts)); qtest_quit(qts); +#else + g_test_skip("HMP not enabled"); +#endif } static void test_cli_device_del(void) @@ -416,15 +415,11 @@ static void test_device_add_and_del_q35(void) static void test_drive_add_device_add_and_del(void) { +#ifdef CONFIG_HMP QTestState *qts; const char *arch = qtest_get_arch(); const char *machine_addition = ""; -#ifndef CONFIG_HMP - g_test_skip("HMP not enabled"); - return; -#endif - if (!has_device_builtin("virtio-blk")) { g_test_skip("Device virtio-blk is not available"); return; @@ -450,17 +445,16 @@ static void test_drive_add_device_add_and_del(void) g_assert(!has_drive(qts)); qtest_quit(qts); +#else + g_test_skip("HMP not enabled"); +#endif } static void test_drive_add_device_add_and_del_q35(void) { +#ifdef CONFIG_HMP QTestState *qts; -#ifndef CONFIG_HMP - g_test_skip("HMP not enabled"); - return; -#endif - if (!has_device_builtin("virtio-blk")) { g_test_skip("Device virtio-blk is not available"); return; @@ -479,6 +473,9 @@ static void test_drive_add_device_add_and_del_q35(void) g_assert(!has_drive(qts)); qtest_quit(qts); +#else + g_test_skip("HMP not enabled"); +#endif } static void test_blockdev_add_device_add_and_del(void) diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c index 895fec6d08..cf109b0799 100644 --- a/tests/qtest/ide-test.c +++ b/tests/qtest/ide-test.c @@ -1345,11 +1345,34 @@ static void ide_prepare_markers(QTestState *qts, QPCIDevice *dev, ide_write_marker(qts, dev, ide_bar, 63, CHS_MARKER_DEFAULT); } -static void ide_hmp_quiet(QTestState *qts, const char *command) +static void ide_snapshot_save(QTestState *qts, const char *tag, + const char *vmstate, const char *device) { - g_autofree char *out = qtest_hmp(qts, "%s", command); + qtest_qmp_assert_success(qts, + "{ 'execute': 'snapshot-save'," + " 'arguments': {" + " 'job-id': 'save0'," + " 'tag': %s," + " 'vmstate': %s," + " 'devices': [%s]" + " }" + "}", tag, vmstate, device); + qtest_qmp_job_wait(qts, "save0"); +} - g_assert_cmpstr(out, ==, ""); +static void ide_snapshot_load(QTestState *qts, const char *tag, + const char *vmstate, const char *device) +{ + qtest_qmp_assert_success(qts, + "{ 'execute': 'snapshot-load'," + " 'arguments': {" + " 'job-id': 'load0'," + " 'tag': %s," + " 'vmstate': %s," + " 'devices': [%s]" + " }" + "}", tag, vmstate, device); + qtest_qmp_job_wait(qts, "load0"); } static char *ide_migration_status(QTestState *qts) @@ -1455,10 +1478,6 @@ static void test_migrate_chs_snapshot(void) char marker[9]; int fd; -#ifndef CONFIG_HMP - g_test_skip("HMP not enabled"); - return; -#endif if (!have_qemu_img()) { g_test_skip("QTEST_QEMU_IMG not set, snapshots need a qcow2 image"); return; @@ -1480,13 +1499,13 @@ static void test_migrate_chs_snapshot(void) /* Snapshot taken while the default translation is in effect */ ide_read_chs_marker(qts, dev, ide_bar, 0, 1, 1, marker); g_assert_cmpstr(marker, ==, CHS_MARKER_DEFAULT); - ide_hmp_quiet(qts, "savevm s0"); + ide_snapshot_save(qts, "s0", "hda", "hda"); ide_set_translation(dev, ide_bar, 8, 32); ide_read_chs_marker(qts, dev, ide_bar, 0, 1, 1, marker); g_assert_cmpstr(marker, ==, CHS_MARKER_CUSTOM); - ide_hmp_quiet(qts, "loadvm s0"); + ide_snapshot_load(qts, "s0", "hda", "hda"); ide_read_chs_marker(qts, dev, ide_bar, 0, 1, 1, marker); g_assert_cmpstr(marker, ==, CHS_MARKER_DEFAULT); diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index 28bb72bfae..05d8847615 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -984,6 +984,44 @@ void qtest_qmp_eventwait(QTestState *s, const char *event) qobject_unref(response); } +void qtest_qmp_job_wait(QTestState *s, const char *job_id) +{ + QDict *response, *data, *error; + QList *jobs; + const QListEntry *entry; + + for (;;) { + response = qtest_qmp_eventwait_ref(s, "JOB_STATUS_CHANGE"); + data = qdict_get_qdict(response, "data"); + if (!strcmp(qdict_get_str(data, "id"), job_id) && + !strcmp(qdict_get_str(data, "status"), "concluded")) { + qobject_unref(response); + break; + } + qobject_unref(response); + } + + response = qtest_qmp(s, "{ 'execute': 'query-jobs' }"); + g_assert(qdict_haskey(response, "return")); + jobs = qobject_to(QList, qdict_get(response, "return")); + g_assert(jobs); + QLIST_FOREACH_ENTRY(jobs, entry) { + QDict *job = qobject_to(QDict, qlist_entry_obj(entry)); + if (!strcmp(qdict_get_str(job, "id"), job_id)) { + g_assert_null(qdict_get_try_str(job, "error")); + break; + } + } + qobject_unref(response); + + response = qtest_qmp(s, + "{ 'execute': 'job-dismiss', 'arguments': { 'id': %s } }", job_id); + error = qdict_get_qdict(response, "error"); + g_assert_null(error); + qobject_unref(response); +} + +#ifdef CONFIG_HMP char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap) { char *cmd; @@ -1011,6 +1049,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) va_end(ap); return ret; } +#endif void qtest_qemu_io(QTestState *s, const char *device, const char *fmt, ...) diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 58491ca53a..20982d3fe8 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -399,6 +399,18 @@ QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event); QDict *qtest_qmp_event_ref(QTestState *s, const char *event); /** + * qtest_qmp_job_wait: + * @s: #QTestState instance to operate on. + * @job_id: job identifier to wait for. + * + * Wait for a QMP job to reach "concluded" status by consuming + * JOB_STATUS_CHANGE events, then dismiss the job. + * Asserts that the job completed without error. + */ +void qtest_qmp_job_wait(QTestState *s, const char *job_id); + +#ifdef CONFIG_HMP +/** * qtest_hmp: * @s: #QTestState instance to operate on. * @fmt: HMP command to send to QEMU, formats arguments like sprintf(). @@ -423,6 +435,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) G_GNUC_PRINTF(2, 3); */ char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap) G_GNUC_PRINTF(2, 0); +#endif /** * qtest_qemu_io: |
