Thomas Huth | 5e0ac7e | 2020-02-25 18:24:59 +0100 | [diff] [blame] | 1 | # Functional test that boots a Linux kernel and checks the console |
| 2 | # |
| 3 | # Copyright (c) 2020 Red Hat, Inc. |
| 4 | # |
| 5 | # Author: |
| 6 | # Thomas Huth <thuth@redhat.com> |
| 7 | # |
| 8 | # This work is licensed under the terms of the GNU GPL, version 2 or |
| 9 | # later. See the COPYING file in the top-level directory. |
| 10 | |
| 11 | import os |
Philippe Mathieu-Daudé | 15b1bdc | 2020-02-25 18:25:01 +0100 | [diff] [blame] | 12 | import logging |
Thomas Huth | 5e0ac7e | 2020-02-25 18:24:59 +0100 | [diff] [blame] | 13 | |
| 14 | from avocado import skipUnless |
Philippe Mathieu-Daudé | 2283b62 | 2021-09-27 18:14:33 +0200 | [diff] [blame] | 15 | from avocado_qemu import QemuSystemTest |
Thomas Huth | 5e0ac7e | 2020-02-25 18:24:59 +0100 | [diff] [blame] | 16 | from avocado_qemu import wait_for_console_pattern |
| 17 | |
Philippe Mathieu-Daudé | 15b1bdc | 2020-02-25 18:25:01 +0100 | [diff] [blame] | 18 | |
| 19 | NUMPY_AVAILABLE = True |
| 20 | try: |
| 21 | import numpy as np |
| 22 | except ImportError: |
| 23 | NUMPY_AVAILABLE = False |
| 24 | |
| 25 | CV2_AVAILABLE = True |
| 26 | try: |
| 27 | import cv2 |
| 28 | except ImportError: |
| 29 | CV2_AVAILABLE = False |
| 30 | |
| 31 | |
Philippe Mathieu-Daudé | 2283b62 | 2021-09-27 18:14:33 +0200 | [diff] [blame] | 32 | class IntegratorMachine(QemuSystemTest): |
Thomas Huth | 5e0ac7e | 2020-02-25 18:24:59 +0100 | [diff] [blame] | 33 | |
| 34 | timeout = 90 |
| 35 | |
Philippe Mathieu-Daudé | 595f1ac | 2020-02-25 18:25:00 +0100 | [diff] [blame] | 36 | def boot_integratorcp(self): |
Thomas Huth | 5e0ac7e | 2020-02-25 18:24:59 +0100 | [diff] [blame] | 37 | kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/' |
| 38 | 'arm-test/kernel/zImage.integrator') |
| 39 | kernel_hash = '0d7adba893c503267c946a3cbdc63b4b54f25468' |
| 40 | kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) |
| 41 | |
| 42 | initrd_url = ('https://github.com/zayac/qemu-arm/raw/master/' |
| 43 | 'arm-test/kernel/arm_root.img') |
| 44 | initrd_hash = 'b51e4154285bf784e017a37586428332d8c7bd8b' |
| 45 | initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) |
| 46 | |
| 47 | self.vm.set_console() |
| 48 | self.vm.add_args('-kernel', kernel_path, |
| 49 | '-initrd', initrd_path, |
| 50 | '-append', 'printk.time=0 console=ttyAMA0') |
| 51 | self.vm.launch() |
Philippe Mathieu-Daudé | 595f1ac | 2020-02-25 18:25:00 +0100 | [diff] [blame] | 52 | |
| 53 | @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') |
| 54 | def test_integratorcp_console(self): |
| 55 | """ |
| 56 | Boots the Linux kernel and checks that the console is operational |
| 57 | :avocado: tags=arch:arm |
| 58 | :avocado: tags=machine:integratorcp |
| 59 | :avocado: tags=device:pl011 |
| 60 | """ |
| 61 | self.boot_integratorcp() |
Thomas Huth | 5e0ac7e | 2020-02-25 18:24:59 +0100 | [diff] [blame] | 62 | wait_for_console_pattern(self, 'Log in as root') |
Philippe Mathieu-Daudé | 15b1bdc | 2020-02-25 18:25:01 +0100 | [diff] [blame] | 63 | |
| 64 | @skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed') |
| 65 | @skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed') |
| 66 | @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code') |
| 67 | def test_framebuffer_tux_logo(self): |
| 68 | """ |
| 69 | Boot Linux and verify the Tux logo is displayed on the framebuffer. |
| 70 | :avocado: tags=arch:arm |
| 71 | :avocado: tags=machine:integratorcp |
| 72 | :avocado: tags=device:pl110 |
| 73 | :avocado: tags=device:framebuffer |
| 74 | """ |
| 75 | screendump_path = os.path.join(self.workdir, "screendump.pbm") |
| 76 | tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/' |
| 77 | 'drivers/video/logo/logo_linux_vga16.ppm') |
| 78 | tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af' |
| 79 | tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash) |
| 80 | |
| 81 | self.boot_integratorcp() |
| 82 | framebuffer_ready = 'Console: switching to colour frame buffer device' |
| 83 | wait_for_console_pattern(self, framebuffer_ready) |
| 84 | self.vm.command('human-monitor-command', command_line='stop') |
| 85 | self.vm.command('human-monitor-command', |
| 86 | command_line='screendump %s' % screendump_path) |
| 87 | logger = logging.getLogger('framebuffer') |
| 88 | |
| 89 | cpu_count = 1 |
| 90 | match_threshold = 0.92 |
| 91 | screendump_bgr = cv2.imread(screendump_path) |
| 92 | screendump_gray = cv2.cvtColor(screendump_bgr, cv2.COLOR_BGR2GRAY) |
| 93 | result = cv2.matchTemplate(screendump_gray, cv2.imread(tuxlogo_path, 0), |
| 94 | cv2.TM_CCOEFF_NORMED) |
| 95 | loc = np.where(result >= match_threshold) |
| 96 | tux_count = 0 |
| 97 | for tux_count, pt in enumerate(zip(*loc[::-1]), start=1): |
| 98 | logger.debug('found Tux at position [x, y] = %s', pt) |
| 99 | self.assertGreaterEqual(tux_count, cpu_count) |