qemu-cr16/tests/functional/m68k/test_nextcube.py
Thomas Huth 6096dfa6c5 tests/functional/m68k: Use proper polling in the next-cube test
The next-cube tests currently sleep for 2 seconds to wait for the
guest's display to come up with the expected results. That's bad
since there is still a theoretical race left here, and since there
are two subtests, the whole test takes more than 4 seconds this way.

Looking at what the firmware does, there is a better way instead of
blindly waiting for two seconds: The firmware is writing some values
to the FPU registers during a test (and never touches them again
afterwards, so we can be sure about the final values), so we can
poll for the right values in those registers to know when we reached
a state when the display is initialized for sure. We just have to
also make sure to not look for text anymore that is only printed
after the FPU test has been done by the guest firmware.

This way the whole tests finishes in less than 1 second here, and
there should be no race condition here anymore.

Message-ID: <20250909074817.84661-1-thuth@redhat.com>
Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
2025-09-23 11:32:27 +02:00

72 lines
2.5 KiB
Python
Executable file

#!/usr/bin/env python3
#
# Functional test that boots a VM and run OCR on the framebuffer
#
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
#
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
import time
from qemu_test import QemuSystemTest, Asset
from qemu_test import skipIfMissingImports, skipIfMissingCommands
from qemu_test.tesseract import tesseract_ocr
class NextCubeMachine(QemuSystemTest):
timeout = 15
ASSET_ROM = Asset(('https://sourceforge.net/p/previous/code/1350/tree/'
'trunk/src/Rev_2.5_v66.BIN?format=raw'),
'1b753890b67095b73e104c939ddf62eca9e7d0aedde5108e3893b0ed9d8000a4')
def check_bootrom_framebuffer(self, screenshot_path):
rom_path = self.ASSET_ROM.fetch()
self.vm.add_args('-bios', rom_path)
self.vm.launch()
self.log.info('VM launched, waiting for display')
# 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)
if 'unknown command' in res:
self.skipTest('screendump not available')
@skipIfMissingImports("PIL")
def test_bootrom_framebuffer_size(self):
self.set_machine('next-cube')
screenshot_path = self.scratch_file("dump.ppm")
self.check_bootrom_framebuffer(screenshot_path)
from PIL import Image
with Image.open(screenshot_path) as image:
width, height = image.size
self.assertEqual(width, 1120)
self.assertEqual(height, 832)
@skipIfMissingCommands('tesseract')
def test_bootrom_framebuffer_ocr_with_tesseract(self):
self.set_machine('next-cube')
screenshot_path = self.scratch_file("dump.ppm")
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)
if __name__ == '__main__':
QemuSystemTest.main()