aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitlab-ci.d/check-dco.py5
-rw-r--r--MAINTAINERS4
-rw-r--r--block/parallels.c4
-rw-r--r--block/ssh.c3
-rw-r--r--docs/devel/submitting-a-patch.rst7
-rw-r--r--docs/devel/testing/functional.rst16
-rw-r--r--hw/core/qdev-properties-system.c54
-rw-r--r--include/qemu/qemu-plugin.h1
-rw-r--r--migration/fd.c27
-rw-r--r--migration/savevm.c1
-rw-r--r--plugins/meson.build12
-rw-r--r--plugins/qemu-plugins.symbols59
-rw-r--r--python/scripts/mkvenv.py3
-rw-r--r--python/setup.cfg1
-rw-r--r--rust/hw/char/pl011/src/device.rs2
-rwxr-xr-xscripts/qemu-plugin-symbols.py45
-rw-r--r--system/qdev-monitor.c42
-rw-r--r--system/vl.c14
-rw-r--r--tests/avocado/hotplug_blk.py2
-rw-r--r--tests/avocado/machine_aspeed.py202
-rw-r--r--tests/avocado/tuxrun_baselines.py224
-rw-r--r--tests/functional/meson.build4
-rw-r--r--tests/functional/qemu_test/cmd.py89
-rw-r--r--tests/functional/qemu_test/testcase.py43
-rw-r--r--tests/functional/qemu_test/tuxruntest.py17
-rw-r--r--tests/functional/test_aarch64_aspeed.py98
-rwxr-xr-xtests/functional/test_aarch64_tuxrun.py50
-rwxr-xr-xtests/functional/test_acpi_bits.py57
-rwxr-xr-xtests/functional/test_arm_aspeed.py84
-rwxr-xr-xtests/functional/test_arm_bpim2u.py20
-rwxr-xr-xtests/functional/test_arm_orangepi.py27
-rwxr-xr-xtests/functional/test_m68k_nextcube.py3
-rwxr-xr-xtests/functional/test_mips64el_malta.py4
-rwxr-xr-xtests/functional/test_virtio_gpu.py3
-rw-r--r--tests/qemu-iotests/iotests.py11
-rw-r--r--tests/qemu-iotests/pylintrc1
36 files changed, 554 insertions, 685 deletions
diff --git a/.gitlab-ci.d/check-dco.py b/.gitlab-ci.d/check-dco.py
index d221b16bd5..70dec7d6ee 100755
--- a/.gitlab-ci.d/check-dco.py
+++ b/.gitlab-ci.d/check-dco.py
@@ -78,7 +78,10 @@ of Origin 1.1 (DCO):
To indicate acceptance of the DCO every commit must have a tag
- Signed-off-by: REAL NAME <EMAIL>
+ Signed-off-by: YOUR NAME <EMAIL>
+
+where "YOUR NAME" is your commonly known identity in the context
+of the community.
This can be achieved by passing the "-s" flag to the "git commit" command.
diff --git a/MAINTAINERS b/MAINTAINERS
index acc7405aed..2b1c4abed6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -994,6 +994,7 @@ F: hw/arm/virt*
F: include/hw/arm/virt.h
F: docs/system/arm/virt.rst
F: tests/functional/test_aarch64_virt.py
+F: tests/functional/test_aarch64_tuxrun.py
F: tests/functional/test_arm_tuxrun.py
Xilinx Zynq
@@ -3751,6 +3752,7 @@ F: plugins/
F: tests/tcg/plugins/
F: tests/functional/test_aarch64_tcg_plugins.py
F: contrib/plugins/
+F: scripts/qemu-plugin-symbols.py
AArch64 TCG target
M: Richard Henderson <richard.henderson@linaro.org>
@@ -4129,7 +4131,7 @@ F: scripts/ci/
F: tests/docker/
F: tests/vm/
F: tests/lcitool/
-F: tests/avocado/tuxrun_baselines.py
+F: tests/functional/test_*_tuxrun.py
F: scripts/archive-source.sh
F: docs/devel/testing.rst
W: https://gitlab.com/qemu-project/qemu/pipelines
diff --git a/block/parallels.c b/block/parallels.c
index 9205a0864f..071b6dcaf8 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -184,11 +184,11 @@ static int mark_used(BlockDriverState *bs, unsigned long *bitmap,
BDRVParallelsState *s = bs->opaque;
uint32_t cluster_index = host_cluster_index(s, off);
unsigned long next_used;
- if (cluster_index + count > bitmap_size) {
+ if ((uint64_t)cluster_index + count > bitmap_size) {
return -E2BIG;
}
next_used = find_next_bit(bitmap, bitmap_size, cluster_index);
- if (next_used < cluster_index + count) {
+ if (next_used < (uint64_t)cluster_index + count) {
return -EBUSY;
}
bitmap_set(bitmap, cluster_index, count);
diff --git a/block/ssh.c b/block/ssh.c
index 9f8140bcb6..b9f33ec739 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -866,9 +866,6 @@ static int ssh_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
goto err;
}
- /* Go non-blocking. */
- ssh_set_blocking(s->session, 0);
-
if (s->attrs->type == SSH_FILEXFER_TYPE_REGULAR) {
bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
}
diff --git a/docs/devel/submitting-a-patch.rst b/docs/devel/submitting-a-patch.rst
index 83e9092b8c..10b062eec2 100644
--- a/docs/devel/submitting-a-patch.rst
+++ b/docs/devel/submitting-a-patch.rst
@@ -18,7 +18,7 @@ one-shot fix, the bare minimum we ask is that:
* - Check
- Reason
- * - Patches contain Signed-off-by: Real Name <author@email>
+ * - Patches contain Signed-off-by: Your Name <author@email>
- States you are legally able to contribute the code. See :ref:`patch_emails_must_include_a_signed_off_by_line`
* - Sent as patch emails to ``qemu-devel@nongnu.org``
- The project uses an email list based workflow. See :ref:`submitting_your_patches`
@@ -335,6 +335,11 @@ include a "From:" line in the body of the email (different from your
envelope From:) that will give credit to the correct author; but again,
that author's Signed-off-by: line is mandatory, with the same spelling.
+The name used with "Signed-off-by" does not need to be your legal name,
+nor birth name, nor appear on any government ID. It is the identity you
+choose to be known by in the community, but should not be anonymous,
+nor misrepresent whom you are.
+
There are various tooling options for automatically adding these tags
include using ``git commit -s`` or ``git format-patch -s``. For more
information see `SubmittingPatches 1.12
diff --git a/docs/devel/testing/functional.rst b/docs/devel/testing/functional.rst
index bf6f1bb81e..b8ad7b0bf7 100644
--- a/docs/devel/testing/functional.rst
+++ b/docs/devel/testing/functional.rst
@@ -65,6 +65,12 @@ to the QEMU binary that should be used for the test, for example::
$ export QEMU_TEST_QEMU_BINARY=$PWD/qemu-system-x86_64
$ python3 ../tests/functional/test_file.py
+The test framework will automatically purge any scratch files created during
+the tests. If needing to debug a failed test, it is possible to keep these
+files around on disk by setting ```QEMU_TEST_KEEP_SCRATCH=1``` as an env
+variable. Any preserved files will be deleted the next time the test is run
+without this variable set.
+
Overview
--------
@@ -170,6 +176,16 @@ primarily depend on the value of the ``qemu_bin`` class attribute.
If it is not explicitly set by the test code, its default value will
be the result the QEMU_TEST_QEMU_BINARY environment variable.
+Debugging hung QEMU
+^^^^^^^^^^^^^^^^^^^
+
+When test cases go wrong it may be helpful to debug a stalled QEMU
+process. While the QEMUMachine class owns the primary QMP monitor
+socket, it is possible to request a second QMP monitor be created
+by setting the ``QEMU_TEST_QMP_BACKDOOR`` env variable to refer
+to a UNIX socket name. The ``qmp-shell`` command can then be
+attached to the stalled QEMU to examine its live state.
+
Attribute reference
-------------------
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index a61c5ee6dd..22ea1ed358 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -816,39 +816,57 @@ static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
Property *prop = opaque;
+ g_autofree GenericAlternate *alt;
int32_t value, *ptr = object_field_prop_ptr(obj, prop);
unsigned int slot, fn, n;
- char *str;
+ g_autofree char *str = NULL;
+
+ if (!visit_start_alternate(v, name, &alt, sizeof(*alt), errp)) {
+ return;
+ }
+
+ switch (alt->type) {
+ case QTYPE_QSTRING:
+ if (!visit_type_str(v, name, &str, errp)) {
+ goto out;
+ }
- if (!visit_type_str(v, name, &str, NULL)) {
+ if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
+ fn = 0;
+ if (sscanf(str, "%x%n", &slot, &n) != 1) {
+ goto invalid;
+ }
+ }
+ if (str[n] != '\0' || fn > 7 || slot > 31) {
+ goto invalid;
+ }
+ *ptr = slot << 3 | fn;
+ break;
+
+ case QTYPE_QNUM:
if (!visit_type_int32(v, name, &value, errp)) {
- return;
+ goto out;
}
if (value < -1 || value > 255) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name ? name : "null", "a value between -1 and 255");
- return;
+ goto out;
}
*ptr = value;
- return;
- }
+ break;
- if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
- fn = 0;
- if (sscanf(str, "%x%n", &slot, &n) != 1) {
- goto invalid;
- }
- }
- if (str[n] != '\0' || fn > 7 || slot > 31) {
- goto invalid;
+ default:
+ error_setg(errp, "Invalid parameter type for '%s', expected int or str",
+ name ? name : "null");
+ goto out;
}
- *ptr = slot << 3 | fn;
- g_free(str);
- return;
+
+ goto out;
invalid:
error_set_from_qdev_prop_error(errp, EINVAL, obj, name, str);
- g_free(str);
+out:
+ visit_end_alternate(v, (void **) &alt);
}
static int print_pci_devfn(Object *obj, Property *prop, char *dest,
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 622c9a0232..0fba36ae02 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -803,6 +803,7 @@ void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
qemu_plugin_udata_cb_t cb, void *userdata);
/* returns how many vcpus were started at this point */
+QEMU_PLUGIN_API
int qemu_plugin_num_vcpus(void);
/**
diff --git a/migration/fd.c b/migration/fd.c
index aab5189eac..9bf9be6acb 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -25,6 +25,29 @@
#include "io/channel-util.h"
#include "trace.h"
+static bool fd_is_pipe(int fd)
+{
+ struct stat statbuf;
+
+ if (fstat(fd, &statbuf) == -1) {
+ return false;
+ }
+
+ return S_ISFIFO(statbuf.st_mode);
+}
+
+static bool migration_fd_valid(int fd)
+{
+ if (fd_is_socket(fd)) {
+ return true;
+ }
+
+ if (fd_is_pipe(fd)) {
+ return true;
+ }
+
+ return false;
+}
void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
{
@@ -34,7 +57,7 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
return;
}
- if (!fd_is_socket(fd)) {
+ if (!migration_fd_valid(fd)) {
warn_report("fd: migration to a file is deprecated."
" Use file: instead.");
}
@@ -68,7 +91,7 @@ void fd_start_incoming_migration(const char *fdname, Error **errp)
return;
}
- if (!fd_is_socket(fd)) {
+ if (!migration_fd_valid(fd)) {
warn_report("fd: migration to a file is deprecated."
" Use file: instead.");
}
diff --git a/migration/savevm.c b/migration/savevm.c
index f4e4876f72..98821c8120 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2057,7 +2057,6 @@ static void *postcopy_ram_listen_thread(void *opaque)
* got a bad migration state).
*/
migration_incoming_state_destroy();
- qemu_loadvm_state_cleanup();
rcu_unregister_thread();
mis->have_listen_thread = false;
diff --git a/plugins/meson.build b/plugins/meson.build
index 1cc039d29b..98542e926f 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -2,17 +2,23 @@ if not get_option('plugins')
subdir_done()
endif
+qemu_plugin_symbols = configure_file(
+ input: files('../include/qemu/qemu-plugin.h'),
+ output: 'qemu-plugin.symbols',
+ capture: true,
+ command: [files('../scripts/qemu-plugin-symbols.py'), '@INPUT@'])
+
# Modules need more symbols than just those in plugins/qemu-plugins.symbols
if not enable_modules
if host_os == 'darwin'
configure_file(
- input: files('qemu-plugins.symbols'),
+ input: qemu_plugin_symbols,
output: 'qemu-plugins-ld64.symbols',
capture: true,
command: ['sed', '-ne', 's/^[[:space:]]*\\(qemu_.*\\);/_\\1/p', '@INPUT@'])
emulator_link_args += ['-Wl,-exported_symbols_list,plugins/qemu-plugins-ld64.symbols']
else
- emulator_link_args += ['-Xlinker', '--dynamic-list=' + (meson.project_source_root() / 'plugins/qemu-plugins.symbols')]
+ emulator_link_args += ['-Xlinker', '--dynamic-list=' + qemu_plugin_symbols.full_path()]
endif
endif
@@ -23,7 +29,7 @@ if host_os == 'windows'
# First, create a .def file listing all the symbols a plugin should expect to have
# available in qemu
win32_plugin_def = configure_file(
- input: files('qemu-plugins.symbols'),
+ input: qemu_plugin_symbols,
output: 'qemu_plugin_api.def',
capture: true,
command: ['sed', '-e', '0,/^/s//EXPORTS/; s/[{};]//g', '@INPUT@'])
diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
deleted file mode 100644
index 032661f9ea..0000000000
--- a/plugins/qemu-plugins.symbols
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- qemu_plugin_bool_parse;
- qemu_plugin_end_code;
- qemu_plugin_entry_code;
- qemu_plugin_get_hwaddr;
- qemu_plugin_get_registers;
- qemu_plugin_hwaddr_device_name;
- qemu_plugin_hwaddr_is_io;
- qemu_plugin_hwaddr_phys_addr;
- qemu_plugin_insn_data;
- qemu_plugin_insn_disas;
- qemu_plugin_insn_haddr;
- qemu_plugin_insn_size;
- qemu_plugin_insn_symbol;
- qemu_plugin_insn_vaddr;
- qemu_plugin_mem_get_value;
- qemu_plugin_mem_is_big_endian;
- qemu_plugin_mem_is_sign_extended;
- qemu_plugin_mem_is_store;
- qemu_plugin_mem_size_shift;
- qemu_plugin_num_vcpus;
- qemu_plugin_outs;
- qemu_plugin_path_to_binary;
- qemu_plugin_read_memory_vaddr;
- qemu_plugin_read_register;
- qemu_plugin_register_atexit_cb;
- qemu_plugin_register_flush_cb;
- qemu_plugin_register_vcpu_exit_cb;
- qemu_plugin_register_vcpu_idle_cb;
- qemu_plugin_register_vcpu_init_cb;
- qemu_plugin_register_vcpu_insn_exec_cb;
- qemu_plugin_register_vcpu_insn_exec_cond_cb;
- qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu;
- qemu_plugin_register_vcpu_mem_cb;
- qemu_plugin_register_vcpu_mem_inline_per_vcpu;
- qemu_plugin_register_vcpu_resume_cb;
- qemu_plugin_register_vcpu_syscall_cb;
- qemu_plugin_register_vcpu_syscall_ret_cb;
- qemu_plugin_register_vcpu_tb_exec_cb;
- qemu_plugin_register_vcpu_tb_exec_cond_cb;
- qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu;
- qemu_plugin_register_vcpu_tb_trans_cb;
- qemu_plugin_request_time_control;
- qemu_plugin_reset;
- qemu_plugin_scoreboard_free;
- qemu_plugin_scoreboard_find;
- qemu_plugin_scoreboard_new;
- qemu_plugin_start_code;
- qemu_plugin_tb_get_insn;
- qemu_plugin_tb_n_insns;
- qemu_plugin_tb_vaddr;
- qemu_plugin_u64_add;
- qemu_plugin_u64_get;
- qemu_plugin_u64_set;
- qemu_plugin_u64_sum;
- qemu_plugin_uninstall;
- qemu_plugin_update_ns;
- qemu_plugin_vcpu_for_each;
-};
diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py
index f2526af0a0..8ac5b0b2a0 100644
--- a/python/scripts/mkvenv.py
+++ b/python/scripts/mkvenv.py
@@ -379,6 +379,9 @@ def make_venv( # pylint: disable=too-many-arguments
try:
builder.create(str(env_dir))
except SystemExit as exc:
+ # pylint 3.3 bug:
+ # pylint: disable=raising-non-exception, raise-missing-from
+
# Some versions of the venv module raise SystemExit; *nasty*!
# We want the exception that prompted it. It might be a subprocess
# error that has output we *really* want to see.
diff --git a/python/setup.cfg b/python/setup.cfg
index 3b4e2cc550..cf5af7e664 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -142,6 +142,7 @@ ignore_missing_imports = True
disable=consider-using-f-string,
consider-using-with,
too-many-arguments,
+ too-many-positional-arguments,
too-many-function-args, # mypy handles this with less false positives.
too-many-instance-attributes,
no-member, # mypy also handles this better.
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs
index 2a85960b81..476cacc844 100644
--- a/rust/hw/char/pl011/src/device.rs
+++ b/rust/hw/char/pl011/src/device.rs
@@ -182,7 +182,7 @@ impl PL011State {
use RegisterOffset::*;
std::ops::ControlFlow::Break(match RegisterOffset::try_from(offset) {
- Err(v) if (0x3f8..0x400).contains(&v) => {
+ Err(v) if (0x3f8..0x400).contains(&(v >> 2)) => {
u64::from(self.device_id[(offset - 0xfe0) >> 2])
}
Err(_) => {
diff --git a/scripts/qemu-plugin-symbols.py b/scripts/qemu-plugin-symbols.py
new file mode 100755
index 0000000000..e285ebb8f9
--- /dev/null
+++ b/scripts/qemu-plugin-symbols.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Extract QEMU Plugin API symbols from a header file
+#
+# Copyright 2024 Linaro Ltd
+#
+# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import argparse
+import re
+
+def extract_symbols(plugin_header):
+ with open(plugin_header) as file:
+ content = file.read()
+ # Remove QEMU_PLUGIN_API macro definition.
+ content = content.replace('#define QEMU_PLUGIN_API', '')
+ expected = content.count('QEMU_PLUGIN_API')
+ # Find last word between QEMU_PLUGIN_API and (, matching on several lines.
+ # We use *? non-greedy quantifier.
+ syms = re.findall(r'QEMU_PLUGIN_API.*?(\w+)\s*\(', content, re.DOTALL)
+ syms.sort()
+ # Ensure we found as many symbols as API markers.
+ assert len(syms) == expected
+ return syms
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description='Extract QEMU plugin symbols')
+ parser.add_argument('plugin_header', help='Path to QEMU plugin header.')
+ args = parser.parse_args()
+
+ syms = extract_symbols(args.plugin_header)
+
+ print('{')
+ for s in syms:
+ print(" {};".format(s))
+ print('};')
+
+if __name__ == '__main__':
+ main()
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 4c09b38ffb..03ae610649 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -856,18 +856,9 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict)
void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
{
- QemuOpts *opts;
DeviceState *dev;
- opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, errp);
- if (!opts) {
- return;
- }
- if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
- qemu_opts_del(opts);
- return;
- }
- dev = qdev_device_add(opts, errp);
+ dev = qdev_device_add_from_qdict(qdict, true, errp);
if (!dev) {
/*
* Drain all pending RCU callbacks. This is done because
@@ -879,9 +870,6 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
* to the user
*/
drain_call_rcu();
-
- qemu_opts_del(opts);
- return;
}
object_unref(OBJECT(dev));
}
@@ -1018,8 +1006,34 @@ void qmp_device_sync_config(const char *id, Error **errp)
void hmp_device_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
+ QemuOpts *opts;
+ DeviceState *dev;
- qmp_device_add((QDict *)qdict, NULL, &err);
+ opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &err);
+ if (!opts) {
+ goto out;
+ }
+ if (qdev_device_help(opts)) {
+ qemu_opts_del(opts);
+ return;
+ }
+ dev = qdev_device_add(opts, &err);
+ if (!dev) {
+ /*
+ * Drain all pending RCU callbacks. This is done because
+ * some bus related operations can delay a device removal
+ * (in this case this can happen if device is added and then
+ * removed due to a configuration error)
+ * to a RCU callback, but user might expect that this interface
+ * will finish its job completely once qmp command returns result
+ * to the user
+ */
+ drain_call_rcu();
+
+ qemu_opts_del(opts);
+ }
+ object_unref(dev);
+out:
hmp_handle_error(mon, err);
}
diff --git a/system/vl.c b/system/vl.c
index 3bb8f2db9a..54998fdbc7 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2653,17 +2653,11 @@ static void qemu_create_cli_devices(void)
qemu_opts_foreach(qemu_find_opts("device"),
device_init_func, NULL, &error_fatal);
QTAILQ_FOREACH(opt, &device_opts, next) {
- DeviceState *dev;
+ QObject *ret_data = NULL;
+
loc_push_restore(&opt->loc);
- /*
- * TODO Eventually we should call qmp_device_add() here to make sure it
- * behaves the same, but QMP still has to accept incorrectly typed
- * options until libvirt is fixed and we want to be strict on the CLI
- * from the start, so call qdev_device_add_from_qdict() directly for
- * now.
- */
- dev = qdev_device_add_from_qdict(opt->opts, true, &error_fatal);
- object_unref(OBJECT(dev));
+ qmp_device_add(opt->opts, &ret_data, &error_fatal);
+ assert(ret_data == NULL); /* error_fatal aborts */
loc_pop(&opt->loc);
}
rom_reset_order_override();
diff --git a/tests/avocado/hotplug_blk.py b/tests/avocado/hotplug_blk.py
index d55ded1c1d..b36bca02ec 100644
--- a/tests/avocado/hotplug_blk.py
+++ b/tests/avocado/hotplug_blk.py
@@ -33,7 +33,7 @@ class HotPlug(LinuxTest):
'drive': 'disk',
'id': 'virtio-disk0',
'bus': 'pci.1',
- 'addr': 1
+ 'addr': '1',
}
self.assert_no_vda()
diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py
deleted file mode 100644
index 241ef180af..0000000000
--- a/tests/avocado/machine_aspeed.py
+++ /dev/null
@@ -1,202 +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 ...')
-
- 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):
- """
- :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);
-
- 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/avocado/tuxrun_baselines.py b/tests/avocado/tuxrun_baselines.py
deleted file mode 100644
index 38064840da..0000000000
--- 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 <alex.bennee@linaro.org>
-#
-# 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 758145d1e5..d6d2c0196c 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -11,9 +11,11 @@ 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,
+ 'aarch64_tuxrun' : 240,
'aarch64_virt' : 720,
'acpi_bits' : 420,
'arm_aspeed' : 600,
@@ -47,11 +49,13 @@ tests_generic_bsduser = [
]
tests_aarch64_system_thorough = [
+ 'aarch64_aspeed',
'aarch64_raspi3',
'aarch64_raspi4',
'aarch64_sbsaref',
'aarch64_sbsaref_alpine',
'aarch64_sbsaref_freebsd',
+ 'aarch64_tuxrun',
'aarch64_virt',
'multiprocess',
]
diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py
index cbabb1ceed..11c8334a7c 100644
--- a/tests/functional/qemu_test/cmd.py
+++ b/tests/functional/qemu_test/cmd.py
@@ -78,13 +78,77 @@ 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
+ assert success_message or send_string
+
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())
@@ -92,25 +156,15 @@ 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
- try:
- msg = console.readline().decode().strip()
- except UnicodeDecodeError:
- msg = None
- if not msg:
- continue
- console_logger.debug(msg)
- if success_message is None or 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,
@@ -135,6 +189,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)
@@ -149,6 +204,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):
@@ -177,6 +233,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):
diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py
index 411978b5ef..90ae59eb54 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)
@@ -55,7 +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():
@@ -71,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())
@@ -108,7 +120,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)
@@ -159,10 +171,19 @@ 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,
+ name=name,
+ 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)
+
+ 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
diff --git a/tests/functional/qemu_test/tuxruntest.py b/tests/functional/qemu_test/tuxruntest.py
index f05aa96ad7..ab3b27da43 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)
@@ -125,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
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed.py
new file mode 100644
index 0000000000..59916efd71
--- /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()
diff --git a/tests/functional/test_aarch64_tuxrun.py b/tests/functional/test_aarch64_tuxrun.py
new file mode 100755
index 0000000000..75adc8acb8
--- /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 <alex.bennee@linaro.org>
+#
+# 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/buildroot/20241119/arm64/Image',
+ 'b74743c5e89e1cea0f73368d24ae0ae85c5204ff84be3b5e9610417417d2f235')
+ ASSET_ARM64_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64/rootfs.ext4.zst',
+ 'a1acaaae2068df4648d04ff75f532aaa8c5edcd6b936122b6f0db4848a07b465')
+
+ 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/buildroot/20241119/arm64be/Image',
+ 'fd6af4f16689d17a2c24fe0053cc212edcdf77abdcaf301800b8d38fa9f6e109')
+ ASSET_ARM64BE_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64be/rootfs.ext4.zst',
+ 'f5e9371b62701aab8dead52592ca7488c8a9e255c9be8d7635c7f30f477c2c21')
+
+ 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()
diff --git a/tests/functional/test_acpi_bits.py b/tests/functional/test_acpi_bits.py
index ee40647d5b..3498b96787 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')
@@ -196,11 +195,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))
@@ -224,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))
@@ -246,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')
@@ -289,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)
@@ -320,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()
@@ -333,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()
@@ -359,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)
@@ -399,8 +382,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 ...")
diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py
index 5fb1adf464..d88170ac24 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');
@@ -252,6 +250,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(
diff --git a/tests/functional/test_arm_bpim2u.py b/tests/functional/test_arm_bpim2u.py
index 2f9fa145e3..35ea58d46c 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 d2ed5fcc82..6d57223a03 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()
diff --git a/tests/functional/test_m68k_nextcube.py b/tests/functional/test_m68k_nextcube.py
index 89385a134a..0124622c40 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',
diff --git a/tests/functional/test_mips64el_malta.py b/tests/functional/test_mips64el_malta.py
index 6c6355b131..6d1195d362 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()
@@ -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,
diff --git a/tests/functional/test_virtio_gpu.py b/tests/functional/test_virtio_gpu.py
index 441cbdcf2d..d5027487ac 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
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index ea48af4a7b..19817c7353 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -1614,10 +1614,13 @@ class ReproducibleStreamWrapper:
self.stream.write(arg)
class ReproducibleTestRunner(unittest.TextTestRunner):
- def __init__(self, stream: Optional[TextIO] = None,
- resultclass: Type[unittest.TestResult] =
- ReproducibleTestResult,
- **kwargs: Any) -> None:
+ def __init__(
+ self,
+ stream: Optional[TextIO] = None,
+ resultclass: Type[unittest.TextTestResult] =
+ ReproducibleTestResult,
+ **kwargs: Any
+ ) -> None:
rstream = ReproducibleStreamWrapper(stream or sys.stdout)
super().__init__(stream=rstream, # type: ignore
descriptions=True,
diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc
index 05b75ee59b..c5f4833e45 100644
--- a/tests/qemu-iotests/pylintrc
+++ b/tests/qemu-iotests/pylintrc
@@ -13,6 +13,7 @@ disable=invalid-name,
no-else-return,
too-few-public-methods,
too-many-arguments,
+ too-many-positional-arguments,
too-many-branches,
too-many-lines,
too-many-locals,