qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

tests/acceptance: Count multiple Tux logos displayed on framebuffer

Add a test that verifies that each core properly displays the Tux
logo on the framebuffer device.

We simply follow the OpenCV "Template Matching with Multiple Objects"
tutorial, replacing Lionel Messi by Tux:
https://docs.opencv.org/4.2.0/d4/dc6/tutorial_py_template_matching.html

When OpenCV and NumPy are installed, this test can be run using:

$ avocado --show=app,framebuffer \
run -t cpu:i6400 \
tests/acceptance/machine_mips_malta.py
JOB ID : 54f3d8efd8674f289b8aa01a87f5d70c5814544c
JOB LOG : avocado/job-results/job-2020-02-01T20.52-54f3d8e/job.log
(1/3) tests/acceptance/machine_mips_malta.py:MaltaMachineFramebuffer.test_mips_malta_i6400_framebuffer_logo_1core:
framebuffer: found Tux at position (x, y) = (0, 0)
PASS (3.37 s)
(2/3) tests/acceptance/machine_mips_malta.py:MaltaMachineFramebuffer.test_mips_malta_i6400_framebuffer_logo_7cores:
framebuffer: found Tux at position (x, y) = (0, 0)
framebuffer: found Tux at position (x, y) = (88, 0)
framebuffer: found Tux at position (x, y) = (176, 0)
framebuffer: found Tux at position (x, y) = (264, 0)
framebuffer: found Tux at position (x, y) = (352, 0)
framebuffer: found Tux at position (x, y) = (440, 0)
framebuffer: found Tux at position (x, y) = (528, 0)
PASS (5.80 s)
(3/3) tests/acceptance/machine_mips_malta.py:MaltaMachineFramebuffer.test_mips_malta_i6400_framebuffer_logo_8cores:
framebuffer: found Tux at position (x, y) = (0, 0)
framebuffer: found Tux at position (x, y) = (88, 0)
framebuffer: found Tux at position (x, y) = (176, 0)
framebuffer: found Tux at position (x, y) = (264, 0)
framebuffer: found Tux at position (x, y) = (352, 0)
framebuffer: found Tux at position (x, y) = (440, 0)
framebuffer: found Tux at position (x, y) = (528, 0)
framebuffer: found Tux at position (x, y) = (616, 0)
PASS (6.67 s)
RESULTS : PASS 3 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
JOB TIME : 16.79 s

If the AVOCADO_CV2_SCREENDUMP_PNG_PATH environment variable is set, the
test will save the screenshot with matched squares to it.

Test inspired by the following post:
https://www.mips.com/blog/how-to-run-smp-linux-in-qemu-on-a-mips64-release-6-cpu/
Kernel built with the following Docker file:
https://github.com/philmd/qemu-testing-blob/blob/malta_i6400/mips/malta/mips64el/Dockerfile

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20200201204751.17810-1-f4bug@amsat.org>

authored by

Philippe Mathieu-Daudé and committed by
Aleksandar Markovic
0484d9d4 3fab7f23

+119
+1
MAINTAINERS
··· 1005 1005 F: hw/mips/gt64xxx_pci.c 1006 1006 F: include/hw/southbridge/piix.h 1007 1007 F: tests/acceptance/linux_ssh_mips_malta.py 1008 + F: tests/acceptance/machine_mips_malta.py 1008 1009 1009 1010 Mipssim 1010 1011 M: Aleksandar Markovic <amarkovic@wavecomp.com>
+118
tests/acceptance/machine_mips_malta.py
··· 1 + # Functional tests for the MIPS Malta board 2 + # 3 + # Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org> 4 + # 5 + # This work is licensed under the terms of the GNU GPL, version 2 or later. 6 + # See the COPYING file in the top-level directory. 7 + # 8 + # SPDX-License-Identifier: GPL-2.0-or-later 9 + 10 + import os 11 + import gzip 12 + import logging 13 + 14 + from avocado import skipUnless 15 + from avocado_qemu import Test 16 + from avocado_qemu import wait_for_console_pattern 17 + from avocado.utils import archive 18 + 19 + 20 + NUMPY_AVAILABLE = True 21 + try: 22 + import numpy as np 23 + except ImportError: 24 + NUMPY_AVAILABLE = False 25 + 26 + CV2_AVAILABLE = True 27 + try: 28 + import cv2 29 + except ImportError: 30 + CV2_AVAILABLE = False 31 + 32 + 33 + @skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed') 34 + @skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed') 35 + class MaltaMachineFramebuffer(Test): 36 + 37 + timeout = 30 38 + 39 + KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' 40 + 41 + def do_test_i6400_framebuffer_logo(self, cpu_cores_count): 42 + """ 43 + Boot Linux kernel and check Tux logo is displayed on the framebuffer. 44 + """ 45 + screendump_path = os.path.join(self.workdir, 'screendump.pbm') 46 + 47 + kernel_url = ('https://github.com/philmd/qemu-testing-blob/raw/' 48 + 'a5966ca4b5/mips/malta/mips64el/' 49 + 'vmlinux-4.7.0-rc1.I6400.gz') 50 + kernel_hash = '096f50c377ec5072e6a366943324622c312045f6' 51 + kernel_path_gz = self.fetch_asset(kernel_url, asset_hash=kernel_hash) 52 + kernel_path = self.workdir + "vmlinux" 53 + archive.gzip_uncompress(kernel_path_gz, kernel_path) 54 + 55 + tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/' 56 + 'drivers/video/logo/logo_linux_vga16.ppm') 57 + tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af' 58 + tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash) 59 + 60 + self.vm.set_console() 61 + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 62 + 'clocksource=GIC console=tty0 console=ttyS0') 63 + self.vm.add_args('-kernel', kernel_path, 64 + '-cpu', 'I6400', 65 + '-smp', '%u' % cpu_cores_count, 66 + '-vga', 'std', 67 + '-append', kernel_command_line) 68 + self.vm.launch() 69 + framebuffer_ready = 'Console: switching to colour frame buffer device' 70 + wait_for_console_pattern(self, framebuffer_ready, 71 + failure_message='Kernel panic - not syncing') 72 + self.vm.command('human-monitor-command', command_line='stop') 73 + self.vm.command('human-monitor-command', 74 + command_line='screendump %s' % screendump_path) 75 + logger = logging.getLogger('framebuffer') 76 + 77 + match_threshold = 0.95 78 + screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR) 79 + tuxlogo_bgr = cv2.imread(tuxlogo_path, cv2.IMREAD_COLOR) 80 + result = cv2.matchTemplate(screendump_bgr, tuxlogo_bgr, 81 + cv2.TM_CCOEFF_NORMED) 82 + loc = np.where(result >= match_threshold) 83 + tuxlogo_count = 0 84 + h, w = tuxlogo_bgr.shape[:2] 85 + debug_png = os.getenv('AVOCADO_CV2_SCREENDUMP_PNG_PATH') 86 + for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1): 87 + logger.debug('found Tux at position (x, y) = %s', pt) 88 + cv2.rectangle(screendump_bgr, pt, 89 + (pt[0] + w, pt[1] + h), (0, 0, 255), 2) 90 + if debug_png: 91 + cv2.imwrite(debug_png, screendump_bgr) 92 + self.assertGreaterEqual(tuxlogo_count, cpu_cores_count) 93 + 94 + def test_mips_malta_i6400_framebuffer_logo_1core(self): 95 + """ 96 + :avocado: tags=arch:mips64el 97 + :avocado: tags=machine:malta 98 + :avocado: tags=cpu:i6400 99 + """ 100 + self.do_test_i6400_framebuffer_logo(1) 101 + 102 + def test_mips_malta_i6400_framebuffer_logo_7cores(self): 103 + """ 104 + :avocado: tags=arch:mips64el 105 + :avocado: tags=machine:malta 106 + :avocado: tags=cpu:i6400 107 + :avocado: tags=mips:smp 108 + """ 109 + self.do_test_i6400_framebuffer_logo(7) 110 + 111 + def test_mips_malta_i6400_framebuffer_logo_8cores(self): 112 + """ 113 + :avocado: tags=arch:mips64el 114 + :avocado: tags=machine:malta 115 + :avocado: tags=cpu:i6400 116 + :avocado: tags=mips:smp 117 + """ 118 + self.do_test_i6400_framebuffer_logo(8)