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>
72 lines
2.5 KiB
Python
Executable file
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()
|