diff options
Diffstat (limited to 'tests/functional')
| -rw-r--r-- | tests/functional/meson.build | 10 | ||||
| -rw-r--r-- | tests/functional/qemu_test/asset.py | 3 | ||||
| -rw-r--r-- | tests/functional/qemu_test/tuxruntest.py | 10 | ||||
| -rw-r--r-- | tests/functional/qemu_test/utils.py | 21 | ||||
| -rwxr-xr-x | tests/functional/test_aarch64_tcg_plugins.py | 115 | ||||
| -rwxr-xr-x | tests/functional/test_arm_bpim2u.py | 206 | ||||
| -rwxr-xr-x | tests/functional/test_arm_orangepi.py | 270 | ||||
| -rwxr-xr-x | tests/functional/test_ppc64_tuxrun.py | 4 | ||||
| -rwxr-xr-x | tests/functional/test_sh4eb_r2d.py | 33 |
9 files changed, 668 insertions, 4 deletions
diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 84a07970d4..d5296bff8b 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -16,6 +16,8 @@ test_timeouts = { 'aarch64_virt' : 360, 'acpi_bits' : 240, 'arm_aspeed' : 600, + 'arm_bpim2u' : 360, + 'arm_orangepi' : 540, 'arm_raspi2' : 120, 'arm_tuxrun' : 120, 'arm_sx1' : 360, @@ -25,6 +27,7 @@ test_timeouts = { 'ppc64_hv' : 1000, 'ppc64_powernv' : 240, 'ppc64_pseries' : 240, + 'ppc64_tuxrun' : 240, 's390x_ccw_virtio' : 240, } @@ -54,9 +57,11 @@ tests_alpha_system_thorough = [ tests_arm_system_thorough = [ 'arm_aspeed', + 'arm_bpim2u', 'arm_canona1100', 'arm_collie', 'arm_integratorcp', + 'arm_orangepi', 'arm_raspi2', 'arm_sx1', 'arm_vexpress', @@ -138,6 +143,7 @@ tests_ppc64_system_thorough = [ 'ppc64_hv', 'ppc64_powernv', 'ppc64_pseries', + 'ppc64_tuxrun', ] tests_rx_system_thorough = [ @@ -155,6 +161,7 @@ tests_riscv64_system_thorough = [ tests_s390x_system_thorough = [ 's390x_ccw_virtio', 's390x_topology', + 's390x_tuxrun', ] tests_sh4_system_thorough = [ @@ -162,6 +169,9 @@ tests_sh4_system_thorough = [ 'sh4_tuxrun', ] +tests_sh4eb_system_thorough = [ + 'sh4eb_r2d', +] tests_sparc_system_thorough = [ 'sparc_sun4m', diff --git a/tests/functional/qemu_test/asset.py b/tests/functional/qemu_test/asset.py index e47bfac035..f126cd5863 100644 --- a/tests/functional/qemu_test/asset.py +++ b/tests/functional/qemu_test/asset.py @@ -8,6 +8,7 @@ import hashlib import logging import os +import stat import subprocess import sys import unittest @@ -143,6 +144,8 @@ class Asset: raise Exception("Hash of %s does not match %s" % (self.url, self.hash)) tmp_cache_file.replace(self.cache_file) + # Remove write perms to stop tests accidentally modifying them + os.chmod(self.cache_file, stat.S_IRUSR | stat.S_IRGRP) self.log.info("Cached %s at %s" % (self.url, self.cache_file)) return str(self.cache_file) diff --git a/tests/functional/qemu_test/tuxruntest.py b/tests/functional/qemu_test/tuxruntest.py index 904da6f609..f05aa96ad7 100644 --- a/tests/functional/qemu_test/tuxruntest.py +++ b/tests/functional/qemu_test/tuxruntest.py @@ -10,6 +10,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later import os +import stat import time from qemu_test import QemuSystemTest @@ -77,12 +78,17 @@ class TuxRunBaselineTest(QemuSystemTest): kernel_image = kernel_asset.fetch() disk_image_zst = rootfs_asset.fetch() + disk_image = self.workdir + "/rootfs.ext4" + run_cmd([self.zstd, "-f", "-d", disk_image_zst, - "-o", self.workdir + "/rootfs.ext4"]) + "-o", disk_image]) + # zstd copies source archive permissions for the output + # file, so must make this writable for QEMU + os.chmod(disk_image, stat.S_IRUSR | stat.S_IWUSR) dtb = dtb_asset.fetch() if dtb_asset is not None else None - return (kernel_image, self.workdir + "/rootfs.ext4", dtb) + return (kernel_image, disk_image, dtb) def prepare_run(self, kernel, disk, drive, dtb=None, console_index=0): """ diff --git a/tests/functional/qemu_test/utils.py b/tests/functional/qemu_test/utils.py index 2a1cb60d38..1bf1c410d5 100644 --- a/tests/functional/qemu_test/utils.py +++ b/tests/functional/qemu_test/utils.py @@ -15,6 +15,27 @@ import shutil import subprocess import tarfile +""" +Round up to next power of 2 +""" +def pow2ceil(x): + return 1 if x == 0 else 2**(x - 1).bit_length() + +def file_truncate(path, size): + if size != os.path.getsize(path): + with open(path, 'ab+') as fd: + fd.truncate(size) + +""" +Expand file size to next power of 2 +""" +def image_pow2ceil_expand(path): + size = os.path.getsize(path) + size_aligned = pow2ceil(size) + if size != size_aligned: + with open(path, 'ab+') as fd: + fd.truncate(size_aligned) + def archive_extract(archive, dest_dir, member=None): with tarfile.open(archive) as tf: if hasattr(tarfile, 'data_filter'): diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/test_aarch64_tcg_plugins.py new file mode 100755 index 0000000000..01660eb090 --- /dev/null +++ b/tests/functional/test_aarch64_tcg_plugins.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# +# TCG Plugins tests +# +# These are a little more involved than the basic tests run by check-tcg. +# +# Copyright (c) 2021 Linaro +# +# Author: +# Alex Bennée <alex.bennee@linaro.org> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import tempfile +import mmap +import re + +from qemu_test import LinuxKernelTest, Asset + + +class PluginKernelBase(LinuxKernelTest): + """ + Boots a Linux kernel with a TCG plugin enabled. + """ + + timeout = 120 + KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 ' + + def run_vm(self, kernel_path, kernel_command_line, + plugin, plugin_log, console_pattern, args=None): + + vm = self.get_vm() + vm.set_console() + vm.add_args('-kernel', kernel_path, + '-append', kernel_command_line, + '-plugin', plugin, + '-d', 'plugin', + '-D', plugin_log, + '-net', 'none', + '-no-reboot') + if args: + vm.add_args(*args) + + try: + vm.launch() + except: + # TODO: probably fails because plugins not enabled but we + # can't currently probe for the feature. + self.cancel("TCG Plugins not enabled?") + + self.wait_for_console_pattern(console_pattern, vm) + # ensure logs are flushed + vm.shutdown() + + +class PluginKernelNormal(PluginKernelBase): + + ASSET_KERNEL = Asset( + ('https://storage.tuxboot.com/20230331/arm64/Image'), + 'ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7') + + def test_aarch64_virt_insn(self): + self.set_machine('virt') + self.cpu='cortex-a53' + kernel_path = self.ASSET_KERNEL.fetch() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyAMA0') + console_pattern = 'Kernel panic - not syncing: VFS:' + + plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", + suffix=".log") + + self.run_vm(kernel_path, kernel_command_line, + "tests/tcg/plugins/libinsn.so", plugin_log.name, + console_pattern) + + with plugin_log as lf, \ + mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: + + m = re.search(br"insns: (?P<count>\d+)", s) + if "count" not in m.groupdict(): + self.fail("Failed to find instruction count") + else: + count = int(m.group("count")) + self.log.info(f"Counted: {count} instructions") + + + def test_aarch64_virt_insn_icount(self): + self.set_machine('virt') + self.cpu='cortex-a53' + kernel_path = self.ASSET_KERNEL.fetch() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyAMA0') + console_pattern = 'Kernel panic - not syncing: VFS:' + + plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin", + suffix=".log") + + self.run_vm(kernel_path, kernel_command_line, + "tests/tcg/plugins/libinsn.so", plugin_log.name, + console_pattern, + args=('-icount', 'shift=1')) + + with plugin_log as lf, \ + mmap.mmap(lf.fileno(), 0, access=mmap.ACCESS_READ) as s: + + m = re.search(br"insns: (?P<count>\d+)", s) + if "count" not in m.groupdict(): + self.fail("Failed to find instruction count") + else: + count = int(m.group("count")) + self.log.info(f"Counted: {count} instructions") + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_arm_bpim2u.py b/tests/functional/test_arm_bpim2u.py new file mode 100755 index 0000000000..2f9fa145e3 --- /dev/null +++ b/tests/functional/test_arm_bpim2u.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel on a Banana Pi machine +# and checks the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os + +from qemu_test import LinuxKernelTest, exec_command_and_wait_for_pattern +from qemu_test import Asset, interrupt_interactive_console_until_pattern +from qemu_test.utils import archive_extract, gzip_uncompress, lzma_uncompress +from qemu_test.utils import image_pow2ceil_expand +from unittest import skipUnless + +class BananaPiMachine(LinuxKernelTest): + + ASSET_DEB = Asset( + ('https://apt.armbian.com/pool/main/l/linux-6.6.16/' + 'linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb'), + '3d968c15b121ede871dce49d13ee7644d6f74b6b121b84c9a40f51b0c80d6d22') + + ASSET_INITRD = Asset( + ('https://github.com/groeck/linux-build-test/raw/' + '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' + 'arm/rootfs-armv7a.cpio.gz'), + '2c8dbdb16ea7af2dfbcbea96044dde639fb07d09fd3c4fb31f2027ef71e55ddd') + + ASSET_ROOTFS = Asset( + ('http://storage.kernelci.org/images/rootfs/buildroot/' + 'buildroot-baseline/20230703.0/armel/rootfs.ext2.xz'), + '42b44a12965ac0afe9a88378527fb698a7dc76af50495efc2361ee1595b4e5c6') + + ASSET_SD_IMAGE = Asset( + ('https://downloads.openwrt.org/releases/22.03.3/targets/sunxi/cortexa7/' + 'openwrt-22.03.3-sunxi-cortexa7-sinovoip_bananapi-m2-ultra-ext4-sdcard.img.gz'), + '5b41b4e11423e562c6011640f9a7cd3bdd0a3d42b83430f7caa70a432e6cd82c') + + def test_arm_bpim2u(self): + """ + :avocado: tags=arch:arm + :avocado: tags=machine:bpim2u + :avocado: tags=accel:tcg + """ + self.set_machine('bpim2u') + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' + 'sun8i-r40-bananapi-m2-ultra.dtb') + dtb_path = self.extract_from_deb(deb_path, dtb_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200n8 ' + 'earlycon=uart,mmio32,0x1c28000') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-append', kernel_command_line) + self.vm.launch() + console_pattern = 'Kernel command line: %s' % kernel_command_line + self.wait_for_console_pattern(console_pattern) + os.remove(kernel_path) + os.remove(dtb_path) + + def test_arm_bpim2u_initrd(self): + """ + :avocado: tags=arch:arm + :avocado: tags=accel:tcg + :avocado: tags=machine:bpim2u + """ + self.set_machine('bpim2u') + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' + 'sun8i-r40-bananapi-m2-ultra.dtb') + dtb_path = self.extract_from_deb(deb_path, dtb_path) + initrd_path_gz = self.ASSET_INITRD.fetch() + initrd_path = os.path.join(self.workdir, 'rootfs.cpio') + gzip_uncompress(initrd_path_gz, initrd_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200 ' + 'panic=-1 noreboot') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-initrd', initrd_path, + '-append', kernel_command_line, + '-no-reboot') + self.vm.launch() + self.wait_for_console_pattern('Boot successful.') + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun8i Family') + exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', + 'system-control@1c00000') + exec_command_and_wait_for_pattern(self, 'reboot', + 'reboot: Restarting system') + # Wait for VM to shut down gracefully + self.vm.wait() + os.remove(kernel_path) + os.remove(dtb_path) + os.remove(initrd_path) + + def test_arm_bpim2u_gmac(self): + """ + :avocado: tags=arch:arm + :avocado: tags=machine:bpim2u + :avocado: tags=device:sd + """ + self.set_machine('bpim2u') + self.require_netdev('user') + + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/' + 'sun8i-r40-bananapi-m2-ultra.dtb') + dtb_path = self.extract_from_deb(deb_path, dtb_path) + rootfs_path_xz = self.ASSET_ROOTFS.fetch() + rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') + lzma_uncompress(rootfs_path_xz, rootfs_path) + image_pow2ceil_expand(rootfs_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200 ' + 'root=b300 rootwait rw ' + 'panic=-1 noreboot') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-drive', 'file=' + rootfs_path + ',if=sd,format=raw', + '-net', 'nic,model=gmac,netdev=host_gmac', + '-netdev', 'user,id=host_gmac', + '-append', kernel_command_line, + '-no-reboot') + self.vm.launch() + shell_ready = "/bin/sh: can't access tty; job control turned off" + self.wait_for_console_pattern(shell_ready) + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun8i Family') + exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', + 'mmcblk') + exec_command_and_wait_for_pattern(self, 'ifconfig eth0 up', + 'eth0: Link is Up') + exec_command_and_wait_for_pattern(self, 'udhcpc eth0', + 'udhcpc: lease of 10.0.2.15 obtained') + exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2', + '3 packets transmitted, 3 packets received, 0% packet loss') + exec_command_and_wait_for_pattern(self, 'reboot', + 'reboot: Restarting system') + # Wait for VM to shut down gracefully + self.vm.wait() + os.remove(kernel_path) + os.remove(dtb_path) + os.remove(rootfs_path) + + @skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'), 'storage limited') + def test_arm_bpim2u_openwrt_22_03_3(self): + """ + :avocado: tags=arch:arm + :avocado: tags=machine:bpim2u + :avocado: tags=device:sd + """ + self.set_machine('bpim2u') + # This test download a 8.9 MiB compressed image and expand it + # to 127 MiB. + image_path_gz = self.ASSET_SD_IMAGE.fetch() + image_path = os.path.join(self.workdir, 'sdcard.img') + gzip_uncompress(image_path_gz, image_path) + image_pow2ceil_expand(image_path) + + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw', + '-nic', 'user', + '-no-reboot') + self.vm.launch() + + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'usbcore.nousb ' + 'noreboot') + + self.wait_for_console_pattern('U-Boot SPL') + + interrupt_interactive_console_until_pattern( + self, 'Hit any key to stop autoboot:', '=>') + exec_command_and_wait_for_pattern(self, "setenv extraargs '" + + kernel_command_line + "'", '=>') + exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...'); + + self.wait_for_console_pattern( + 'Please press Enter to activate this console.') + + exec_command_and_wait_for_pattern(self, ' ', 'root@') + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun8i Family') + exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', + 'system-control@1c00000') + os.remove(image_path) + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_arm_orangepi.py b/tests/functional/test_arm_orangepi.py new file mode 100755 index 0000000000..d2ed5fcc82 --- /dev/null +++ b/tests/functional/test_arm_orangepi.py @@ -0,0 +1,270 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel on an Orange Pi machine +# and checks the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import shutil + +from qemu_test import LinuxKernelTest, exec_command_and_wait_for_pattern +from qemu_test import Asset, interrupt_interactive_console_until_pattern +from qemu_test import wait_for_console_pattern +from qemu_test.utils import archive_extract, gzip_uncompress, lzma_uncompress +from qemu_test.utils import image_pow2ceil_expand +from unittest import skipUnless + +class BananaPiMachine(LinuxKernelTest): + + ASSET_DEB = Asset( + ('https://apt.armbian.com/pool/main/l/linux-6.6.16/' + 'linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb'), + '3d968c15b121ede871dce49d13ee7644d6f74b6b121b84c9a40f51b0c80d6d22') + + ASSET_INITRD = Asset( + ('https://github.com/groeck/linux-build-test/raw/' + '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' + 'arm/rootfs-armv7a.cpio.gz'), + '2c8dbdb16ea7af2dfbcbea96044dde639fb07d09fd3c4fb31f2027ef71e55ddd') + + ASSET_ROOTFS = Asset( + ('http://storage.kernelci.org/images/rootfs/buildroot/' + 'buildroot-baseline/20230703.0/armel/rootfs.ext2.xz'), + '42b44a12965ac0afe9a88378527fb698a7dc76af50495efc2361ee1595b4e5c6') + + ASSET_ARMBIAN = Asset( + ('https://k-space.ee.armbian.com/archive/orangepipc/archive/' + 'Armbian_23.8.1_Orangepipc_jammy_current_6.1.47.img.xz'), + 'b386dff6552513b5f164ea00f94814a6b0f1da9fb90b83725e949cf797e11afb') + + ASSET_UBOOT = Asset( + ('http://snapshot.debian.org/archive/debian/20200108T145233Z/pool/' + 'main/u/u-boot/u-boot-sunxi_2020.01%2Bdfsg-1_armhf.deb'), + '9223d94dc283ab54df41ce9d6f69025a5b47fece29fb67a714e23aa0cdf3bdfa') + + ASSET_NETBSD = Asset( + ('https://archive.netbsd.org/pub/NetBSD-archive/NetBSD-9.0/' + 'evbarm-earmv7hf/binary/gzimg/armv7.img.gz'), + '20d3e07dc057e15c12452620e90ecab2047f0f7940d9cba8182ebc795927177f') + + def test_arm_orangepi(self): + """ + :avocado: tags=arch:arm + :avocado: tags=machine:orangepi-pc + :avocado: tags=accel:tcg + """ + self.set_machine('orangepi-pc') + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' + dtb_path = self.extract_from_deb(deb_path, dtb_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200n8 ' + 'earlycon=uart,mmio32,0x1c28000') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-append', kernel_command_line) + self.vm.launch() + console_pattern = 'Kernel command line: %s' % kernel_command_line + self.wait_for_console_pattern(console_pattern) + os.remove(kernel_path) + os.remove(dtb_path) + + def test_arm_orangepi_initrd(self): + """ + :avocado: tags=arch:arm + :avocado: tags=accel:tcg + :avocado: tags=machine:orangepi-pc + """ + self.set_machine('orangepi-pc') + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' + dtb_path = self.extract_from_deb(deb_path, dtb_path) + initrd_path_gz = self.ASSET_INITRD.fetch() + initrd_path = os.path.join(self.workdir, 'rootfs.cpio') + gzip_uncompress(initrd_path_gz, initrd_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200 ' + 'panic=-1 noreboot') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-initrd', initrd_path, + '-append', kernel_command_line, + '-no-reboot') + self.vm.launch() + self.wait_for_console_pattern('Boot successful.') + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun8i Family') + exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', + 'system-control@1c00000') + exec_command_and_wait_for_pattern(self, 'reboot', + 'reboot: Restarting system') + # Wait for VM to shut down gracefully + self.vm.wait() + os.remove(kernel_path) + os.remove(dtb_path) + os.remove(initrd_path) + + def test_arm_orangepi_sd(self): + """ + :avocado: tags=arch:arm + :avocado: tags=accel:tcg + :avocado: tags=machine:orangepi-pc + :avocado: tags=device:sd + """ + self.set_machine('orangepi-pc') + self.require_netdev('user') + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb' + dtb_path = self.extract_from_deb(deb_path, dtb_path) + rootfs_path_xz = self.ASSET_ROOTFS.fetch() + rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') + lzma_uncompress(rootfs_path_xz, rootfs_path) + image_pow2ceil_expand(rootfs_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200 ' + 'root=/dev/mmcblk0 rootwait rw ' + 'panic=-1 noreboot') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-drive', 'file=' + rootfs_path + ',if=sd,format=raw', + '-append', kernel_command_line, + '-no-reboot') + self.vm.launch() + shell_ready = "/bin/sh: can't access tty; job control turned off" + self.wait_for_console_pattern(shell_ready) + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun8i Family') + exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', + 'mmcblk0') + exec_command_and_wait_for_pattern(self, 'ifconfig eth0 up', + 'eth0: Link is Up') + exec_command_and_wait_for_pattern(self, 'udhcpc eth0', + 'udhcpc: lease of 10.0.2.15 obtained') + exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2', + '3 packets transmitted, 3 packets received, 0% packet loss') + exec_command_and_wait_for_pattern(self, 'reboot', + 'reboot: Restarting system') + # Wait for VM to shut down gracefully + self.vm.wait() + os.remove(kernel_path) + os.remove(dtb_path) + os.remove(rootfs_path) + + @skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'), 'storage limited') + def test_arm_orangepi_armbian(self): + """ + :avocado: tags=arch:arm + :avocado: tags=machine:orangepi-pc + :avocado: tags=device:sd + """ + self.set_machine('orangepi-pc') + # This test download a 275 MiB compressed image and expand it + # to 1036 MiB, but the underlying filesystem is 1552 MiB... + # As we expand it to 2 GiB we are safe. + image_path_xz = self.ASSET_ARMBIAN.fetch() + image_path = os.path.join(self.workdir, 'armbian.img') + lzma_uncompress(image_path_xz, image_path) + image_pow2ceil_expand(image_path) + + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw', + '-nic', 'user', + '-no-reboot') + self.vm.launch() + + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200 ' + 'loglevel=7 ' + 'nosmp ' + 'systemd.default_timeout_start_sec=9000 ' + 'systemd.mask=armbian-zram-config.service ' + 'systemd.mask=armbian-ramlog.service') + + self.wait_for_console_pattern('U-Boot SPL') + self.wait_for_console_pattern('Autoboot in ') + exec_command_and_wait_for_pattern(self, ' ', '=>') + exec_command_and_wait_for_pattern(self, "setenv extraargs '" + + kernel_command_line + "'", '=>') + exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...'); + + self.wait_for_console_pattern('systemd[1]: Hostname set ' + + 'to <orangepipc>') + self.wait_for_console_pattern('Starting Load Kernel Modules...') + + @skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'), 'storage limited') + def test_arm_orangepi_uboot_netbsd9(self): + """ + :avocado: tags=arch:arm + :avocado: tags=machine:orangepi-pc + :avocado: tags=device:sd + :avocado: tags=os:netbsd + """ + self.set_machine('orangepi-pc') + # This test download a 304MB compressed image and expand it to 2GB + deb_path = self.ASSET_UBOOT.fetch() + # We use the common OrangePi PC 'plus' build of U-Boot for our secondary + # program loader (SPL). We will then set the path to the more specific + # OrangePi "PC" device tree blob with 'setenv fdtfile' in U-Boot prompt, + # before to boot NetBSD. + uboot_path = '/usr/lib/u-boot/orangepi_plus/u-boot-sunxi-with-spl.bin' + uboot_path = self.extract_from_deb(deb_path, uboot_path) + image_path_gz = self.ASSET_NETBSD.fetch() + image_path = os.path.join(self.workdir, 'armv7.img') + gzip_uncompress(image_path_gz, image_path) + image_pow2ceil_expand(image_path) + image_drive_args = 'if=sd,format=raw,snapshot=on,file=' + image_path + + # dd if=u-boot-sunxi-with-spl.bin of=armv7.img bs=1K seek=8 conv=notrunc + with open(uboot_path, 'rb') as f_in: + with open(image_path, 'r+b') as f_out: + f_out.seek(8 * 1024) + shutil.copyfileobj(f_in, f_out) + + self.vm.set_console() + self.vm.add_args('-nic', 'user', + '-drive', image_drive_args, + '-global', 'allwinner-rtc.base-year=2000', + '-no-reboot') + self.vm.launch() + wait_for_console_pattern(self, 'U-Boot 2020.01+dfsg-1') + interrupt_interactive_console_until_pattern(self, + 'Hit any key to stop autoboot:', + 'switch to partitions #0, OK') + + exec_command_and_wait_for_pattern(self, '', '=>') + cmd = 'setenv bootargs root=ld0a' + exec_command_and_wait_for_pattern(self, cmd, '=>') + cmd = 'setenv kernel netbsd-GENERIC.ub' + exec_command_and_wait_for_pattern(self, cmd, '=>') + cmd = 'setenv fdtfile dtb/sun8i-h3-orangepi-pc.dtb' + exec_command_and_wait_for_pattern(self, cmd, '=>') + cmd = ("setenv bootcmd 'fatload mmc 0:1 ${kernel_addr_r} ${kernel}; " + "fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}; " + "fdt addr ${fdt_addr_r}; " + "bootm ${kernel_addr_r} - ${fdt_addr_r}'") + exec_command_and_wait_for_pattern(self, cmd, '=>') + + exec_command_and_wait_for_pattern(self, 'boot', + 'Booting kernel from Legacy Image') + wait_for_console_pattern(self, 'Starting kernel ...') + wait_for_console_pattern(self, 'NetBSD 9.0 (GENERIC)') + # Wait for user-space + wait_for_console_pattern(self, 'Starting root file system check') + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_ppc64_tuxrun.py b/tests/functional/test_ppc64_tuxrun.py index 552b53c97a..03b47e07f2 100755 --- a/tests/functional/test_ppc64_tuxrun.py +++ b/tests/functional/test_ppc64_tuxrun.py @@ -83,10 +83,10 @@ class TuxRunPPC64Test(TuxRunBaselineTest): ASSET_PPC64_KERNEL = Asset( 'https://storage.tuxboot.com/20230331/ppc64/vmlinux', - '1d953e81a4379e537fc8e41e05a0a59d9b453eef97aa03d47866c6c45b00bdff') + 'f22a9b9e924174a4c199f4c7e5d91a2339fcfe51c6eafd0907dc3e09b64ab728') ASSET_PPC64_ROOTFS = Asset( 'https://storage.tuxboot.com/20230331/ppc64/rootfs.ext4.zst', - 'f22a9b9e924174a4c199f4c7e5d91a2339fcfe51c6eafd0907dc3e09b64ab728') + '1d953e81a4379e537fc8e41e05a0a59d9b453eef97aa03d47866c6c45b00bdff') def test_ppc64(self): self.ppc64_common_tuxrun(kernel_asset=self.ASSET_PPC64_KERNEL, diff --git a/tests/functional/test_sh4eb_r2d.py b/tests/functional/test_sh4eb_r2d.py new file mode 100755 index 0000000000..d9c022c8b8 --- /dev/null +++ b/tests/functional/test_sh4eb_r2d.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +# +# Boot a Linux kernel on a r2d sh4eb machine and check the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import shutil + +from qemu_test import LinuxKernelTest, Asset +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test.utils import archive_extract +from unittest import skipUnless + +class R2dEBTest(LinuxKernelTest): + + ASSET_TGZ = Asset( + 'https://landley.net/bin/mkroot/0.8.11/sh4eb.tgz', + 'be8c6cb5aef8406899dc5aa5e22b6aa45840eb886cdd3ced51555c10577ada2c') + + def test_sh4eb_r2d(self): + self.set_machine('r2d') + file_path = self.ASSET_TGZ.fetch() + archive_extract(file_path, self.workdir) + self.vm.add_args('-append', 'console=ttySC1 noiotrap') + self.launch_kernel(os.path.join(self.workdir, 'sh4eb/linux-kernel'), + initrd=os.path.join(self.workdir, 'sh4eb/initramfs.cpio.gz'), + console_index=1, wait_for='Type exit when done') + exec_command_and_wait_for_pattern(self, 'exit', 'Restarting system') + shutil.rmtree(os.path.join(self.workdir, 'sh4eb')) + +if __name__ == '__main__': + LinuxKernelTest.main() |