From 2abdc8cad0b97f5a98a0e4329a07a658c630ce54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:28 +0000 Subject: tests/functional: fix mips64el test to honour workdir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The missing directory separator resulted in the kernel file being created 1 level higher than expected. Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-2-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-2-alex.bennee@linaro.org> --- tests/functional/test_mips64el_malta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/functional/test_mips64el_malta.py b/tests/functional/test_mips64el_malta.py index 6c6355b..24ebcdb 100755 --- a/tests/functional/test_mips64el_malta.py +++ b/tests/functional/test_mips64el_malta.py @@ -129,7 +129,7 @@ class MaltaMachineFramebuffer(LinuxKernelTest): screendump_path = os.path.join(self.workdir, 'screendump.pbm') kernel_path_gz = self.ASSET_KERNEL_4_7_0.fetch() - kernel_path = self.workdir + "vmlinux" + kernel_path = self.workdir + "/vmlinux" gzip_uncompress(kernel_path_gz, kernel_path) tuxlogo_path = self.ASSET_TUXLOGO.fetch() -- cgit v1.1 From dbaaef7dbfe3a932279c2d77f056a30575cc97cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:29 +0000 Subject: tests/functional: automatically clean up scratch files after tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The build/tests/functional subdirectories are consuming huge amounts of disk space. Split the location for scratch files into a 'scratch' sub-directory, separate from log files, and delete it upon completion of each test. The new env variable QEMU_TEST_KEEP_SCRATCH can be set to preserve this scratch dir for debugging access if required. Reviewed-by: Alex Bennée Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-3-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-3-alex.bennee@linaro.org> --- tests/functional/qemu_test/testcase.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index 411978b..b9418e2 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -13,8 +13,9 @@ import logging import os -import subprocess import pycotap +import shutil +import subprocess import sys import unittest import uuid @@ -40,11 +41,12 @@ class QemuBaseTest(unittest.TestCase): self.assertIsNotNone(self.qemu_bin, 'QEMU_TEST_QEMU_BINARY must be set') self.arch = self.qemu_bin.split('-')[-1] - self.workdir = os.path.join(BUILD_DIR, 'tests/functional', self.arch, - self.id()) + self.outputdir = os.path.join(BUILD_DIR, 'tests', 'functional', + self.arch, self.id()) + self.workdir = os.path.join(self.outputdir, 'scratch') os.makedirs(self.workdir, exist_ok=True) - self.logdir = self.workdir + self.logdir = self.outputdir self.log_filename = os.path.join(self.logdir, 'base.log') self.log = logging.getLogger('qemu-test') self.log.setLevel(logging.DEBUG) @@ -56,6 +58,8 @@ class QemuBaseTest(unittest.TestCase): self.log.addHandler(self._log_fh) def tearDown(self): + if "QEMU_TEST_KEEP_SCRATCH" not in os.environ: + shutil.rmtree(self.workdir) self.log.removeHandler(self._log_fh) def main(): @@ -108,7 +112,7 @@ class QemuSystemTest(QemuBaseTest): console_log = logging.getLogger('console') console_log.setLevel(logging.DEBUG) - self.console_log_name = os.path.join(self.workdir, 'console.log') + self.console_log_name = os.path.join(self.logdir, 'console.log') self._console_log_fh = logging.FileHandler(self.console_log_name, mode='w') self._console_log_fh.setLevel(logging.DEBUG) -- cgit v1.1 From b0b5bc2dc6580d87ead7ff7a5ba51c8a2358bf52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:30 +0000 Subject: tests/functional: remove "AVOCADO" from env variable name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This env variable is a debugging flag to save screendumps in the mips64el malta tests. Reviewed-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-4-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-4-alex.bennee@linaro.org> --- tests/functional/test_mips64el_malta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/functional/test_mips64el_malta.py b/tests/functional/test_mips64el_malta.py index 24ebcdb..6d1195d 100755 --- a/tests/functional/test_mips64el_malta.py +++ b/tests/functional/test_mips64el_malta.py @@ -159,7 +159,7 @@ class MaltaMachineFramebuffer(LinuxKernelTest): loc = np.where(result >= match_threshold) tuxlogo_count = 0 h, w = tuxlogo_bgr.shape[:2] - debug_png = os.getenv('AVOCADO_CV2_SCREENDUMP_PNG_PATH') + debug_png = os.getenv('QEMU_TEST_CV2_SCREENDUMP_PNG_PATH') for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1): logger.debug('found Tux at position (x, y) = %s', pt) cv2.rectangle(screendump_bgr, pt, -- cgit v1.1 From 200cd4b081732c27e50262287ff3f07bf0211f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:31 +0000 Subject: tests/functional: remove todo wrt avocado.utils.wait_for MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're not using avocado anymore, so while the TODO item is still relevant, suggesting use of avocado.utils is not. Reviewed-by: Alex Bennée Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-5-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-5-alex.bennee@linaro.org> --- tests/functional/test_m68k_nextcube.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/functional/test_m68k_nextcube.py b/tests/functional/test_m68k_nextcube.py index 89385a1..0124622 100755 --- a/tests/functional/test_m68k_nextcube.py +++ b/tests/functional/test_m68k_nextcube.py @@ -37,8 +37,7 @@ class NextCubeMachine(QemuSystemTest): self.vm.launch() self.log.info('VM launched, waiting for display') - # TODO: Use avocado.utils.wait.wait_for to catch the - # 'displaysurface_create 1120x832' trace-event. + # TODO: wait for the 'displaysurface_create 1120x832' trace-event. time.sleep(2) self.vm.cmd('human-monitor-command', -- cgit v1.1 From b12b4dbcd0ce9fe5c87c4ebdf1f11eb614ff515a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:32 +0000 Subject: tests/functional: remove leftover :avocado: tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These tags are not honoured under the new functional test harness. Reviewed-by: Alex Bennée Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-6-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-6-alex.bennee@linaro.org> --- tests/functional/test_arm_bpim2u.py | 20 -------------------- tests/functional/test_arm_orangepi.py | 27 --------------------------- 2 files changed, 47 deletions(-) (limited to 'tests') diff --git a/tests/functional/test_arm_bpim2u.py b/tests/functional/test_arm_bpim2u.py index 2f9fa14..35ea58d 100755 --- a/tests/functional/test_arm_bpim2u.py +++ b/tests/functional/test_arm_bpim2u.py @@ -37,11 +37,6 @@ class BananaPiMachine(LinuxKernelTest): '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, @@ -64,11 +59,6 @@ class BananaPiMachine(LinuxKernelTest): 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, @@ -105,11 +95,6 @@ class BananaPiMachine(LinuxKernelTest): 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') @@ -160,11 +145,6 @@ class BananaPiMachine(LinuxKernelTest): @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. diff --git a/tests/functional/test_arm_orangepi.py b/tests/functional/test_arm_orangepi.py index d2ed5fc..6d57223 100755 --- a/tests/functional/test_arm_orangepi.py +++ b/tests/functional/test_arm_orangepi.py @@ -49,11 +49,6 @@ class BananaPiMachine(LinuxKernelTest): '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, @@ -75,11 +70,6 @@ class BananaPiMachine(LinuxKernelTest): 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, @@ -115,12 +105,6 @@ class BananaPiMachine(LinuxKernelTest): 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() @@ -167,11 +151,6 @@ class BananaPiMachine(LinuxKernelTest): @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... @@ -208,12 +187,6 @@ class BananaPiMachine(LinuxKernelTest): @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() -- cgit v1.1 From 57e504ad4f0cc2037aebf18b1ca6f73c8a4b304b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:33 +0000 Subject: tests/functional: remove obsolete reference to avocado bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Historical bugs in avocado related to zstd support are not relevant to the code now that it uses QEMU's native test harness. Reviewed-by: Alex Bennée Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-7-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-7-alex.bennee@linaro.org> --- tests/functional/qemu_test/tuxruntest.py | 1 - 1 file changed, 1 deletion(-) (limited to 'tests') diff --git a/tests/functional/qemu_test/tuxruntest.py b/tests/functional/qemu_test/tuxruntest.py index f05aa96..ed2b238 100644 --- a/tests/functional/qemu_test/tuxruntest.py +++ b/tests/functional/qemu_test/tuxruntest.py @@ -39,7 +39,6 @@ class TuxRunBaselineTest(QemuSystemTest): super().setUp() # We need zstd for all the tuxrun tests - # See https://github.com/avocado-framework/avocado/issues/5609 (has_zstd, msg) = has_cmd('zstd') if has_zstd is False: self.skipTest(msg) -- cgit v1.1 From ebc88b2d54cb4cb29149816a9d1942d548b1ebd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:34 +0000 Subject: tests/functional: remove comments talking about avocado MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first comment is still relevant but should talk about our own test harness instead. The second comment adds no value over reading the code and can be removed. Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-8-berrange@redhat.com> Reviewed-by: Pierrick Bouvier Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-8-alex.bennee@linaro.org> --- tests/functional/test_acpi_bits.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/functional/test_acpi_bits.py b/tests/functional/test_acpi_bits.py index ee40647..4c192d9 100755 --- a/tests/functional/test_acpi_bits.py +++ b/tests/functional/test_acpi_bits.py @@ -196,11 +196,12 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes for filename in os.listdir(bits_test_dir): if os.path.isfile(os.path.join(bits_test_dir, filename)) and \ filename.endswith('.py2'): - # all test scripts are named with extension .py2 so that - # avocado does not try to load them. These scripts are - # written for python 2.7 not python 3 and hence if avocado - # loaded them, it would complain about python 3 specific - # syntaxes. + # All test scripts are named with extension .py2 so that + # they are not run by accident. + # + # These scripts are intended to run inside the test VM + # and are written for python 2.7 not python 3, hence + # would cause syntax errors if loaded ouside the VM. newfilename = os.path.splitext(filename)[0] + '.py' shutil.copy2(os.path.join(bits_test_dir, filename), os.path.join(target_test_dir, newfilename)) @@ -399,8 +400,6 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes # biosbits has been configured to run all the specified test suites # in batch mode and then automatically initiate a vm shutdown. - # Set timeout to BITS_TIMEOUT for SHUTDOWN event from bits VM at par - # with the avocado test timeout. self._vm.event_wait('SHUTDOWN', timeout=BITS_TIMEOUT) self._vm.wait(timeout=None) self.logger.debug("Checking console output ...") -- cgit v1.1 From 03d6c237ccd98f2873d1dc59287f163ad0eb83ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:35 +0000 Subject: tests/functional: honour self.workdir in ACPI bits tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ACPI bits test sets up its own private temporary directory into it creates scratch files. This is justified by a suggestion that we need to be able to preserve the scratch files. We have the ability to preserve the scratch dir with our functional harness, so there's no reason to diverge from standard practice in file placement. Reviewed-by: Alex Bennée Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-9-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-9-alex.bennee@linaro.org> --- tests/functional/test_acpi_bits.py | 44 +++++++++++--------------------------- 1 file changed, 13 insertions(+), 31 deletions(-) (limited to 'tests') diff --git a/tests/functional/test_acpi_bits.py b/tests/functional/test_acpi_bits.py index 4c192d9..3498b96 100755 --- a/tests/functional/test_acpi_bits.py +++ b/tests/functional/test_acpi_bits.py @@ -150,7 +150,6 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._vm = None - self._workDir = None self._baseDir = None self._debugcon_addr = '0x403' @@ -169,7 +168,7 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes config_file = 'bits-cfg.txt' bits_config_dir = os.path.join(self._baseDir, 'acpi-bits', 'bits-config') - target_config_dir = os.path.join(self._workDir, + target_config_dir = os.path.join(self.workdir, 'bits-%d' %self.BITS_INTERNAL_VER, 'boot') self.assertTrue(os.path.exists(bits_config_dir)) @@ -186,7 +185,7 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes bits_test_dir = os.path.join(self._baseDir, 'acpi-bits', 'bits-tests') - target_test_dir = os.path.join(self._workDir, + target_test_dir = os.path.join(self.workdir, 'bits-%d' %self.BITS_INTERNAL_VER, 'boot', 'python') @@ -225,8 +224,8 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes the directory where we have extracted our pre-built bits grub tarball. """ - grub_x86_64_mods = os.path.join(self._workDir, 'grub-inst-x86_64-efi') - grub_i386_mods = os.path.join(self._workDir, 'grub-inst') + grub_x86_64_mods = os.path.join(self.workdir, 'grub-inst-x86_64-efi') + grub_i386_mods = os.path.join(self.workdir, 'grub-inst') self.assertTrue(os.path.exists(grub_x86_64_mods)) self.assertTrue(os.path.exists(grub_i386_mods)) @@ -247,11 +246,11 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes """ Uses grub-mkrescue to generate a fresh bits iso with the python test scripts """ - bits_dir = os.path.join(self._workDir, + bits_dir = os.path.join(self.workdir, 'bits-%d' %self.BITS_INTERNAL_VER) - iso_file = os.path.join(self._workDir, + iso_file = os.path.join(self.workdir, 'bits-%d.iso' %self.BITS_INTERNAL_VER) - mkrescue_script = os.path.join(self._workDir, + mkrescue_script = os.path.join(self.workdir, 'grub-inst-x86_64-efi', 'bin', 'grub-mkrescue') @@ -290,17 +289,7 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes self._baseDir = Path(__file__).parent - # workdir could also be avocado's own workdir in self.workdir. - # At present, I prefer to maintain my own temporary working - # directory. It gives us more control over the generated bits - # log files and also for debugging, we may chose not to remove - # this working directory so that the logs and iso can be - # inspected manually and archived if needed. - self._workDir = tempfile.mkdtemp(prefix='acpi-bits-', - suffix='.tmp') - self.logger.info('working dir: %s', self._workDir) - - prebuiltDir = os.path.join(self._workDir, 'prebuilt') + prebuiltDir = os.path.join(self.workdir, 'prebuilt') if not os.path.isdir(prebuiltDir): os.mkdir(prebuiltDir, mode=0o775) @@ -321,10 +310,10 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes # extract the bits software in the temp working directory with zipfile.ZipFile(bits_zip_file, 'r') as zref: - zref.extractall(self._workDir) + zref.extractall(self.workdir) with tarfile.open(grub_tar_file, 'r', encoding='utf-8') as tarball: - tarball.extractall(self._workDir) + tarball.extractall(self.workdir) self.copy_test_scripts() self.copy_bits_config() @@ -334,7 +323,7 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes """parse the log generated by running bits tests and check for failures. """ - debugconf = os.path.join(self._workDir, self._debugcon_log) + debugconf = os.path.join(self.workdir, self._debugcon_log) log = "" with open(debugconf, 'r', encoding='utf-8') as filehandle: log = filehandle.read() @@ -360,25 +349,18 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes """ if self._vm: self.assertFalse(not self._vm.is_running) - if not os.getenv('BITS_DEBUG') and self._workDir: - self.logger.info('removing the work directory %s', self._workDir) - shutil.rmtree(self._workDir) - else: - self.logger.info('not removing the work directory %s ' \ - 'as BITS_DEBUG is ' \ - 'passed in the environment', self._workDir) super().tearDown() def test_acpi_smbios_bits(self): """The main test case implementation.""" - iso_file = os.path.join(self._workDir, + iso_file = os.path.join(self.workdir, 'bits-%d.iso' %self.BITS_INTERNAL_VER) self.assertTrue(os.access(iso_file, os.R_OK)) self._vm = QEMUBitsMachine(binary=self.qemu_bin, - base_temp_dir=self._workDir, + base_temp_dir=self.workdir, debugcon_log=self._debugcon_log, debugcon_addr=self._debugcon_addr) -- cgit v1.1 From e6d69e0f3b83b7c60d024f41f5eaf130755b090c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:36 +0000 Subject: tests/functional: put QEMUMachine logs in testcase log directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are not passing the 'log_dir' parameter to QEMUMachine, so the QEMU stdout/err logs are being placed in a temp directory and thus deleted after execution. This makes them inaccessible as gitlab CI artifacts. Pass the testcase log directory path into QEMUMachine to make the logs persistent. Reviewed-by: Alex Bennée Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-10-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-10-alex.bennee@linaro.org> --- tests/functional/qemu_test/testcase.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index b9418e2..ca13af2 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -163,10 +163,11 @@ class QemuSystemTest(QemuBaseTest): self.skipTest('no support for device ' + devicename) def _new_vm(self, name, *args): - vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir) + vm = QEMUMachine(self.qemu_bin, + base_temp_dir=self.workdir, + log_dir=self.logdir) self.log.debug('QEMUMachine "%s" created', name) self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir) - self.log.debug('QEMUMachine "%s" log_dir: %s', name, vm.log_dir) if args: vm.add_args(*args) return vm -- cgit v1.1 From 9f85aff93f5dcedb70819a5ed7796b6df90fdf2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:37 +0000 Subject: tests/functional: honour requested test VM name in QEMUMachine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functional test case class is going to the trouble of passing around a machine name, but then fails to give this QEMUMachine. As a result, QEMUMachine will create a completely random name. Since log file names match the machine name, this results in log files accumulating over time. Reviewed-by: Thomas Huth Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-11-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-11-alex.bennee@linaro.org> --- tests/functional/qemu_test/testcase.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index ca13af2..f9c9de1 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -164,6 +164,7 @@ class QemuSystemTest(QemuBaseTest): def _new_vm(self, name, *args): vm = QEMUMachine(self.qemu_bin, + name=name, base_temp_dir=self.workdir, log_dir=self.logdir) self.log.debug('QEMUMachine "%s" created', name) -- cgit v1.1 From 9bcfead1ee1c5d37c39b129557e1528879270fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:38 +0000 Subject: tests/functional: enable debug logging for QEMUMachine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the 'qemu.machine' logger to 'DEBUG' level, to ensure we see log messages related to the QEMUMachine class. Most importantly this ensures we capture the full QEMU command line args for instances we spawn. Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-12-berrange@redhat.com> Tested-by: Thomas Huth Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Reviewed-by: Thomas Huth Message-Id: <20241121165806.476008-12-alex.bennee@linaro.org> --- tests/functional/qemu_test/testcase.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests') diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index f9c9de1..e2a329c 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -57,9 +57,15 @@ class QemuBaseTest(unittest.TestCase): self._log_fh.setFormatter(fileFormatter) self.log.addHandler(self._log_fh) + # Capture QEMUMachine logging + self.machinelog = logging.getLogger('qemu.machine') + self.machinelog.setLevel(logging.DEBUG) + self.machinelog.addHandler(self._log_fh) + def tearDown(self): if "QEMU_TEST_KEEP_SCRATCH" not in os.environ: shutil.rmtree(self.workdir) + self.machinelog.removeHandler(self._log_fh) self.log.removeHandler(self._log_fh) def main(): -- cgit v1.1 From 6f0942b723df9441fe3304e8ab6d87bb17f88a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:39 +0000 Subject: tests/functional: logs details of console interaction operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When functional tests go wrong, it will often be related to the console interaction wait state. By logging the messages that we're looking for, and data we're about to be sending, it'll be easier to diagnose where tests are getting stuck. Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-13-berrange@redhat.com> Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-13-alex.bennee@linaro.org> --- tests/functional/qemu_test/cmd.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tests') diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py index cbabb1c..98722a9 100644 --- a/tests/functional/qemu_test/cmd.py +++ b/tests/functional/qemu_test/cmd.py @@ -85,6 +85,9 @@ def _console_interaction(test, success_message, failure_message, vm = test.vm console = vm.console_file console_logger = logging.getLogger('console') + test.log.debug( + f"Console interaction: success_msg='{success_message}' " + + f"failure_msg='{failure_message}' send_string='{send_string}'") while True: if send_string: vm.console_socket.sendall(send_string.encode()) -- cgit v1.1 From 7699e37b2ac32ba4b905b4b22024e93f33337ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:40 +0000 Subject: tests/functional: don't try to wait for the empty string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Telling exec_command_wand_wait_for_pattern to wait for the empty string does not make any conceptual sense, as a check for empty string will always succeed. It makes even less sense when followed by a call to wait_for_console_pattern() with a real match. Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-14-berrange@redhat.com> Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-14-alex.bennee@linaro.org> --- tests/functional/test_virtio_gpu.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/functional/test_virtio_gpu.py b/tests/functional/test_virtio_gpu.py index 441cbdc..d502748 100755 --- a/tests/functional/test_virtio_gpu.py +++ b/tests/functional/test_virtio_gpu.py @@ -80,9 +80,8 @@ class VirtioGPUx86(QemuSystemTest): self.wait_for_console_pattern("as init process") exec_command_and_wait_for_pattern( - self, "/usr/sbin/modprobe virtio_gpu", "" + self, "/usr/sbin/modprobe virtio_gpu", "features: +virgl +edid" ) - self.wait_for_console_pattern("features: +virgl +edid") def test_vhost_user_vga_virgl(self): # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc -- cgit v1.1 From f03a81897db14bb56109b6adc8699a91774b3389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:41 +0000 Subject: tests/functional: require non-NULL success_message for console wait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When waiting for expected output, the 'success_message' is a mandatory parameter, with 'failure_message' defaulting to None. The code has logic which indicates it was trying to cope with 'success_message' being None and 'failure_message' being non-None but it does not appear able to actually do anything useful. The check for 'success_message is None' will break out of the loop before any check for 'failure_message' has been performed. IOW, for practcal purposes 'success_message' must be non-None unless 'send_string' is set. Assert this expectation and simplify the loop logic. Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-15-berrange@redhat.com> Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-15-alex.bennee@linaro.org> --- tests/functional/qemu_test/cmd.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py index 98722a9..f6c4e4d 100644 --- a/tests/functional/qemu_test/cmd.py +++ b/tests/functional/qemu_test/cmd.py @@ -81,6 +81,8 @@ def is_readable_executable_file(path): def _console_interaction(test, success_message, failure_message, send_string, keep_sending=False, vm=None): assert not keep_sending or send_string + assert success_message or send_string + if vm is None: vm = test.vm console = vm.console_file @@ -95,7 +97,7 @@ def _console_interaction(test, success_message, failure_message, send_string = None # send only once # Only consume console output if waiting for something - if success_message is None and failure_message is None: + if success_message is None: if send_string is None: break continue @@ -107,7 +109,7 @@ def _console_interaction(test, success_message, failure_message, if not msg: continue console_logger.debug(msg) - if success_message is None or success_message in msg: + if success_message in msg: break if failure_message and failure_message in msg: console.close() @@ -138,6 +140,7 @@ def interrupt_interactive_console_until_pattern(test, success_message, :param interrupt_string: a string to send to the console before trying to read a new line """ + assert success_message _console_interaction(test, success_message, failure_message, interrupt_string, True) @@ -152,6 +155,7 @@ def wait_for_console_pattern(test, success_message, failure_message=None, :param success_message: if this message appears, test succeeds :param failure_message: if this message appears, test fails """ + assert success_message _console_interaction(test, success_message, failure_message, None, vm=vm) def exec_command(test, command): @@ -180,6 +184,7 @@ def exec_command_and_wait_for_pattern(test, command, :param success_message: if this message appears, test succeeds :param failure_message: if this message appears, test fails """ + assert success_message _console_interaction(test, success_message, failure_message, command + '\r') def get_qemu_img(test): -- cgit v1.1 From cdad03b74f759857d784e074755f0d96a64d69af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:42 +0000 Subject: tests/functional: rewrite console handling to be bytewise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The console interaction that waits for predicted strings uses readline(), and thus is only capable of waiting for strings that are followed by a newline. This is inconvenient when needing to match on some things, particularly login prompts, or shell prompts, causing tests to use time.sleep(...) instead, which is unreliable. Switch to reading the console 1 byte at a time, comparing against the success/failure messages until we see a match, regardless of whether a newline is encountered. The success/failure comparisons are done with the python bytes type, rather than strings, to avoid the problem of needing to decode partially received multibyte utf8 characters. Heavily inspired by a patch proposed by Cédric, but written again to work in bytes, rather than strings. Co-developed-by: Cédric Le Goater Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-16-berrange@redhat.com> Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-16-alex.bennee@linaro.org> --- tests/functional/qemu_test/cmd.py | 79 +++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 15 deletions(-) (limited to 'tests') diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py index f6c4e4d..11c8334 100644 --- a/tests/functional/qemu_test/cmd.py +++ b/tests/functional/qemu_test/cmd.py @@ -78,6 +78,54 @@ def run_cmd(args): def is_readable_executable_file(path): return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK) +# @test: functional test to fail if @failure is seen +# @vm: the VM whose console to process +# @success: a non-None string to look for +# @failure: a string to look for that triggers test failure, or None +# +# Read up to 1 line of text from @vm, looking for @success +# and optionally @failure. +# +# If @success or @failure are seen, immediately return True, +# even if end of line is not yet seen. ie remainder of the +# line is left unread. +# +# If end of line is seen, with neither @success or @failure +# return False +# +# If @failure is seen, then mark @test as failed +def _console_read_line_until_match(test, vm, success, failure): + msg = bytes([]) + done = False + while True: + c = vm.console_socket.recv(1) + if c is None: + done = True + test.fail( + f"EOF in console, expected '{success}'") + break + msg += c + + if success in msg: + done = True + break + if failure and failure in msg: + done = True + vm.console_socket.close() + test.fail( + f"'{failure}' found in console, expected '{success}'") + + if c == b'\n': + break + + console_logger = logging.getLogger('console') + try: + console_logger.debug(msg.decode().strip()) + except: + console_logger.debug(msg) + + return done + def _console_interaction(test, success_message, failure_message, send_string, keep_sending=False, vm=None): assert not keep_sending or send_string @@ -85,11 +133,22 @@ def _console_interaction(test, success_message, failure_message, if vm is None: vm = test.vm - console = vm.console_file - console_logger = logging.getLogger('console') + test.log.debug( f"Console interaction: success_msg='{success_message}' " + f"failure_msg='{failure_message}' send_string='{send_string}'") + + # We'll process console in bytes, to avoid having to + # deal with unicode decode errors from receiving + # partial utf8 byte sequences + success_message_b = None + if success_message is not None: + success_message_b = success_message.encode() + + failure_message_b = None + if failure_message is not None: + failure_message_b = failure_message.encode() + while True: if send_string: vm.console_socket.sendall(send_string.encode()) @@ -102,20 +161,10 @@ def _console_interaction(test, success_message, failure_message, break continue - try: - msg = console.readline().decode().strip() - except UnicodeDecodeError: - msg = None - if not msg: - continue - console_logger.debug(msg) - if success_message in msg: + if _console_read_line_until_match(test, vm, + success_message_b, + failure_message_b): break - if failure_message and failure_message in msg: - console.close() - fail = 'Failure message found in console: "%s". Expected: "%s"' % \ - (failure_message, success_message) - test.fail(fail) def interrupt_interactive_console_until_pattern(test, success_message, failure_message=None, -- cgit v1.1 From 97d79319f0475fe248962166d9ec4ecf6477d8cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:43 +0000 Subject: tests/functional: remove time.sleep usage from tuxrun tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tuxrun tests send a series of strings to the guest to login and then run commands. Since we have been unable to match on console output that isn't followed by a newline, the test used many time.sleep() statements to pretend to synchronize with the guest. This has proved to be unreliable for the aarch64be instance of the tuxrun tests, with the test often hanging. The hang is a very subtle timing problem, and it is suspected that some (otherwise apparently harmless) I/O error messages could be resulting in full FIFO buffers, stalling interaction with the guest. With the newly rewritten console interaction able to match strings that don't have a following newline, the tux run tests can now match directly on the login prompt, and/or shell PS1 prompt. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2689 Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-17-berrange@redhat.com> Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-17-alex.bennee@linaro.org> --- tests/functional/qemu_test/tuxruntest.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/functional/qemu_test/tuxruntest.py b/tests/functional/qemu_test/tuxruntest.py index ed2b238..ab3b27d 100644 --- a/tests/functional/qemu_test/tuxruntest.py +++ b/tests/functional/qemu_test/tuxruntest.py @@ -124,16 +124,12 @@ class TuxRunBaselineTest(QemuSystemTest): then do a few things on the console. Trigger a shutdown and wait to exit cleanly. """ - self.wait_for_console_pattern("Welcome to TuxTest") - time.sleep(0.2) - exec_command(self, 'root') - time.sleep(0.2) - exec_command(self, 'cat /proc/interrupts') - time.sleep(0.1) - exec_command(self, 'cat /proc/self/maps') - time.sleep(0.1) - exec_command(self, 'uname -a') - time.sleep(0.1) + ps1='root@tuxtest:~#' + self.wait_for_console_pattern('tuxtest login:') + exec_command_and_wait_for_pattern(self, 'root', ps1) + exec_command_and_wait_for_pattern(self, 'cat /proc/interrupts', ps1) + exec_command_and_wait_for_pattern(self, 'cat /proc/self/maps', ps1) + exec_command_and_wait_for_pattern(self, 'uname -a', ps1) exec_command_and_wait_for_pattern(self, 'halt', haltmsg) # Wait for VM to shut down gracefully if it can -- cgit v1.1 From 1a8755a51eef11360af92adf71fed6a20a1260b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:44 +0000 Subject: tests/functional: add a QMP backdoor for debugging stalled tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support the QEMU_TEST_QMP_BACKDOOR=backdoor.sock env variable as a way to get a QMP backdoor for debugging a stalled QEMU test. Most typically this would be used if running the tests directly: $ QEMU_TEST_QMP_BACKDOOR=backdoor.sock \ QEMU_TEST_QEMU_BINARY=./build/qemu-system-arm \ PYTHONPATH=./python \ ./tests/functional/test_arm_tuxrun.py And then, when the test stalls, in a second shell run: $ ./scripts/qmp/qmp-shell backdoor.sock Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-18-berrange@redhat.com> Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-18-alex.bennee@linaro.org> --- tests/functional/qemu_test/testcase.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index e2a329c..fceafb3 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -175,6 +175,13 @@ class QemuSystemTest(QemuBaseTest): log_dir=self.logdir) self.log.debug('QEMUMachine "%s" created', name) self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir) + + sockpath = os.environ.get("QEMU_TEST_QMP_BACKDOOR", None) + if sockpath is not None: + vm.add_args("-chardev", + f"socket,id=backdoor,path={sockpath},server=on,wait=off", + "-mon", "chardev=backdoor,mode=control") + if args: vm.add_args(*args) return vm -- cgit v1.1 From f5578e427f95cb34436a18c0cd4417d4280e61bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 21 Nov 2024 16:57:45 +0000 Subject: tests/functional: avoid accessing log_filename on earlier failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a failure occurs early in the QemuBaseTest constructor, the 'log_filename' object atttribute may not exist yet. This happens most notably if the QEMU_TEST_QEMU_BINARY is not set. We can't initialize 'log_filename' earlier as we use the binary to identify the architecture which is then used to build the path in which the logs are stored. Signed-off-by: Daniel P. Berrangé Message-Id: <20241121154218.1423005-19-berrange@redhat.com> Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-19-alex.bennee@linaro.org> --- tests/functional/qemu_test/testcase.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index fceafb3..90ae59e 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -81,10 +81,12 @@ class QemuBaseTest(unittest.TestCase): res = unittest.main(module = None, testRunner = tr, exit = False, argv=["__dummy__", path]) for (test, message) in res.result.errors + res.result.failures: - print('More information on ' + test.id() + ' could be found here:' - '\n %s' % test.log_filename, file=sys.stderr) - if hasattr(test, 'console_log_name'): - print(' %s' % test.console_log_name, file=sys.stderr) + + if hasattr(test, "log_filename"): + print('More information on ' + test.id() + ' could be found here:' + '\n %s' % test.log_filename, file=sys.stderr) + if hasattr(test, 'console_log_name'): + print(' %s' % test.console_log_name, file=sys.stderr) sys.exit(not res.result.wasSuccessful()) -- cgit v1.1 From 3713690264ea752e84df1369efa0584e5e46bfe2 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 21 Nov 2024 16:57:46 +0000 Subject: tests/functional: Convert the Avocado aarch64 tuxrun tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the tests to a new file so that they can be run via qemu-system-aarch64 in the functional framework. Since these were the last tests in tests/avocado/tuxrun_baselines.py, we can now remove that file, too. Signed-off-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-20-alex.bennee@linaro.org> --- tests/avocado/tuxrun_baselines.py | 224 -------------------------------- tests/functional/meson.build | 2 + tests/functional/test_aarch64_tuxrun.py | 50 +++++++ 3 files changed, 52 insertions(+), 224 deletions(-) delete mode 100644 tests/avocado/tuxrun_baselines.py create mode 100755 tests/functional/test_aarch64_tuxrun.py (limited to 'tests') diff --git a/tests/avocado/tuxrun_baselines.py b/tests/avocado/tuxrun_baselines.py deleted file mode 100644 index 3806484..0000000 --- a/tests/avocado/tuxrun_baselines.py +++ /dev/null @@ -1,224 +0,0 @@ -# Functional test that boots known good tuxboot images the same way -# that tuxrun (www.tuxrun.org) does. This tool is used by things like -# the LKFT project to run regression tests on kernels. -# -# Copyright (c) 2023 Linaro Ltd. -# -# Author: -# Alex Bennée -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os -import time -import tempfile - -from avocado import skip, skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import exec_command, exec_command_and_wait_for_pattern -from avocado_qemu import wait_for_console_pattern -from avocado.utils import process -from avocado.utils.path import find_command - -class TuxRunBaselineTest(QemuSystemTest): - """ - :avocado: tags=accel:tcg - """ - - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0' - # Tests are ~10-40s, allow for --debug/--enable-gcov overhead - timeout = 100 - - def get_tag(self, tagname, default=None): - """ - Get the metadata tag or return the default. - """ - utag = self._get_unique_tag_val(tagname) - print(f"{tagname}/{default} -> {utag}") - if utag: - return utag - - return default - - def setUp(self): - super().setUp() - - # We need zstd for all the tuxrun tests - # See https://github.com/avocado-framework/avocado/issues/5609 - zstd = find_command('zstd', False) - if zstd is False: - self.cancel('Could not find "zstd", which is required to ' - 'decompress rootfs') - self.zstd = zstd - - # Process the TuxRun specific tags, most machines work with - # reasonable defaults but we sometimes need to tweak the - # config. To avoid open coding everything we store all these - # details in the metadata for each test. - - # The tuxboot tag matches the root directory - self.tuxboot = self.get_tag('tuxboot') - - # Most Linux's use ttyS0 for their serial port - self.console = self.get_tag('console', "ttyS0") - - # Does the machine shutdown QEMU nicely on "halt" - self.shutdown = self.get_tag('shutdown') - - # The name of the kernel Image file - self.image = self.get_tag('image', "Image") - - self.root = self.get_tag('root', "vda") - - # Occasionally we need extra devices to hook things up - self.extradev = self.get_tag('extradev') - - self.qemu_img = super().get_qemu_img() - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def fetch_tuxrun_assets(self, csums=None, dt=None): - """ - Fetch the TuxBoot assets. They are stored in a standard way so we - use the per-test tags to fetch details. - """ - base_url = f"https://storage.tuxboot.com/20230331/{self.tuxboot}/" - - # empty hash if we weren't passed one - csums = {} if csums is None else csums - ksum = csums.get(self.image, None) - isum = csums.get("rootfs.ext4.zst", None) - - kernel_image = self.fetch_asset(base_url + self.image, - asset_hash = ksum, - algorithm = "sha256") - disk_image_zst = self.fetch_asset(base_url + "rootfs.ext4.zst", - asset_hash = isum, - algorithm = "sha256") - - cmd = f"{self.zstd} -d {disk_image_zst} -o {self.workdir}/rootfs.ext4" - process.run(cmd) - - if dt: - dsum = csums.get(dt, None) - dtb = self.fetch_asset(base_url + dt, - asset_hash = dsum, - algorithm = "sha256") - else: - dtb = None - - return (kernel_image, self.workdir + "/rootfs.ext4", dtb) - - def prepare_run(self, kernel, disk, drive, dtb=None, console_index=0): - """ - Setup to run and add the common parameters to the system - """ - self.vm.set_console(console_index=console_index) - - # all block devices are raw ext4's - blockdev = "driver=raw,file.driver=file," \ - + f"file.filename={disk},node-name=hd0" - - kcmd_line = self.KERNEL_COMMON_COMMAND_LINE - kcmd_line += f" root=/dev/{self.root}" - kcmd_line += f" console={self.console}" - - self.vm.add_args('-kernel', kernel, - '-append', kcmd_line, - '-blockdev', blockdev) - - # Sometimes we need extra devices attached - if self.extradev: - self.vm.add_args('-device', self.extradev) - - self.vm.add_args('-device', - f"{drive},drive=hd0") - - # Some machines need an explicit DTB - if dtb: - self.vm.add_args('-dtb', dtb) - - def run_tuxtest_tests(self, haltmsg): - """ - Wait for the system to boot up, wait for the login prompt and - then do a few things on the console. Trigger a shutdown and - wait to exit cleanly. - """ - self.wait_for_console_pattern("Welcome to TuxTest") - time.sleep(0.2) - exec_command(self, 'root') - time.sleep(0.2) - exec_command(self, 'cat /proc/interrupts') - time.sleep(0.1) - exec_command(self, 'cat /proc/self/maps') - time.sleep(0.1) - exec_command(self, 'uname -a') - time.sleep(0.1) - exec_command_and_wait_for_pattern(self, 'halt', haltmsg) - - # Wait for VM to shut down gracefully if it can - if self.shutdown == "nowait": - self.vm.shutdown() - else: - self.vm.wait() - - def common_tuxrun(self, - csums=None, - dt=None, - drive="virtio-blk-device", - haltmsg="reboot: System halted", - console_index=0): - """ - Common path for LKFT tests. Unless we need to do something - special with the command line we can process most things using - the tag metadata. - """ - (kernel, disk, dtb) = self.fetch_tuxrun_assets(csums, dt) - - self.prepare_run(kernel, disk, drive, dtb, console_index) - self.vm.launch() - self.run_tuxtest_tests(haltmsg) - - - # - # The tests themselves. The configuration is derived from how - # tuxrun invokes qemu (with minor tweaks like using -blockdev - # consistently). The tuxrun equivalent is something like: - # - # tuxrun --device qemu-{ARCH} \ - # --kernel https://storage.tuxboot.com/{TUXBOOT}/{IMAGE} - # - - def test_arm64(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=cpu:cortex-a57 - :avocado: tags=machine:virt - :avocado: tags=tuxboot:arm64 - :avocado: tags=console:ttyAMA0 - :avocado: tags=shutdown:nowait - """ - sums = {"Image" : - "ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7", - "rootfs.ext4.zst" : - "bbd5ed4b9c7d3f4ca19ba71a323a843c6b585e880115df3b7765769dbd9dd061"} - self.common_tuxrun(csums=sums) - - def test_arm64be(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=cpu:cortex-a57 - :avocado: tags=endian:big - :avocado: tags=machine:virt - :avocado: tags=tuxboot:arm64be - :avocado: tags=console:ttyAMA0 - :avocado: tags=shutdown:nowait - """ - sums = { "Image" : - "e0df4425eb2cd9ea9a283e808037f805641c65d8fcecc8f6407d8f4f339561b4", - "rootfs.ext4.zst" : - "e6ffd8813c8a335bc15728f2835f90539c84be7f8f5f691a8b01451b47fb4bd7"} - self.common_tuxrun(csums=sums) diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 758145d..923f9e7 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -14,6 +14,7 @@ test_timeouts = { 'aarch64_raspi4' : 480, 'aarch64_sbsaref_alpine' : 720, 'aarch64_sbsaref_freebsd' : 720, + 'aarch64_tuxrun' : 240, 'aarch64_virt' : 720, 'acpi_bits' : 420, 'arm_aspeed' : 600, @@ -52,6 +53,7 @@ tests_aarch64_system_thorough = [ 'aarch64_sbsaref', 'aarch64_sbsaref_alpine', 'aarch64_sbsaref_freebsd', + 'aarch64_tuxrun', 'aarch64_virt', 'multiprocess', ] diff --git a/tests/functional/test_aarch64_tuxrun.py b/tests/functional/test_aarch64_tuxrun.py new file mode 100755 index 0000000..da56aee --- /dev/null +++ b/tests/functional/test_aarch64_tuxrun.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# +# Functional test that boots known good tuxboot images the same way +# that tuxrun (www.tuxrun.org) does. This tool is used by things like +# the LKFT project to run regression tests on kernels. +# +# Copyright (c) 2023 Linaro Ltd. +# +# Author: +# Alex Bennée +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import Asset +from qemu_test.tuxruntest import TuxRunBaselineTest + +class TuxRunAarch64Test(TuxRunBaselineTest): + + ASSET_ARM64_KERNEL = Asset( + 'https://storage.tuxboot.com/20230331/arm64/Image', + 'ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7') + ASSET_ARM64_ROOTFS = Asset( + 'https://storage.tuxboot.com/20230331/arm64/rootfs.ext4.zst', + 'bbd5ed4b9c7d3f4ca19ba71a323a843c6b585e880115df3b7765769dbd9dd061') + + def test_arm64(self): + self.set_machine('virt') + self.cpu='cortex-a57' + self.console='ttyAMA0' + self.wait_for_shutdown=False + self.common_tuxrun(kernel_asset=self.ASSET_ARM64_KERNEL, + rootfs_asset=self.ASSET_ARM64_ROOTFS) + + ASSET_ARM64BE_KERNEL = Asset( + 'https://storage.tuxboot.com/20230331/arm64be/Image', + 'e0df4425eb2cd9ea9a283e808037f805641c65d8fcecc8f6407d8f4f339561b4') + ASSET_ARM64BE_ROOTFS = Asset( + 'https://storage.tuxboot.com/20230331/arm64be/rootfs.ext4.zst', + 'e6ffd8813c8a335bc15728f2835f90539c84be7f8f5f691a8b01451b47fb4bd7') + + def test_arm64be(self): + self.set_machine('virt') + self.cpu='cortex-a57' + self.console='ttyAMA0' + self.wait_for_shutdown=False + self.common_tuxrun(kernel_asset=self.ASSET_ARM64BE_KERNEL, + rootfs_asset=self.ASSET_ARM64BE_ROOTFS) + +if __name__ == '__main__': + TuxRunBaselineTest.main() -- cgit v1.1 From abf7c0f1adb3f2fd6f429d449cb68d266db85069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 21 Nov 2024 16:57:48 +0000 Subject: tests/functional: update the aarch64 tuxrun tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now there are new up to date images available we should update to them. With the new rootfs the blk I/O errors also go away on arm64be. Cc: Anders Roxell Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20241121165806.476008-22-alex.bennee@linaro.org> --- tests/functional/test_aarch64_tuxrun.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/functional/test_aarch64_tuxrun.py b/tests/functional/test_aarch64_tuxrun.py index da56aee..75adc8a 100755 --- a/tests/functional/test_aarch64_tuxrun.py +++ b/tests/functional/test_aarch64_tuxrun.py @@ -17,11 +17,11 @@ from qemu_test.tuxruntest import TuxRunBaselineTest class TuxRunAarch64Test(TuxRunBaselineTest): ASSET_ARM64_KERNEL = Asset( - 'https://storage.tuxboot.com/20230331/arm64/Image', - 'ce95a7101a5fecebe0fe630deee6bd97b32ba41bc8754090e9ad8961ea8674c7') + 'https://storage.tuxboot.com/buildroot/20241119/arm64/Image', + 'b74743c5e89e1cea0f73368d24ae0ae85c5204ff84be3b5e9610417417d2f235') ASSET_ARM64_ROOTFS = Asset( - 'https://storage.tuxboot.com/20230331/arm64/rootfs.ext4.zst', - 'bbd5ed4b9c7d3f4ca19ba71a323a843c6b585e880115df3b7765769dbd9dd061') + 'https://storage.tuxboot.com/buildroot/20241119/arm64/rootfs.ext4.zst', + 'a1acaaae2068df4648d04ff75f532aaa8c5edcd6b936122b6f0db4848a07b465') def test_arm64(self): self.set_machine('virt') @@ -32,11 +32,11 @@ class TuxRunAarch64Test(TuxRunBaselineTest): rootfs_asset=self.ASSET_ARM64_ROOTFS) ASSET_ARM64BE_KERNEL = Asset( - 'https://storage.tuxboot.com/20230331/arm64be/Image', - 'e0df4425eb2cd9ea9a283e808037f805641c65d8fcecc8f6407d8f4f339561b4') + 'https://storage.tuxboot.com/buildroot/20241119/arm64be/Image', + 'fd6af4f16689d17a2c24fe0053cc212edcdf77abdcaf301800b8d38fa9f6e109') ASSET_ARM64BE_ROOTFS = Asset( - 'https://storage.tuxboot.com/20230331/arm64be/rootfs.ext4.zst', - 'e6ffd8813c8a335bc15728f2835f90539c84be7f8f5f691a8b01451b47fb4bd7') + 'https://storage.tuxboot.com/buildroot/20241119/arm64be/rootfs.ext4.zst', + 'f5e9371b62701aab8dead52592ca7488c8a9e255c9be8d7635c7f30f477c2c21') def test_arm64be(self): self.set_machine('virt') -- cgit v1.1 From c95309b221ebd6e240a62927836491a6a4a5d397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Fri, 22 Nov 2024 10:03:20 +0100 Subject: tests/functional: Convert Aspeed aarch64 SDK tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the SSH connection which was introduced in the avocado tests to workaround read issues when interacting with console. Signed-off-by: Cédric Le Goater Reviewed-by: Thomas Huth Message-Id: <20241122090322.1934697-2-clg@redhat.com> Signed-off-by: Alex Bennée --- tests/avocado/machine_aspeed.py | 78 -------------------------- tests/functional/meson.build | 2 + tests/functional/test_aarch64_aspeed.py | 98 +++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 78 deletions(-) create mode 100644 tests/functional/test_aarch64_aspeed.py (limited to 'tests') diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py index 241ef18..2240c82 100644 --- a/tests/avocado/machine_aspeed.py +++ b/tests/avocado/machine_aspeed.py @@ -59,17 +59,6 @@ class AST2x00MachineSDK(QemuSystemTest, LinuxSSHMixIn): self, 'boot', '## Loading kernel from FIT Image') self.wait_for_console_pattern('Starting kernel ...') - def do_test_aarch64_aspeed_sdk_start(self, image): - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', - '-net', 'nic', '-net', 'user,hostfwd=:127.0.0.1:0-:22') - - self.vm.launch() - - self.wait_for_console_pattern('U-Boot 2023.10') - self.wait_for_console_pattern('## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') def test_arm_ast2500_evb_sdk(self): """ @@ -133,70 +122,3 @@ class AST2x00MachineSDK(QemuSystemTest, LinuxSSHMixIn): year = time.strftime("%Y") self.ssh_command_output_contains('/sbin/hwclock -f /dev/rtc1', year); - def test_aarch64_ast2700_evb_sdk_v09_02(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:ast2700-evb - """ - - image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/' - 'download/v09.02/ast2700-default-obmc.tar.gz') - image_hash = 'ac969c2602f4e6bdb69562ff466b89ae3fe1d86e1f6797bb7969d787f82116a7' - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - archive.extract(image_path, self.workdir) - - num_cpu = 4 - image_dir = self.workdir + '/ast2700-default/' - uboot_size = os.path.getsize(image_dir + 'u-boot-nodtb.bin') - uboot_dtb_load_addr = hex(0x400000000 + uboot_size) - - load_images_list = [ - { - 'addr': '0x400000000', - 'file': image_dir + 'u-boot-nodtb.bin' - }, - { - 'addr': str(uboot_dtb_load_addr), - 'file': image_dir + 'u-boot.dtb' - }, - { - 'addr': '0x430000000', - 'file': image_dir + 'bl31.bin' - }, - { - 'addr': '0x430080000', - 'file': image_dir + 'optee/tee-raw.bin' - } - ] - - for load_image in load_images_list: - addr = load_image['addr'] - file = load_image['file'] - self.vm.add_args('-device', - f'loader,force-raw=on,addr={addr},file={file}') - - for i in range(num_cpu): - self.vm.add_args('-device', - f'loader,addr=0x430000000,cpu-num={i}') - - self.vm.add_args('-smp', str(num_cpu)) - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test') - self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc') - self.wait_for_console_pattern('nodistro.0 ast2700-default ttyS12') - - self.ssh_connect('root', '0penBmc', False) - self.ssh_command('dmesg -c > /dev/null') - - self.ssh_command_output_contains( - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ' - '&& dmesg -c', - 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d'); - - self.ssh_command_output_contains( - 'cat /sys/class/hwmon/hwmon20/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000) - self.ssh_command_output_contains( - 'cat /sys/class/hwmon/hwmon20/temp1_input', '18000') diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 923f9e7..d6d2c01 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -11,6 +11,7 @@ endif # Timeouts for individual tests that can be slow e.g. with debugging enabled test_timeouts = { + 'aarch64_aspeed' : 600, 'aarch64_raspi4' : 480, 'aarch64_sbsaref_alpine' : 720, 'aarch64_sbsaref_freebsd' : 720, @@ -48,6 +49,7 @@ tests_generic_bsduser = [ ] tests_aarch64_system_thorough = [ + 'aarch64_aspeed', 'aarch64_raspi3', 'aarch64_raspi4', 'aarch64_sbsaref', diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py new file mode 100644 index 0000000..59916ef --- /dev/null +++ b/tests/functional/test_aarch64_aspeed.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED SoCs with firmware +# +# Copyright (C) 2022 ASPEED Technology Inc +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import sys +import os + +from qemu_test import QemuSystemTest, Asset +from qemu_test import wait_for_console_pattern +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test.utils import archive_extract + +class AST2x00MachineSDK(QemuSystemTest): + + def do_test_aarch64_aspeed_sdk_start(self, image): + self.require_netdev('user') + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', + '-net', 'nic', '-net', 'user', '-snapshot') + + self.vm.launch() + + wait_for_console_pattern(self, 'U-Boot 2023.10') + wait_for_console_pattern(self, '## Loading kernel from FIT Image') + wait_for_console_pattern(self, 'Starting kernel ...') + + ASSET_SDK_V902_AST2700 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.02/ast2700-default-obmc.tar.gz', + 'ac969c2602f4e6bdb69562ff466b89ae3fe1d86e1f6797bb7969d787f82116a7') + + def test_aarch64_ast2700_evb_sdk_v09_02(self): + self.set_machine('ast2700-evb') + + image_path = self.ASSET_SDK_V902_AST2700.fetch() + archive_extract(image_path, self.workdir) + + num_cpu = 4 + image_dir = self.workdir + '/ast2700-default/' + uboot_size = os.path.getsize(image_dir + 'u-boot-nodtb.bin') + uboot_dtb_load_addr = hex(0x400000000 + uboot_size) + + load_images_list = [ + { + 'addr': '0x400000000', + 'file': image_dir + 'u-boot-nodtb.bin' + }, + { + 'addr': str(uboot_dtb_load_addr), + 'file': image_dir + 'u-boot.dtb' + }, + { + 'addr': '0x430000000', + 'file': image_dir + 'bl31.bin' + }, + { + 'addr': '0x430080000', + 'file': image_dir + 'optee/tee-raw.bin' + } + ] + + for load_image in load_images_list: + addr = load_image['addr'] + file = load_image['file'] + self.vm.add_args('-device', + f'loader,force-raw=on,addr={addr},file={file}') + + for i in range(num_cpu): + self.vm.add_args('-device', + f'loader,addr=0x430000000,cpu-num={i}') + + self.vm.add_args('-smp', str(num_cpu)) + self.vm.add_args('-device', + 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test') + self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc') + + wait_for_console_pattern(self, 'ast2700-default login:') + + exec_command_and_wait_for_pattern(self, 'root', 'Password:') + exec_command_and_wait_for_pattern(self, + '0penBmc', 'root@ast2700-default:~#') + + exec_command_and_wait_for_pattern(self, + 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ', + 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d'); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon20/temp1_input', '0') + self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', + property='temperature', value=18000) + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon20/temp1_input', '18000') + + +if __name__ == '__main__': + QemuSystemTest.main() -- cgit v1.1 From f9ab0f467863a52445a37f36d7cf2dbd95db7553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Fri, 22 Nov 2024 10:03:21 +0100 Subject: tests/functional: Convert Aspeed arm SDK tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the SSH connection which was introduced in the avocado tests to workaround read issues when interacting with console. EXTRA_BOOTARGS was introduced to reduce the console output at Linux boot time. This didn't have the desired effect as we still had issues when trying to match patterns on the console and we had to use the ssh connection as a workaround. While at it, remove the U-Boot EXTRA_BOOTARGS variable which has become useless. Signed-off-by: Cédric Le Goater Reviewed-by: Thomas Huth Message-Id: <20241122090322.1934697-3-clg@redhat.com> Signed-off-by: Alex Bennée --- tests/avocado/machine_aspeed.py | 124 ------------------------------------ tests/functional/test_arm_aspeed.py | 68 ++++++++++++++++++++ 2 files changed, 68 insertions(+), 124 deletions(-) delete mode 100644 tests/avocado/machine_aspeed.py (limited to 'tests') diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py deleted file mode 100644 index 2240c82..0000000 --- a/tests/avocado/machine_aspeed.py +++ /dev/null @@ -1,124 +0,0 @@ -# Functional test that boots the ASPEED SoCs with firmware -# -# Copyright (C) 2022 ASPEED Technology Inc -# -# 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 -import os -import tempfile -import subprocess - -from avocado_qemu import LinuxSSHMixIn -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado_qemu import exec_command -from avocado_qemu import exec_command_and_wait_for_pattern -from avocado_qemu import interrupt_interactive_console_until_pattern -from avocado_qemu import has_cmd -from avocado.utils import archive -from avocado import skipUnless - -class AST2x00MachineSDK(QemuSystemTest, LinuxSSHMixIn): - - EXTRA_BOOTARGS = ( - 'quiet ' - 'systemd.mask=org.openbmc.HostIpmi.service ' - 'systemd.mask=xyz.openbmc_project.Chassis.Control.Power@0.service ' - 'systemd.mask=modprobe@fuse.service ' - 'systemd.mask=rngd.service ' - 'systemd.mask=obmc-console@ttyS2.service ' - ) - - # FIXME: Although these tests boot a whole distro they are still - # slower than comparable machine models. There may be some - # optimisations which bring down the runtime. In the meantime they - # have generous timeouts and are disable for CI which aims for all - # tests to run in less than 60 seconds. - timeout = 240 - - def wait_for_console_pattern(self, success_message, vm=None): - wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing', - vm=vm) - - def do_test_arm_aspeed_sdk_start(self, image): - self.require_netdev('user') - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', - '-net', 'nic', '-net', 'user,hostfwd=:127.0.0.1:0-:22') - self.vm.launch() - - self.wait_for_console_pattern('U-Boot 2019.04') - interrupt_interactive_console_until_pattern( - self, 'Hit any key to stop autoboot:', 'ast#') - exec_command_and_wait_for_pattern( - self, 'setenv bootargs ${bootargs} ' + self.EXTRA_BOOTARGS, 'ast#') - exec_command_and_wait_for_pattern( - self, 'boot', '## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - def test_arm_ast2500_evb_sdk(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast2500-evb - :avocado: tags=flaky - """ - - image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/' - 'download/v08.06/ast2500-default-obmc.tar.gz') - image_hash = ('e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - archive.extract(image_path, self.workdir) - - self.do_test_arm_aspeed_sdk_start( - self.workdir + '/ast2500-default/image-bmc') - self.wait_for_console_pattern('nodistro.0 ast2500-default ttyS4') - - @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') - def test_arm_ast2600_evb_sdk(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:ast2600-evb - :avocado: tags=flaky - """ - - image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/' - 'download/v08.06/ast2600-a2-obmc.tar.gz') - image_hash = ('9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4') - image_path = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - archive.extract(image_path, self.workdir) - - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test'); - self.vm.add_args('-device', - 'ds1338,bus=aspeed.i2c.bus.5,address=0x32'); - self.do_test_arm_aspeed_sdk_start( - self.workdir + '/ast2600-a2/image-bmc') - self.wait_for_console_pattern('nodistro.0 ast2600-a2 ttyS4') - - self.ssh_connect('root', '0penBmc', False) - self.ssh_command('dmesg -c > /dev/null') - - self.ssh_command_output_contains( - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device ; ' - 'dmesg -c', - 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d'); - self.ssh_command_output_contains( - 'cat /sys/class/hwmon/hwmon19/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000); - self.ssh_command_output_contains( - 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000') - - self.ssh_command_output_contains( - 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device ; ' - 'dmesg -c', - 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32'); - year = time.strftime("%Y") - self.ssh_command_output_contains('/sbin/hwclock -f /dev/rtc1', year); - diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py index 5fb1adf..c2c1522 100755 --- a/tests/functional/test_arm_aspeed.py +++ b/tests/functional/test_arm_aspeed.py @@ -252,6 +252,74 @@ class AST2x00Machine(LinuxKernelTest): self.do_test_arm_aspeed_buildroot_poweroff() + def do_test_arm_aspeed_sdk_start(self, image): + self.require_netdev('user') + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', + '-net', 'nic', '-net', 'user', '-snapshot') + self.vm.launch() + + self.wait_for_console_pattern('U-Boot 2019.04') + self.wait_for_console_pattern('## Loading kernel from FIT Image') + self.wait_for_console_pattern('Starting kernel ...') + + ASSET_SDK_V806_AST2500 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz', + 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca') + + def test_arm_ast2500_evb_sdk(self): + self.set_machine('ast2500-evb') + + image_path = self.ASSET_SDK_V806_AST2500.fetch() + + archive_extract(image_path, self.workdir) + + self.do_test_arm_aspeed_sdk_start( + self.workdir + '/ast2500-default/image-bmc') + + self.wait_for_console_pattern('ast2500-default login:') + + ASSET_SDK_V806_AST2600_A2 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz', + '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4') + + def test_arm_ast2600_evb_sdk(self): + self.set_machine('ast2600-evb') + + image_path = self.ASSET_SDK_V806_AST2600_A2.fetch() + + archive_extract(image_path, self.workdir) + + self.vm.add_args('-device', + 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test'); + self.vm.add_args('-device', + 'ds1338,bus=aspeed.i2c.bus.5,address=0x32'); + self.do_test_arm_aspeed_sdk_start( + self.workdir + '/ast2600-a2/image-bmc') + + self.wait_for_console_pattern('ast2600-a2 login:') + + exec_command_and_wait_for_pattern(self, 'root', 'Password:') + exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#') + + exec_command_and_wait_for_pattern(self, + 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device', + 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d'); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon19/temp1_input', '0') + self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', + property='temperature', value=18000); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000') + + exec_command_and_wait_for_pattern(self, + 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device', + 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32'); + year = time.strftime("%Y") + exec_command_and_wait_for_pattern(self, + '/sbin/hwclock -f /dev/rtc1', year); + + class AST2x00MachineMMC(LinuxKernelTest): ASSET_RAINIER_EMMC = Asset( -- cgit v1.1 From f8f5923808031e1335fc6d280a4b959ed5d28608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Fri, 22 Nov 2024 10:03:22 +0100 Subject: tests/functional: Remove sleep workarounds from Aspeed tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were introduced in the avocado tests to workaround read issues when interacting with console. They are no longer necessary and we can use the expected "login:" string or the command prompt now. Drop the last use of exec_command. Signed-off-by: Cédric Le Goater Reviewed-by: Thomas Huth Message-Id: <20241122090322.1934697-4-clg@redhat.com> Signed-off-by: Alex Bennée --- tests/functional/test_arm_aspeed.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py index c2c1522..d88170a 100755 --- a/tests/functional/test_arm_aspeed.py +++ b/tests/functional/test_arm_aspeed.py @@ -14,7 +14,6 @@ import tempfile from qemu_test import LinuxKernelTest, Asset from qemu_test import exec_command_and_wait_for_pattern from qemu_test import interrupt_interactive_console_until_pattern -from qemu_test import exec_command from qemu_test import has_cmd from qemu_test.utils import archive_extract from zipfile import ZipFile @@ -136,10 +135,8 @@ class AST2x00Machine(LinuxKernelTest): self.wait_for_console_pattern('lease of 10.0.2.15') # the line before login: self.wait_for_console_pattern(pattern) - time.sleep(0.1) - exec_command(self, 'root') - time.sleep(0.1) - exec_command(self, "passw0rd") + exec_command_and_wait_for_pattern(self, 'root', 'Password:') + exec_command_and_wait_for_pattern(self, 'passw0rd', '#') def do_test_arm_aspeed_buildroot_poweroff(self): exec_command_and_wait_for_pattern(self, 'poweroff', @@ -158,7 +155,7 @@ class AST2x00Machine(LinuxKernelTest): self.vm.add_args('-device', 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); self.do_test_arm_aspeed_buildroot_start(image_path, '0x0', - 'Aspeed AST2500 EVB') + 'ast2500-evb login:') exec_command_and_wait_for_pattern(self, 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', @@ -188,7 +185,8 @@ class AST2x00Machine(LinuxKernelTest): 'ds1338,bus=aspeed.i2c.bus.3,address=0x32'); self.vm.add_args('-device', 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42'); - self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', 'Aspeed AST2600 EVB') + self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', + 'ast2600-evb login:') exec_command_and_wait_for_pattern(self, 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', @@ -209,8 +207,8 @@ class AST2x00Machine(LinuxKernelTest): exec_command_and_wait_for_pattern(self, 'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device', 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64'); - exec_command(self, 'i2cset -y 3 0x42 0x64 0x00 0xaa i'); - time.sleep(0.1) + exec_command_and_wait_for_pattern(self, + 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#'); exec_command_and_wait_for_pattern(self, 'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom', '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff'); -- cgit v1.1