Merge tag 'pull-request-2025-09-24' of https://gitlab.com/thuth/qemu into staging

* New functional tests to check via the vmstate-static-checker.py script
* New functional tests for CD-ROM boot on hppa
* Skip functional tests on more exotic network errors, too
* Fix another issue with htags in the gitlab CI
* Some additional minor fixes to various functional tests

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCgAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmjTkIkRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbUZCA/9Fb3bVlK108aD5ipuMLlgsXlRI+leEQC6
# h8BJgrb1GvYLlxEguHZJcSIxQN0F6TZsj31xWjpsSMNQro7tbmBcDZtj9FkCrAuG
# E99tG67A6RCTeFbqCfi19QlU9C0UOhJPPEkzZ56D+jik9NJKSG0fM0OFVEt0vBEt
# NLFrfOS6Tgc4XP6qXDXQ7v61SldZtJdDEvkMo2CkXqxu8pDz4vw8G6CSMWPfCH5v
# vkZydxLw38mkp8OtGX/tYiGn5s7/N59B29nlDkfuyOaJXjjKb+kid1XE58Y5R3Lm
# FYEuyGYgOcycH/hLiFtAFQpYYxy2yrbaHnySCP/GkMftmynz2w49hCvXca6gtcxO
# MFwzxdzDkGpPGhgANP9P3xNuZceObq6nKOdlo/tI5vG3rQp5V/n6A8T3JWIWgRHd
# 71HNPYlLf53lYLbiOPAZ9SRaPjElcnJoIF0jrplOWfz8vo1NzanPV4MMOw480uFW
# HDD77dZWrFTox1Unmv1E/TS/85h5b93dbnG9XRiUUn+k8TGtBA71kDme2KEdTZzw
# 3eNkOHUyc6RIwaSjBHWKOfXsaxa9EmS33dfg/jiJ9EpyGie30/faGhK1SiMr9HEp
# 35s4qcpFE71eZKRqXojv8XQJmc5uRCIa30MWGwl0QoU1XaLrF2NUEPECdZRNOBCO
# Jrb+UWMEIsE=
# =RTPq
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 23 Sep 2025 11:32:41 PM PDT
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [unknown]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [unknown]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2025-09-24' of https://gitlab.com/thuth/qemu:
  tests/functional: treat unknown exceptions as transient faults
  tests/functional: retry when seeing ConnectionError exception
  tests: Fix "make check-functional" for targets without thorough tests
  tests/functional/hppa: Add a CD-ROM boot test for qemu-system-hppa
  .gitlab-ci.d/buildtest.yml: Unset CI_COMMIT_DESCRIPTION for htags
  tests/functional: use self.log for all logging
  tests/functional: Use vmstate-static-checker.py to test data from v7.2
  tests/data/vmstate-static-checker: Add dump files from QEMU 7.2.17
  tests/functional: Test whether the vmstate-static-checker script works fine
  tests: Move the old vmstate-static-checker files to tests/data/
  tests/functional/s390x/test_pxelinux: Fix warnings from pylint
  tests/functional/m68k: Use proper polling in the next-cube test

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2025-09-24 12:03:29 -07:00
27 changed files with 10599 additions and 49 deletions
+1 -1
View File
@@ -736,7 +736,7 @@ pages:
- make gtags
# We unset variables to work around a bug in some htags versions
# which causes it to fail when the environment is large
- CI_COMMIT_MESSAGE= CI_COMMIT_TAG_MESSAGE= htags
- CI_COMMIT_MESSAGE= CI_COMMIT_TAG_MESSAGE= CI_COMMIT_DESCRIPTION= htags
-anT --tree-view=filetree -m qemu_init
-t "Welcome to the QEMU sourcecode"
- mv HTML public/src
+4 -2
View File
@@ -1276,7 +1276,7 @@ F: include/hw/pci-host/astro.h
F: include/hw/pci-host/dino.h
F: pc-bios/hppa-firmware.img
F: roms/seabios-hppa/
F: tests/functional/hppa/test_seabios.py
F: tests/functional/hppa/
LoongArch Machines
------------------
@@ -3613,7 +3613,9 @@ F: migration/
F: scripts/vmstate-static-checker.py
F: tests/functional/migration.py
F: tests/functional/*/*migration.py
F: tests/vmstate-static-checker-data/
F: tests/functional/generic/test_vmstate.py
F: tests/functional/x86_64/test_bad_vmstate.py
F: tests/data/vmstate-static-checker/
F: tests/qtest/migration/
F: tests/qtest/migration-*
F: docs/devel/migration/
+3
View File
@@ -113,6 +113,9 @@ check-functional:
@$(NINJA) precache-functional
@QEMU_TEST_NO_DOWNLOAD=1 $(MAKE) SPEED=thorough check-func check-func-quick
.PHONY: check-func check-func-quick
check-func check-func-quick:
# Consolidated targets
.PHONY: check check-clean
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,475 @@
{
"vmschkmachine": {
"Name": "s390-ccw-virtio-7.2"
},
"sclpquiesce": {
"Name": "sclpquiesce",
"version_id": 0,
"minimum_version_id": 0,
"Description": {
"name": "sclpquiesce",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "event_pending",
"version_id": 0,
"field_exists": false,
"size": 1
}
]
}
},
"s390-sclp-event-facility": {
"Name": "s390-sclp-event-facility",
"version_id": 0,
"minimum_version_id": 0,
"Description": {
"name": "vmstate-event-facility",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "receive_mask_pieces[1]",
"version_id": 0,
"field_exists": false,
"size": 4
}
],
"Subsections": [
{
"name": "vmstate-event-facility/mask64",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "receive_mask_pieces[0]",
"version_id": 0,
"field_exists": false,
"size": 4
}
]
},
{
"name": "vmstate-event-facility/mask_length",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "mask_length",
"version_id": 0,
"field_exists": false,
"size": 2
}
]
}
]
}
},
"zpci": {
"Name": "zpci",
"version_id": 0,
"minimum_version_id": 0,
"Description": {
"name": "zpci",
"version_id": 0,
"minimum_version_id": 0
}
},
"sclpconsole": {
"Name": "sclpconsole",
"version_id": 0,
"minimum_version_id": 0,
"Description": {
"name": "sclpconsole",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "event.event_pending",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "iov",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "iov_sclp",
"version_id": 0,
"field_exists": false,
"size": 4
},
{
"field": "iov_bs",
"version_id": 0,
"field_exists": false,
"size": 4
},
{
"field": "iov_data_len",
"version_id": 0,
"field_exists": false,
"size": 4
},
{
"field": "iov_sclp_rest",
"version_id": 0,
"field_exists": false,
"size": 4
}
]
}
},
"virtio-serial-device": {
"Name": "virtio-serial-device",
"version_id": 3,
"minimum_version_id": 3,
"Description": {
"name": "virtio-console",
"version_id": 3,
"minimum_version_id": 3,
"Fields": [
{
"field": "virtio",
"version_id": 0,
"field_exists": false,
"size": 0
}
]
}
},
"sclplmconsole": {
"Name": "sclplmconsole",
"version_id": 0,
"minimum_version_id": 0,
"Description": {
"name": "sclplmconsole",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "event.event_pending",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "write_errors",
"version_id": 0,
"field_exists": false,
"size": 4
},
{
"field": "length",
"version_id": 0,
"field_exists": false,
"size": 4
},
{
"field": "buf",
"version_id": 0,
"field_exists": false,
"size": 1
}
]
}
},
"s390-pcihost": {
"Name": "s390-pcihost",
"version_id": 1,
"minimum_version_id": 1,
"Description": {
"name": "PCIHost",
"version_id": 1,
"minimum_version_id": 1,
"Fields": [
{
"field": "config_reg",
"version_id": 0,
"field_exists": false,
"size": 4
}
]
}
},
"s390-flic-qemu": {
"Name": "s390-flic-qemu",
"version_id": 1,
"minimum_version_id": 1,
"Description": {
"name": "qemu-s390-flic",
"version_id": 1,
"minimum_version_id": 1,
"Fields": [
{
"field": "simm",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "nimm",
"version_id": 0,
"field_exists": false,
"size": 1
}
]
}
},
"fw_cfg_io": {
"Name": "fw_cfg_io",
"version_id": 2,
"minimum_version_id": 1,
"Description": {
"name": "fw_cfg",
"version_id": 2,
"minimum_version_id": 1,
"Fields": [
{
"field": "cur_entry",
"version_id": 0,
"field_exists": false,
"size": 2
},
{
"field": "cur_offset",
"version_id": 0,
"field_exists": true,
"size": 4
},
{
"field": "cur_offset",
"version_id": 2,
"field_exists": false,
"size": 4
}
],
"Subsections": [
{
"name": "fw_cfg/dma",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "dma_addr",
"version_id": 0,
"field_exists": false,
"size": 8
}
]
},
{
"name": "fw_cfg/acpi_mr",
"version_id": 1,
"minimum_version_id": 1,
"Fields": [
{
"field": "table_mr_size",
"version_id": 0,
"field_exists": false,
"size": 8
},
{
"field": "linker_mr_size",
"version_id": 0,
"field_exists": false,
"size": 8
},
{
"field": "rsdp_mr_size",
"version_id": 0,
"field_exists": false,
"size": 8
}
]
}
]
}
},
"s390-ipl": {
"Name": "s390-ipl",
"version_id": 0,
"minimum_version_id": 0,
"Description": {
"name": "ipl",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "compat_start_addr",
"version_id": 0,
"field_exists": false,
"size": 8
},
{
"field": "compat_bios_start_addr",
"version_id": 0,
"field_exists": false,
"size": 8
},
{
"field": "iplb",
"version_id": 0,
"field_exists": false,
"size": 4096,
"Description": {
"name": "ipl/iplb",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "reserved1",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "devno",
"version_id": 0,
"field_exists": false,
"size": 2
},
{
"field": "reserved2",
"version_id": 0,
"field_exists": false,
"size": 1
}
],
"Subsections": [
{
"name": "ipl/iplb_extended",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "reserved_ext",
"version_id": 0,
"field_exists": false,
"size": 1
}
]
}
]
}
},
{
"field": "iplb_valid",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "cssid",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "ssid",
"version_id": 0,
"field_exists": false,
"size": 1
},
{
"field": "devno",
"version_id": 0,
"field_exists": false,
"size": 2
}
]
}
},
"pci-host-bridge": {
"Name": "pci-host-bridge",
"version_id": 1,
"minimum_version_id": 1,
"Description": {
"name": "PCIHost",
"version_id": 1,
"minimum_version_id": 1,
"Fields": [
{
"field": "config_reg",
"version_id": 0,
"field_exists": false,
"size": 4
}
]
}
},
"fw_cfg_mem": {
"Name": "fw_cfg_mem",
"version_id": 2,
"minimum_version_id": 1,
"Description": {
"name": "fw_cfg",
"version_id": 2,
"minimum_version_id": 1,
"Fields": [
{
"field": "cur_entry",
"version_id": 0,
"field_exists": false,
"size": 2
},
{
"field": "cur_offset",
"version_id": 0,
"field_exists": true,
"size": 4
},
{
"field": "cur_offset",
"version_id": 2,
"field_exists": false,
"size": 4
}
],
"Subsections": [
{
"name": "fw_cfg/dma",
"version_id": 0,
"minimum_version_id": 0,
"Fields": [
{
"field": "dma_addr",
"version_id": 0,
"field_exists": false,
"size": 8
}
]
},
{
"name": "fw_cfg/acpi_mr",
"version_id": 1,
"minimum_version_id": 1,
"Fields": [
{
"field": "table_mr_size",
"version_id": 0,
"field_exists": false,
"size": 8
},
{
"field": "linker_mr_size",
"version_id": 0,
"field_exists": false,
"size": 8
},
{
"field": "rsdp_mr_size",
"version_id": 0,
"field_exists": false,
"size": 8
}
]
}
]
}
}
}
File diff suppressed because it is too large Load Diff
+1
View File
@@ -19,6 +19,7 @@ test_aarch64_timeouts = {
tests_aarch64_system_quick = [
'migration',
'vmstate',
]
tests_aarch64_system_thorough = [
+1 -3
View File
@@ -72,8 +72,6 @@ class Aarch64VirtMachine(QemuSystemTest):
self.set_machine('virt')
self.require_accelerator("tcg")
logger = logging.getLogger('aarch64_virt')
kernel_path = self.ASSET_KERNEL.fetch()
self.vm.set_console()
@@ -91,7 +89,7 @@ class Aarch64VirtMachine(QemuSystemTest):
'rng-random,id=rng0,filename=/dev/urandom')
# Also add a scratch block device
logger.info('creating scratch qcow2 image')
self.log.info('creating scratch qcow2 image')
image_path = self.scratch_file('scratch.qcow2')
qemu_img = get_qemu_img(self)
check_call([qemu_img, 'create', '-f', 'qcow2', image_path, '8M'],
+1 -2
View File
@@ -77,7 +77,6 @@ class IntegratorMachine(QemuSystemTest):
command_line='screendump %s' % screendump_path)
if 'unknown command' in res:
self.skipTest('screendump not available')
logger = logging.getLogger('framebuffer')
cpu_count = 1
match_threshold = 0.92
@@ -88,7 +87,7 @@ class IntegratorMachine(QemuSystemTest):
loc = np.where(result >= match_threshold)
tux_count = 0
for tux_count, pt in enumerate(zip(*loc[::-1]), start=1):
logger.debug('found Tux at position [x, y] = %s', pt)
self.log.debug('found Tux at position [x, y] = %s', pt)
self.assertGreaterEqual(tux_count, cpu_count)
if __name__ == '__main__':
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
'''This test runs the vmstate-static-checker script with the current QEMU'''
import subprocess
from qemu_test import QemuSystemTest, skipFlakyTest
@skipFlakyTest("vmstate-static-checker can produce false positives")
class VmStateTest(QemuSystemTest):
'''
This test helps to check whether there are problems between old
reference data and the current QEMU
'''
def test_vmstate_7_2(self):
'''Check reference data from QEMU v7.2'''
target_machine = {
'aarch64': 'virt-7.2',
'm68k': 'virt-7.2',
'ppc64': 'pseries-7.2',
's390x': 's390-ccw-virtio-7.2',
'x86_64': 'pc-q35-7.2',
}
self.set_machine(target_machine[self.arch])
# Run QEMU to get the current vmstate json file:
dst_json = self.scratch_file('dest.json')
self.log.info('Dumping vmstate from %s', self.qemu_bin)
cp = subprocess.run([self.qemu_bin, '-nodefaults',
'-M', target_machine[self.arch],
'-dump-vmstate', dst_json],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True, check=True)
if cp.stdout:
self.log.info('QEMU output: %s', cp.stdout)
# Check whether the old vmstate json file is still compatible:
src_json = self.data_file('..', 'data', 'vmstate-static-checker',
self.arch,
target_machine[self.arch] + '.json')
self.log.info('Comparing vmstate with %s', src_json)
checkerscript = self.data_file('..', '..', 'scripts',
'vmstate-static-checker.py')
cp = subprocess.run([checkerscript, '-s', src_json, '-d', dst_json],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True, check=False)
if cp.returncode != 0:
self.fail('Running vmstate-static-checker failed:\n' + cp.stdout +
'\nThis either means that there is a migration bug '
'that needs to be fixed, or\nvmstate-static-checker.py '
'needs to be improved (e.g. extend the changed_names\n'
'in case a field has been renamed), or drop the '
'problematic field from\n' + src_json +
'\nin case the script cannot be fixed easily.')
if cp.stdout:
self.log.warning('vmstate-static-checker output: %s', cp.stdout)
if __name__ == '__main__':
QemuSystemTest.main()
+4
View File
@@ -3,3 +3,7 @@
tests_hppa_system_quick = [
'seabios',
]
tests_hppa_system_thorough = [
'cdboot',
]
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
#
# CD boot test for HPPA machines
#
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import wait_for_console_pattern
class HppaCdBoot(QemuSystemTest):
ASSET_CD = Asset(
('https://github.com/philmd/qemu-testing-blob/raw/ec1b741/'
'hppa/hp9000/712/C7120023.frm'),
'32c612ad2074516986bdc27768903c561fa92af2ca48e5ac3f3359ade1c42f70')
def test_cdboot(self):
self.set_machine('B160L')
cdrom_path = self.ASSET_CD.fetch()
self.vm.set_console()
self.vm.add_args('-cdrom', cdrom_path,
'-boot', 'd',
'-no-reboot')
self.vm.launch()
wait_for_console_pattern(self, 'Unrecognized MODEL TYPE = 502')
wait_for_console_pattern(self, 'UPDATE PAUSED>')
exec_command_and_wait_for_pattern(self, 'exit\r', 'UPDATE>')
exec_command_and_wait_for_pattern(self, 'ls\r', 'IMAGE1B')
wait_for_console_pattern(self, 'UPDATE>')
exec_command_and_wait_for_pattern(self, 'exit\r',
'THIS UTILITY WILL NOW RESET THE SYSTEM.....')
if __name__ == '__main__':
QemuSystemTest.main()
+4
View File
@@ -1,5 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
tests_m68k_system_quick = [
'vmstate',
]
tests_m68k_system_thorough = [
'mcf5208evb',
'nextcube',
+12 -5
View File
@@ -29,8 +29,15 @@ class NextCubeMachine(QemuSystemTest):
self.vm.launch()
self.log.info('VM launched, waiting for display')
# TODO: wait for the 'displaysurface_create 1120x832' trace-event.
time.sleep(2)
# Wait for the FPU test to finish, then the display is available, too:
while True:
res = self.vm.cmd('human-monitor-command',
command_line='info registers')
if ("F0 = 400e 8400000000000000" in res and
"F1 = 400e 83ff000000000000" in res and
"F2 = 400e 83ff000000000000" in res):
break
time.sleep(0.1)
res = self.vm.cmd('human-monitor-command',
command_line='screendump %s' % screenshot_path)
@@ -56,10 +63,10 @@ class NextCubeMachine(QemuSystemTest):
self.check_bootrom_framebuffer(screenshot_path)
lines = tesseract_ocr(screenshot_path)
text = '\n'.join(lines)
self.assertIn('Backplane slot', text)
self.assertIn('Ethernet address', text)
self.assertIn('Testing the FPU', text)
self.assertIn('System test failed. Error code', text)
self.assertIn('Boot command', text)
self.assertIn('Next>', text)
if __name__ == '__main__':
QemuSystemTest.main()
+1 -2
View File
@@ -159,7 +159,6 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
command_line='screendump %s' % screendump_path)
if 'unknown command' in res:
self.skipTest('screendump not available')
logger = logging.getLogger('framebuffer')
match_threshold = 0.95
screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR)
@@ -171,7 +170,7 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
h, w = tuxlogo_bgr.shape[:2]
debug_png = os.getenv('QEMU_TEST_CV2_SCREENDUMP_PNG_PATH')
for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1):
logger.debug('found Tux at position (x, y) = %s', pt)
self.log.debug('found Tux at position (x, y) = %s', pt)
cv2.rectangle(screendump_bgr, pt,
(pt[0] + w, pt[1] + h), (0, 0, 255), 2)
if debug_png:
+1
View File
@@ -11,6 +11,7 @@ test_ppc64_timeouts = {
tests_ppc64_system_quick = [
'migration',
'vmstate',
]
tests_ppc64_system_thorough = [

Some files were not shown because too many files have changed in this diff Show More