summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.include21
-rw-r--r--tests/acceptance/README.rst10
-rw-r--r--tests/avocado/README.rst10
-rw-r--r--tests/avocado/avocado_qemu/__init__.py (renamed from tests/acceptance/avocado_qemu/__init__.py)163
-rw-r--r--tests/avocado/boot_linux.py (renamed from tests/acceptance/boot_linux.py)0
-rw-r--r--tests/avocado/boot_linux_console.py (renamed from tests/acceptance/boot_linux_console.py)11
-rw-r--r--tests/avocado/boot_xen.py (renamed from tests/acceptance/boot_xen.py)0
-rw-r--r--tests/avocado/cpu_queries.py (renamed from tests/acceptance/cpu_queries.py)4
-rw-r--r--tests/avocado/empty_cpu_model.py (renamed from tests/acceptance/empty_cpu_model.py)4
-rw-r--r--tests/avocado/hotplug_cpu.py (renamed from tests/acceptance/hotplug_cpu.py)0
-rw-r--r--tests/avocado/info_usernet.py (renamed from tests/acceptance/info_usernet.py)4
-rw-r--r--tests/avocado/intel_iommu.py (renamed from tests/acceptance/intel_iommu.py)0
-rw-r--r--tests/avocado/linux_initrd.py (renamed from tests/acceptance/linux_initrd.py)6
-rw-r--r--tests/avocado/linux_ssh_mips_malta.py (renamed from tests/acceptance/linux_ssh_mips_malta.py)5
-rw-r--r--tests/avocado/load_bflt.py54
-rw-r--r--tests/avocado/machine_arm_canona1100.py (renamed from tests/acceptance/machine_arm_canona1100.py)4
-rw-r--r--tests/avocado/machine_arm_integratorcp.py (renamed from tests/acceptance/machine_arm_integratorcp.py)4
-rw-r--r--tests/avocado/machine_arm_n8x0.py (renamed from tests/acceptance/machine_arm_n8x0.py)4
-rw-r--r--tests/avocado/machine_avr6.py (renamed from tests/acceptance/machine_avr6.py)6
-rw-r--r--tests/avocado/machine_m68k_nextcube.py (renamed from tests/acceptance/machine_m68k_nextcube.py)4
-rw-r--r--tests/avocado/machine_microblaze.py (renamed from tests/acceptance/machine_microblaze.py)4
-rw-r--r--tests/avocado/machine_mips_fuloong2e.py (renamed from tests/acceptance/machine_mips_fuloong2e.py)4
-rw-r--r--tests/avocado/machine_mips_loongson3v.py (renamed from tests/acceptance/machine_mips_loongson3v.py)4
-rw-r--r--tests/avocado/machine_mips_malta.py (renamed from tests/acceptance/machine_mips_malta.py)4
-rw-r--r--tests/avocado/machine_rx_gdbsim.py (renamed from tests/acceptance/machine_rx_gdbsim.py)4
-rw-r--r--tests/avocado/machine_s390_ccw_virtio.py (renamed from tests/acceptance/machine_s390_ccw_virtio.py)4
-rw-r--r--tests/avocado/machine_sparc64_sun4u.py (renamed from tests/acceptance/machine_sparc64_sun4u.py)0
-rw-r--r--tests/avocado/machine_sparc_leon3.py (renamed from tests/acceptance/machine_sparc_leon3.py)4
-rw-r--r--tests/avocado/migration.py (renamed from tests/acceptance/migration.py)4
-rw-r--r--tests/avocado/multiprocess.py (renamed from tests/acceptance/multiprocess.py)4
-rw-r--r--tests/avocado/pc_cpu_hotplug_props.py (renamed from tests/acceptance/pc_cpu_hotplug_props.py)4
-rw-r--r--tests/avocado/ppc_405.py (renamed from tests/acceptance/ppc_405.py)4
-rw-r--r--tests/avocado/ppc_bamboo.py (renamed from tests/acceptance/ppc_bamboo.py)4
-rw-r--r--tests/avocado/ppc_mpc8544ds.py (renamed from tests/acceptance/ppc_mpc8544ds.py)4
-rw-r--r--tests/avocado/ppc_prep_40p.py (renamed from tests/acceptance/ppc_prep_40p.py)4
-rw-r--r--tests/avocado/ppc_pseries.py (renamed from tests/acceptance/ppc_pseries.py)4
-rw-r--r--tests/avocado/ppc_virtex_ml507.py (renamed from tests/acceptance/ppc_virtex_ml507.py)4
-rw-r--r--tests/avocado/replay_kernel.py (renamed from tests/acceptance/replay_kernel.py)0
-rw-r--r--tests/avocado/replay_linux.py (renamed from tests/acceptance/replay_linux.py)0
-rw-r--r--tests/avocado/reverse_debugging.py (renamed from tests/acceptance/reverse_debugging.py)0
-rw-r--r--tests/avocado/smmu.py (renamed from tests/acceptance/smmu.py)0
-rw-r--r--tests/avocado/tcg_plugins.py (renamed from tests/acceptance/tcg_plugins.py)0
-rw-r--r--tests/avocado/tesseract_utils.py (renamed from tests/acceptance/tesseract_utils.py)0
-rw-r--r--tests/avocado/version.py (renamed from tests/acceptance/version.py)4
-rw-r--r--tests/avocado/virtio-gpu.py (renamed from tests/acceptance/virtio-gpu.py)4
-rw-r--r--tests/avocado/virtio_check_params.py (renamed from tests/acceptance/virtio_check_params.py)4
-rw-r--r--tests/avocado/virtio_version.py (renamed from tests/acceptance/virtio_version.py)4
-rw-r--r--tests/avocado/virtiofs_submounts.py (renamed from tests/acceptance/virtiofs_submounts.py)59
-rw-r--r--tests/avocado/virtiofs_submounts.py.data/cleanup.sh (renamed from tests/acceptance/virtiofs_submounts.py.data/cleanup.sh)0
-rw-r--r--tests/avocado/virtiofs_submounts.py.data/guest-cleanup.sh (renamed from tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh)0
-rw-r--r--tests/avocado/virtiofs_submounts.py.data/guest.sh (renamed from tests/acceptance/virtiofs_submounts.py.data/guest.sh)0
-rw-r--r--tests/avocado/virtiofs_submounts.py.data/host.sh (renamed from tests/acceptance/virtiofs_submounts.py.data/host.sh)0
-rw-r--r--tests/avocado/vnc.py (renamed from tests/acceptance/vnc.py)4
-rw-r--r--tests/avocado/x86_cpu_model_versions.py (renamed from tests/acceptance/x86_cpu_model_versions.py)4
54 files changed, 271 insertions, 190 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 8434a33fe6..4c564cf789 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -16,7 +16,7 @@ ifneq ($(filter $(all-check-targets), check-softfloat),)
 	@echo " $(MAKE) check-tcg            Run TCG tests"
 	@echo " $(MAKE) check-softfloat      Run FPU emulation tests"
 endif
-	@echo " $(MAKE) check-acceptance     Run acceptance (functional) tests for currently configured targets"
+	@echo " $(MAKE) check-avocado        Run avocado (integration) tests for currently configured targets"
 	@echo
 	@echo " $(MAKE) check-report.tap     Generates an aggregated TAP test report"
 	@echo " $(MAKE) check-venv           Creates a Python venv for tests"
@@ -24,7 +24,7 @@ endif
 	@echo
 	@echo "The following are useful for CI builds"
 	@echo " $(MAKE) check-build          Build most test binaris"
-	@echo " $(MAKE) get-vm-images        Downloads all images used by acceptance tests, according to configured targets (~350 MB each, 1.5 GB max)"
+	@echo " $(MAKE) get-vm-images        Downloads all images used by avocado tests, according to configured targets (~350 MB each, 1.5 GB max)"
 	@echo
 	@echo
 	@echo "The variable SPEED can be set to control the gtester speed setting."
@@ -83,13 +83,13 @@ clean-tcg: $(CLEAN_TCG_TARGET_RULES)
 
 # Python venv for running tests
 
-.PHONY: check-venv check-acceptance
+.PHONY: check-venv check-avocado check-acceptance check-acceptance-deprecated-warning
 
 TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
 TESTS_VENV_REQ=$(SRC_PATH)/tests/requirements.txt
 TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
 ifndef AVOCADO_TESTS
-	AVOCADO_TESTS=tests/acceptance
+	AVOCADO_TESTS=tests/avocado
 endif
 # Controls the output generated by Avocado when running tests.
 # Any number of command separated loggers are accepted.  For more
@@ -127,12 +127,12 @@ get-vm-image-fedora-31-%: check-venv
 	$(call quiet-command, \
              $(TESTS_VENV_DIR)/bin/python -m avocado vmimage get \
              --distro=fedora --distro-version=31 --arch=$*, \
-	"AVOCADO", "Downloading acceptance tests VM image for $*")
+	"AVOCADO", "Downloading avocado tests VM image for $*")
 
 # download all vm images, according to defined targets
 get-vm-images: check-venv $(patsubst %,get-vm-image-fedora-31-%, $(FEDORA_31_DOWNLOAD))
 
-check-acceptance: check-venv $(TESTS_RESULTS_DIR) get-vm-images
+check-avocado: check-venv $(TESTS_RESULTS_DIR) get-vm-images
 	$(call quiet-command, \
             $(TESTS_VENV_DIR)/bin/python -m avocado \
             --show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) \
@@ -140,7 +140,14 @@ check-acceptance: check-venv $(TESTS_RESULTS_DIR) get-vm-images
 			--filter-by-tags-include-empty-key) \
             $(AVOCADO_CMDLINE_TAGS) \
             $(if $(GITLAB_CI),,--failfast) $(AVOCADO_TESTS), \
-            "AVOCADO", "tests/acceptance")
+            "AVOCADO", "tests/avocado")
+
+check-acceptance-deprecated-warning:
+	@echo
+	@echo "Note '$(MAKE) check-acceptance' is deprecated, use '$(MAKE) check-avocado' instead."
+	@echo
+
+check-acceptance: check-acceptance-deprecated-warning | check-avocado
 
 # Consolidated targets
 
diff --git a/tests/acceptance/README.rst b/tests/acceptance/README.rst
deleted file mode 100644
index 89260faed6..0000000000
--- a/tests/acceptance/README.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-============================================
-Acceptance tests using the Avocado Framework
-============================================
-
-This directory contains functional tests, also known as acceptance
-level tests.  They're usually higher level, and may interact with
-external resources and with various guest operating systems.
-
-For more information, please refer to ``docs/devel/testing.rst``,
-section "Acceptance tests using the Avocado Framework".
diff --git a/tests/avocado/README.rst b/tests/avocado/README.rst
new file mode 100644
index 0000000000..94488371bb
--- /dev/null
+++ b/tests/avocado/README.rst
@@ -0,0 +1,10 @@
+=============================================
+Integration tests using the Avocado Framework
+=============================================
+
+This directory contains integration tests. They're usually higher
+level, and may interact with external resources and with various
+guest operating systems.
+
+For more information, please refer to ``docs/devel/testing.rst``,
+section "Integration tests using the Avocado Framework".
diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/avocado/avocado_qemu/__init__.py
index 1841053e2c..75063c0c30 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/avocado/avocado_qemu/__init__.py
@@ -11,13 +11,14 @@
 import logging
 import os
 import shutil
+import subprocess
 import sys
 import tempfile
 import time
 import uuid
 
 import avocado
-from avocado.utils import cloudinit, datadrainer, network, ssh, vmimage
+from avocado.utils import cloudinit, datadrainer, network, process, ssh, vmimage
 from avocado.utils.path import find_command
 
 #: The QEMU build root directory.  It may also be the source directory
@@ -27,7 +28,7 @@ from avocado.utils.path import find_command
 BUILD_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
 
 if os.path.islink(os.path.dirname(os.path.dirname(__file__))):
-    # The link to the acceptance tests dir in the source code directory
+    # The link to the avocado tests dir in the source code directory
     lnk = os.path.dirname(os.path.dirname(__file__))
     #: The QEMU root source directory
     SOURCE_DIR = os.path.dirname(os.path.dirname(os.readlink(lnk)))
@@ -41,11 +42,67 @@ from qemu.utils import (get_info_usernet_hostfwd_port, kvm_available,
                         tcg_available)
 
 
+def has_cmd(name, args=None):
+    """
+    This function is for use in a @avocado.skipUnless decorator, e.g.:
+
+        @skipUnless(*has_cmd('sudo -n', ('sudo', '-n', 'true')))
+        def test_something_that_needs_sudo(self):
+            ...
+    """
+
+    if args is None:
+        args = ('which', name)
+
+    try:
+        _, stderr, exitcode = run_cmd(args)
+    except Exception as e:
+        exitcode = -1
+        stderr = str(e)
+
+    if exitcode != 0:
+        cmd_line = ' '.join(args)
+        err = f'{name} required, but "{cmd_line}" failed: {stderr.strip()}'
+        return (False, err)
+    else:
+        return (True, '')
+
+def has_cmds(*cmds):
+    """
+    This function is for use in a @avocado.skipUnless decorator and
+    allows checking for the availability of multiple commands, e.g.:
+
+        @skipUnless(*has_cmds(('cmd1', ('cmd1', '--some-parameter')),
+                              'cmd2', 'cmd3'))
+        def test_something_that_needs_cmd1_and_cmd2(self):
+            ...
+    """
+
+    for cmd in cmds:
+        if isinstance(cmd, str):
+            cmd = (cmd,)
+
+        ok, errstr = has_cmd(*cmd)
+        if not ok:
+            return (False, errstr)
+
+    return (True, '')
+
+def run_cmd(args):
+    subp = subprocess.Popen(args,
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE,
+                            universal_newlines=True)
+    stdout, stderr = subp.communicate()
+    ret = subp.returncode
+
+    return (stdout, stderr, ret)
+
 def is_readable_executable_file(path):
     return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
 
 
-def pick_default_qemu_bin(arch=None):
+def pick_default_qemu_bin(bin_prefix='qemu-system-', arch=None):
     """
     Picks the path of a QEMU binary, starting either in the current working
     directory or in the source tree root directory.
@@ -64,7 +121,7 @@ def pick_default_qemu_bin(arch=None):
     # qemu binary path does not match arch for powerpc, handle it
     if 'ppc64le' in arch:
         arch = 'ppc64'
-    qemu_bin_relative_path = "./qemu-system-%s" % arch
+    qemu_bin_relative_path = os.path.join(".", bin_prefix + arch)
     if is_readable_executable_file(qemu_bin_relative_path):
         return qemu_bin_relative_path
 
@@ -119,7 +176,7 @@ def interrupt_interactive_console_until_pattern(test, success_message,
 
     :param test: an Avocado test containing a VM that will have its console
                  read and probed for a success or failure message
-    :type test: :class:`avocado_qemu.Test`
+    :type test: :class:`avocado_qemu.QemuSystemTest`
     :param success_message: if this message appears, test succeeds
     :param failure_message: if this message appears, test fails
     :param interrupt_string: a string to send to the console before trying
@@ -135,7 +192,7 @@ def wait_for_console_pattern(test, success_message, failure_message=None,
 
     :param test: an Avocado test containing a VM that will have its console
                  read and probed for a success or failure message
-    :type test: :class:`avocado_qemu.Test`
+    :type test: :class:`avocado_qemu.QemuSystemTest`
     :param success_message: if this message appears, test succeeds
     :param failure_message: if this message appears, test fails
     """
@@ -147,7 +204,7 @@ def exec_command(test, command):
     the content.
 
     :param test: an Avocado test containing a VM.
-    :type test: :class:`avocado_qemu.Test`
+    :type test: :class:`avocado_qemu.QemuSystemTest`
     :param command: the command to send
     :type command: str
     """
@@ -162,14 +219,14 @@ def exec_command_and_wait_for_pattern(test, command,
 
     :param test: an Avocado test containing a VM that will have its console
                  read and probed for a success or failure message
-    :type test: :class:`avocado_qemu.Test`
+    :type test: :class:`avocado_qemu.QemuSystemTest`
     :param command: the command to send
     :param success_message: if this message appears, test succeeds
     :param failure_message: if this message appears, test fails
     """
     _console_interaction(test, success_message, failure_message, command + '\r')
 
-class Test(avocado.Test):
+class QemuBaseTest(avocado.Test):
     def _get_unique_tag_val(self, tag_name):
         """
         Gets a tag value, if unique for a key
@@ -179,6 +236,43 @@ class Test(avocado.Test):
             return vals.pop()
         return None
 
+    def setUp(self, bin_prefix):
+        self.arch = self.params.get('arch',
+                                    default=self._get_unique_tag_val('arch'))
+
+        self.cpu = self.params.get('cpu',
+                                   default=self._get_unique_tag_val('cpu'))
+
+        default_qemu_bin = pick_default_qemu_bin(bin_prefix, arch=self.arch)
+        self.qemu_bin = self.params.get('qemu_bin',
+                                        default=default_qemu_bin)
+        if self.qemu_bin is None:
+            self.cancel("No QEMU binary defined or found in the build tree")
+
+    def fetch_asset(self, name,
+                    asset_hash=None, algorithm=None,
+                    locations=None, expire=None,
+                    find_only=False, cancel_on_missing=True):
+        return super().fetch_asset(name,
+                        asset_hash=asset_hash,
+                        algorithm=algorithm,
+                        locations=locations,
+                        expire=expire,
+                        find_only=find_only,
+                        cancel_on_missing=cancel_on_missing)
+
+
+class QemuSystemTest(QemuBaseTest):
+    """Facilitates system emulation tests."""
+
+    def setUp(self):
+        self._vms = {}
+
+        super().setUp('qemu-system-')
+
+        self.machine = self.params.get('machine',
+                                       default=self._get_unique_tag_val('machine'))
+
     def require_accelerator(self, accelerator):
         """
         Requires an accelerator to be available for the test to continue
@@ -201,24 +295,6 @@ class Test(avocado.Test):
             self.cancel("%s accelerator does not seem to be "
                         "available" % accelerator)
 
-    def setUp(self):
-        self._vms = {}
-
-        self.arch = self.params.get('arch',
-                                    default=self._get_unique_tag_val('arch'))
-
-        self.cpu = self.params.get('cpu',
-                                   default=self._get_unique_tag_val('cpu'))
-
-        self.machine = self.params.get('machine',
-                                       default=self._get_unique_tag_val('machine'))
-
-        default_qemu_bin = pick_default_qemu_bin(arch=self.arch)
-        self.qemu_bin = self.params.get('qemu_bin',
-                                        default=default_qemu_bin)
-        if self.qemu_bin is None:
-            self.cancel("No QEMU binary defined or found in the build tree")
-
     def _new_vm(self, name, *args):
         self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
         vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir,
@@ -272,17 +348,22 @@ class Test(avocado.Test):
         self._sd = None
         super().tearDown()
 
-    def fetch_asset(self, name,
-                    asset_hash=None, algorithm=None,
-                    locations=None, expire=None,
-                    find_only=False, cancel_on_missing=True):
-        return super().fetch_asset(name,
-                        asset_hash=asset_hash,
-                        algorithm=algorithm,
-                        locations=locations,
-                        expire=expire,
-                        find_only=find_only,
-                        cancel_on_missing=cancel_on_missing)
+
+class QemuUserTest(QemuBaseTest):
+    """Facilitates user-mode emulation tests."""
+
+    def setUp(self):
+        self._ldpath = []
+        super().setUp('qemu-')
+
+    def add_ldpath(self, ldpath):
+        self._ldpath.append(os.path.abspath(ldpath))
+
+    def run(self, bin_path, args=[]):
+        qemu_args = " ".join(["-L %s" % ldpath for ldpath in self._ldpath])
+        bin_args = " ".join(args)
+        return process.run("%s %s %s %s" % (self.qemu_bin, qemu_args,
+                                            bin_path, bin_args))
 
 
 class LinuxSSHMixIn:
@@ -424,11 +505,11 @@ class LinuxDistro:
         return self._info.get('kernel_params', None)
 
 
-class LinuxTest(LinuxSSHMixIn, Test):
+class LinuxTest(LinuxSSHMixIn, QemuSystemTest):
     """Facilitates having a cloud-image Linux based available.
 
-    For tests that indend to interact with guests, this is a better choice
-    to start with than the more vanilla `Test` class.
+    For tests that indent to interact with guests, this is a better choice
+    to start with than the more vanilla `QemuSystemTest` class.
     """
 
     timeout = 900
diff --git a/tests/acceptance/boot_linux.py b/tests/avocado/boot_linux.py
index ab19146d1e..ab19146d1e 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/avocado/boot_linux.py
diff --git a/tests/acceptance/boot_linux_console.py b/tests/avocado/boot_linux_console.py
index 06fc967f6c..9c618d4809 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/avocado/boot_linux_console.py
@@ -15,20 +15,13 @@ import shutil
 
 from avocado import skip
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 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 wait_for_console_pattern
 from avocado.utils import process
 from avocado.utils import archive
-from avocado.utils.path import find_command, CmdNotFoundError
-
-P7ZIP_AVAILABLE = True
-try:
-    find_command('7z')
-except CmdNotFoundError:
-    P7ZIP_AVAILABLE = False
 
 """
 Round up to next power of 2
@@ -46,7 +39,7 @@ def image_pow2ceil_expand(path):
             with open(path, 'ab+') as fd:
                 fd.truncate(size_aligned)
 
-class LinuxKernelTest(Test):
+class LinuxKernelTest(QemuSystemTest):
     KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
 
     def wait_for_console_pattern(self, success_message, vm=None):
diff --git a/tests/acceptance/boot_xen.py b/tests/avocado/boot_xen.py
index fc2faeedb5..fc2faeedb5 100644
--- a/tests/acceptance/boot_xen.py
+++ b/tests/avocado/boot_xen.py
diff --git a/tests/acceptance/cpu_queries.py b/tests/avocado/cpu_queries.py
index cc9e380cc7..cf69f69b11 100644
--- a/tests/acceptance/cpu_queries.py
+++ b/tests/avocado/cpu_queries.py
@@ -8,9 +8,9 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later.  See the COPYING file in the top-level directory.
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
-class QueryCPUModelExpansion(Test):
+class QueryCPUModelExpansion(QemuSystemTest):
     """
     Run query-cpu-model-expansion for each CPU model, and validate results
     """
diff --git a/tests/acceptance/empty_cpu_model.py b/tests/avocado/empty_cpu_model.py
index a1e59e45e4..22f504418d 100644
--- a/tests/acceptance/empty_cpu_model.py
+++ b/tests/avocado/empty_cpu_model.py
@@ -7,9 +7,9 @@
 #
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later.  See the COPYING file in the top-level directory.
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
-class EmptyCPUModel(Test):
+class EmptyCPUModel(QemuSystemTest):
     def test(self):
         self.vm.add_args('-S', '-display', 'none', '-machine', 'none', '-cpu', '')
         self.vm.set_qmp_monitor(enabled=False)
diff --git a/tests/acceptance/hotplug_cpu.py b/tests/avocado/hotplug_cpu.py
index 6374bf1b54..6374bf1b54 100644
--- a/tests/acceptance/hotplug_cpu.py
+++ b/tests/avocado/hotplug_cpu.py
diff --git a/tests/acceptance/info_usernet.py b/tests/avocado/info_usernet.py
index 9c1fd903a0..dc01f74150 100644
--- a/tests/acceptance/info_usernet.py
+++ b/tests/avocado/info_usernet.py
@@ -8,12 +8,12 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later.  See the COPYING file in the top-level directory.
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
 from qemu.utils import get_info_usernet_hostfwd_port
 
 
-class InfoUsernet(Test):
+class InfoUsernet(QemuSystemTest):
 
     def test_hostfwd(self):
         self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22')
diff --git a/tests/acceptance/intel_iommu.py b/tests/avocado/intel_iommu.py
index 474d62f6bf..474d62f6bf 100644
--- a/tests/acceptance/intel_iommu.py
+++ b/tests/avocado/intel_iommu.py
diff --git a/tests/acceptance/linux_initrd.py b/tests/avocado/linux_initrd.py
index a249e2f14a..ba02e5a563 100644
--- a/tests/acceptance/linux_initrd.py
+++ b/tests/avocado/linux_initrd.py
@@ -1,4 +1,4 @@
-# Linux initrd acceptance test.
+# Linux initrd integration test.
 #
 # Copyright (c) 2018 Red Hat, Inc.
 #
@@ -12,11 +12,11 @@ import os
 import logging
 import tempfile
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado import skipIf
 
 
-class LinuxInitrd(Test):
+class LinuxInitrd(QemuSystemTest):
     """
     Checks QEMU evaluates correctly the initrd file passed as -initrd option.
 
diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/avocado/linux_ssh_mips_malta.py
index 4de1947418..c0f0be5ade 100644
--- a/tests/acceptance/linux_ssh_mips_malta.py
+++ b/tests/avocado/linux_ssh_mips_malta.py
@@ -12,7 +12,8 @@ import logging
 import time
 
 from avocado import skipUnless
-from avocado_qemu import Test, LinuxSSHMixIn
+from avocado_qemu import LinuxSSHMixIn
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import process
 from avocado.utils import archive
@@ -21,7 +22,7 @@ from avocado.utils import ssh
 
 @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
 @skipUnless(ssh.SSH_CLIENT_BINARY, 'No SSH client available')
-class LinuxSSH(Test, LinuxSSHMixIn):
+class LinuxSSH(QemuSystemTest, LinuxSSHMixIn):
 
     timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
 
diff --git a/tests/avocado/load_bflt.py b/tests/avocado/load_bflt.py
new file mode 100644
index 0000000000..bb50cec1ee
--- /dev/null
+++ b/tests/avocado/load_bflt.py
@@ -0,0 +1,54 @@
+# Test the bFLT loader format
+#
+# Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+import bz2
+import subprocess
+
+from avocado import skipUnless
+from avocado_qemu import QemuUserTest
+from avocado_qemu import has_cmd
+
+
+class LoadBFLT(QemuUserTest):
+
+    def extract_cpio(self, cpio_path):
+        """
+        Extracts a cpio archive into the test workdir
+
+        :param cpio_path: path to the cpio archive
+        """
+        cwd = os.getcwd()
+        os.chdir(self.workdir)
+        with bz2.open(cpio_path, 'rb') as archive_cpio:
+            subprocess.run(['cpio', '-i'], input=archive_cpio.read(),
+                           stderr=subprocess.DEVNULL)
+        os.chdir(cwd)
+
+    @skipUnless(*has_cmd('cpio'))
+    @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
+    def test_stm32(self):
+        """
+        :avocado: tags=arch:arm
+        :avocado: tags=linux_user
+        :avocado: tags=quick
+        """
+        # See https://elinux.org/STM32#User_Space
+        rootfs_url = ('https://elinux.org/images/5/51/'
+                      'Stm32_mini_rootfs.cpio.bz2')
+        rootfs_hash = '9f065e6ba40cce7411ba757f924f30fcc57951e6'
+        rootfs_path_bz2 = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
+        busybox_path = os.path.join(self.workdir, "/bin/busybox")
+
+        self.extract_cpio(rootfs_path_bz2)
+
+        res = self.run(busybox_path)
+        ver = 'BusyBox v1.24.0.git (2015-02-03 22:17:13 CET) multi-call binary.'
+        self.assertIn(ver, res.stdout_text)
+
+        res = self.run(busybox_path, ['uname', '-a'])
+        unm = 'armv7l GNU/Linux'
+        self.assertIn(unm, res.stdout_text)
diff --git a/tests/acceptance/machine_arm_canona1100.py b/tests/avocado/machine_arm_canona1100.py
index 0e5c43dbcf..182a0b0513 100644
--- a/tests/acceptance/machine_arm_canona1100.py
+++ b/tests/avocado/machine_arm_canona1100.py
@@ -8,11 +8,11 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later.  See the COPYING file in the top-level directory.
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import archive
 
-class CanonA1100Machine(Test):
+class CanonA1100Machine(QemuSystemTest):
     """Boots the barebox firmware and checks that the console is operational"""
 
     timeout = 90
diff --git a/tests/acceptance/machine_arm_integratorcp.py b/tests/avocado/machine_arm_integratorcp.py
index 49c8ebff78..1ffe1073ef 100644
--- a/tests/acceptance/machine_arm_integratorcp.py
+++ b/tests/avocado/machine_arm_integratorcp.py
@@ -12,7 +12,7 @@ import os
 import logging
 
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
 
@@ -29,7 +29,7 @@ except ImportError:
     CV2_AVAILABLE = False
 
 
-class IntegratorMachine(Test):
+class IntegratorMachine(QemuSystemTest):
 
     timeout = 90
 
diff --git a/tests/acceptance/machine_arm_n8x0.py b/tests/avocado/machine_arm_n8x0.py
index e5741f2d8d..12e9a6803b 100644
--- a/tests/acceptance/machine_arm_n8x0.py
+++ b/tests/avocado/machine_arm_n8x0.py
@@ -11,10 +11,10 @@
 import os
 
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
-class N8x0Machine(Test):
+class N8x0Machine(QemuSystemTest):
     """Boots the Linux kernel and checks that the console is operational"""
 
     timeout = 90
diff --git a/tests/acceptance/machine_avr6.py b/tests/avocado/machine_avr6.py
index 6baf4e9c7f..5485db79c6 100644
--- a/tests/acceptance/machine_avr6.py
+++ b/tests/avocado/machine_avr6.py
@@ -1,5 +1,5 @@
 #
-# QEMU AVR acceptance tests
+# QEMU AVR integration tests
 #
 # Copyright (c) 2019-2020 Michael Rolnik <mrolnik@gmail.com>
 #
@@ -19,9 +19,9 @@
 
 import time
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
-class AVR6Machine(Test):
+class AVR6Machine(QemuSystemTest):
     timeout = 5
 
     def test_freertos(self):
diff --git a/tests/acceptance/machine_m68k_nextcube.py b/tests/avocado/machine_m68k_nextcube.py
index 09e2745cc5..6790e7d9cd 100644
--- a/tests/acceptance/machine_m68k_nextcube.py
+++ b/tests/avocado/machine_m68k_nextcube.py
@@ -8,7 +8,7 @@
 import os
 import time
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado import skipUnless
 
 from tesseract_utils import tesseract_available, tesseract_ocr
@@ -20,7 +20,7 @@ except ImportError:
     PIL_AVAILABLE = False
 
 
-class NextCubeMachine(Test):
+class NextCubeMachine(QemuSystemTest):
     """
     :avocado: tags=arch:m68k
     :avocado: tags=machine:next-cube
diff --git a/tests/acceptance/machine_microblaze.py b/tests/avocado/machine_microblaze.py
index 7f6d18495d..4928920f96 100644
--- a/tests/acceptance/machine_microblaze.py
+++ b/tests/avocado/machine_microblaze.py
@@ -5,11 +5,11 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later. See the COPYING file in the top-level directory.
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import archive
 
-class MicroblazeMachine(Test):
+class MicroblazeMachine(QemuSystemTest):
 
     timeout = 90
 
diff --git a/tests/acceptance/machine_mips_fuloong2e.py b/tests/avocado/machine_mips_fuloong2e.py
index 0ac285e2af..89291f47b2 100644
--- a/tests/acceptance/machine_mips_fuloong2e.py
+++ b/tests/avocado/machine_mips_fuloong2e.py
@@ -10,10 +10,10 @@
 import os
 
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
-class MipsFuloong2e(Test):
+class MipsFuloong2e(QemuSystemTest):
 
     timeout = 60
 
diff --git a/tests/acceptance/machine_mips_loongson3v.py b/tests/avocado/machine_mips_loongson3v.py
index 85b131a40f..5194cf18c9 100644
--- a/tests/acceptance/machine_mips_loongson3v.py
+++ b/tests/avocado/machine_mips_loongson3v.py
@@ -11,10 +11,10 @@ import os
 import time
 
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
-class MipsLoongson3v(Test):
+class MipsLoongson3v(QemuSystemTest):
     timeout = 60
 
     @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
diff --git a/tests/acceptance/machine_mips_malta.py b/tests/avocado/machine_mips_malta.py
index b67d8cb141..f1895d59f3 100644
--- a/tests/acceptance/machine_mips_malta.py
+++ b/tests/avocado/machine_mips_malta.py
@@ -12,7 +12,7 @@ import gzip
 import logging
 
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import archive
 from avocado import skipIf
@@ -33,7 +33,7 @@ except ImportError:
 
 @skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed')
 @skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed')
-class MaltaMachineFramebuffer(Test):
+class MaltaMachineFramebuffer(QemuSystemTest):
 
     timeout = 30
 
diff --git a/tests/acceptance/machine_rx_gdbsim.py b/tests/avocado/machine_rx_gdbsim.py
index 32b737b6d8..6cd8704b01 100644
--- a/tests/acceptance/machine_rx_gdbsim.py
+++ b/tests/avocado/machine_rx_gdbsim.py
@@ -11,13 +11,13 @@
 import os
 
 from avocado import skipIf
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import exec_command_and_wait_for_pattern
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import archive
 
 
-class RxGdbSimMachine(Test):
+class RxGdbSimMachine(QemuSystemTest):
 
     timeout = 30
     KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
diff --git a/tests/acceptance/machine_s390_ccw_virtio.py b/tests/avocado/machine_s390_ccw_virtio.py
index 4028c99afc..bd03d7160b 100644
--- a/tests/acceptance/machine_s390_ccw_virtio.py
+++ b/tests/avocado/machine_s390_ccw_virtio.py
@@ -13,12 +13,12 @@ import os
 import tempfile
 
 from avocado import skipIf
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import exec_command_and_wait_for_pattern
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import archive
 
-class S390CCWVirtioMachine(Test):
+class S390CCWVirtioMachine(QemuSystemTest):
     KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
 
     timeout = 120
diff --git a/tests/acceptance/machine_sparc64_sun4u.py b/tests/avocado/machine_sparc64_sun4u.py
index 458165500e..458165500e 100644
--- a/tests/acceptance/machine_sparc64_sun4u.py
+++ b/tests/avocado/machine_sparc64_sun4u.py
diff --git a/tests/acceptance/machine_sparc_leon3.py b/tests/avocado/machine_sparc_leon3.py
index 2405cd7a0d..e61b223185 100644
--- a/tests/acceptance/machine_sparc_leon3.py
+++ b/tests/avocado/machine_sparc_leon3.py
@@ -5,12 +5,12 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later. See the COPYING file in the top-level directory.
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado import skip
 
 
-class Leon3Machine(Test):
+class Leon3Machine(QemuSystemTest):
 
     timeout = 60
 
diff --git a/tests/acceptance/migration.py b/tests/avocado/migration.py
index 792639cb69..584d6ef53f 100644
--- a/tests/acceptance/migration.py
+++ b/tests/avocado/migration.py
@@ -11,7 +11,7 @@
 
 
 import tempfile
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado import skipUnless
 
 from avocado.utils import network
@@ -19,7 +19,7 @@ from avocado.utils import wait
 from avocado.utils.path import find_command
 
 
-class Migration(Test):
+class Migration(QemuSystemTest):
     """
     :avocado: tags=migration
     """
diff --git a/tests/acceptance/multiprocess.py b/tests/avocado/multiprocess.py
index 96627f022a..80a3b8f442 100644
--- a/tests/acceptance/multiprocess.py
+++ b/tests/avocado/multiprocess.py
@@ -7,12 +7,12 @@
 import os
 import socket
 
-from avocado_qemu import Test
+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
 
-class Multiprocess(Test):
+class Multiprocess(QemuSystemTest):
     """
     :avocado: tags=multiprocess
     """
diff --git a/tests/acceptance/pc_cpu_hotplug_props.py b/tests/avocado/pc_cpu_hotplug_props.py
index 2e86d5017a..52b878188e 100644
--- a/tests/acceptance/pc_cpu_hotplug_props.py
+++ b/tests/avocado/pc_cpu_hotplug_props.py
@@ -20,9 +20,9 @@
 # License along with this library; if not, see <http://www.gnu.org/licenses/>.
 #
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
-class OmittedCPUProps(Test):
+class OmittedCPUProps(QemuSystemTest):
     """
     :avocado: tags=arch:x86_64
     :avocado: tags=cpu:qemu64
diff --git a/tests/acceptance/ppc_405.py b/tests/avocado/ppc_405.py
index c534d5d32f..a47f89b934 100644
--- a/tests/acceptance/ppc_405.py
+++ b/tests/avocado/ppc_405.py
@@ -6,11 +6,11 @@
 # later.  See the COPYING file in the top-level directory.
 
 from avocado.utils import archive
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado_qemu import exec_command_and_wait_for_pattern
 
-class Ppc405Machine(Test):
+class Ppc405Machine(QemuSystemTest):
 
     timeout = 90
 
diff --git a/tests/acceptance/ppc_bamboo.py b/tests/avocado/ppc_bamboo.py
index dd33bf66f3..40629e3478 100644
--- a/tests/acceptance/ppc_bamboo.py
+++ b/tests/avocado/ppc_bamboo.py
@@ -6,11 +6,11 @@
 # later.  See the COPYING file in the top-level directory.
 
 from avocado.utils import archive
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado_qemu import exec_command_and_wait_for_pattern
 
-class BambooMachine(Test):
+class BambooMachine(QemuSystemTest):
 
     timeout = 90
 
diff --git a/tests/acceptance/ppc_mpc8544ds.py b/tests/avocado/ppc_mpc8544ds.py
index ce840600c1..886f967b15 100644
--- a/tests/acceptance/ppc_mpc8544ds.py
+++ b/tests/avocado/ppc_mpc8544ds.py
@@ -6,10 +6,10 @@
 # later.  See the COPYING file in the top-level directory.
 
 from avocado.utils import archive
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
-class Mpc8544dsMachine(Test):
+class Mpc8544dsMachine(QemuSystemTest):
 
     timeout = 90
     KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
diff --git a/tests/acceptance/ppc_prep_40p.py b/tests/avocado/ppc_prep_40p.py
index 5e61e686bd..4bd956584d 100644
--- a/tests/acceptance/ppc_prep_40p.py
+++ b/tests/avocado/ppc_prep_40p.py
@@ -8,11 +8,11 @@
 import os
 
 from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
 
-class IbmPrep40pMachine(Test):
+class IbmPrep40pMachine(QemuSystemTest):
 
     timeout = 60
 
diff --git a/tests/acceptance/ppc_pseries.py b/tests/avocado/ppc_pseries.py
index f14a884ee1..d8b04dc3ea 100644
--- a/tests/acceptance/ppc_pseries.py
+++ b/tests/avocado/ppc_pseries.py
@@ -6,10 +6,10 @@
 # later.  See the COPYING file in the top-level directory.
 
 from avocado.utils import archive
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
-class pseriesMachine(Test):
+class pseriesMachine(QemuSystemTest):
 
     timeout = 90
     KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
diff --git a/tests/acceptance/ppc_virtex_ml507.py b/tests/avocado/ppc_virtex_ml507.py
index 27f7bf2d49..a6912ee579 100644
--- a/tests/acceptance/ppc_virtex_ml507.py
+++ b/tests/avocado/ppc_virtex_ml507.py
@@ -6,10 +6,10 @@
 # later.  See the COPYING file in the top-level directory.
 
 from avocado.utils import archive
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 
-class VirtexMl507Machine(Test):
+class VirtexMl507Machine(QemuSystemTest):
 
     timeout = 90
     KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
diff --git a/tests/acceptance/replay_kernel.py b/tests/avocado/replay_kernel.py
index c68a953730..c68a953730 100644
--- a/tests/acceptance/replay_kernel.py
+++ b/tests/avocado/replay_kernel.py
diff --git a/tests/acceptance/replay_linux.py b/tests/avocado/replay_linux.py
index 15953f9e49..15953f9e49 100644
--- a/tests/acceptance/replay_linux.py
+++ b/tests/avocado/replay_linux.py
diff --git a/tests/acceptance/reverse_debugging.py b/tests/avocado/reverse_debugging.py
index d2921e70c3..d2921e70c3 100644
--- a/tests/acceptance/reverse_debugging.py
+++ b/tests/avocado/reverse_debugging.py
diff --git a/tests/acceptance/smmu.py b/tests/avocado/smmu.py
index b3c4de6bf4..b3c4de6bf4 100644
--- a/tests/acceptance/smmu.py
+++ b/tests/avocado/smmu.py
diff --git a/tests/acceptance/tcg_plugins.py b/tests/avocado/tcg_plugins.py
index 9ca1515c3b..9ca1515c3b 100644
--- a/tests/acceptance/tcg_plugins.py
+++ b/tests/avocado/tcg_plugins.py
diff --git a/tests/acceptance/tesseract_utils.py b/tests/avocado/tesseract_utils.py
index 72cd9ab798..72cd9ab798 100644
--- a/tests/acceptance/tesseract_utils.py
+++ b/tests/avocado/tesseract_utils.py
diff --git a/tests/acceptance/version.py b/tests/avocado/version.py
index 79b923d4fc..ded7f039c1 100644
--- a/tests/acceptance/version.py
+++ b/tests/avocado/version.py
@@ -9,10 +9,10 @@
 # later.  See the COPYING file in the top-level directory.
 
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
 
-class Version(Test):
+class Version(QemuSystemTest):
     """
     :avocado: tags=quick
     """
diff --git a/tests/acceptance/virtio-gpu.py b/tests/avocado/virtio-gpu.py
index 4acc1e6d5f..2a249a3a2c 100644
--- a/tests/acceptance/virtio-gpu.py
+++ b/tests/avocado/virtio-gpu.py
@@ -4,8 +4,8 @@
 # later.  See the COPYING file in the top-level directory.
 
 
-from avocado_qemu import Test
 from avocado_qemu import BUILD_DIR
+from avocado_qemu import QemuSystemTest
 from avocado_qemu import wait_for_console_pattern
 from avocado_qemu import exec_command_and_wait_for_pattern
 from avocado_qemu import is_readable_executable_file
@@ -27,7 +27,7 @@ def pick_default_vug_bin():
         return bld_dir_path
 
 
-class VirtioGPUx86(Test):
+class VirtioGPUx86(QemuSystemTest):
     """
     :avocado: tags=virtio-gpu
     :avocado: tags=arch:x86_64
diff --git a/tests/acceptance/virtio_check_params.py b/tests/avocado/virtio_check_params.py
index 87e6c839d1..e869690473 100644
--- a/tests/acceptance/virtio_check_params.py
+++ b/tests/avocado/virtio_check_params.py
@@ -24,7 +24,7 @@ import logging
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
 from qemu.machine import QEMUMachine
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 from avocado import skip
 
 #list of machine types and virtqueue properties to test
@@ -41,7 +41,7 @@ VM_DEV_PARAMS = {'virtio-scsi-pci': ['-device', 'virtio-scsi-pci,id=scsi0'],
                                     'driver=null-co,id=drive0,if=none']}
 
 
-class VirtioMaxSegSettingsCheck(Test):
+class VirtioMaxSegSettingsCheck(QemuSystemTest):
     @staticmethod
     def make_pattern(props):
         pattern_items = ['{0} = \w+'.format(prop) for prop in props]
diff --git a/tests/acceptance/virtio_version.py b/tests/avocado/virtio_version.py
index 33593c29dd..208910bb84 100644
--- a/tests/acceptance/virtio_version.py
+++ b/tests/avocado/virtio_version.py
@@ -13,7 +13,7 @@ import os
 
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
 from qemu.machine import QEMUMachine
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
 # Virtio Device IDs:
 VIRTIO_NET = 1
@@ -55,7 +55,7 @@ def get_pci_interfaces(vm, devtype):
     interfaces = ('pci-express-device', 'conventional-pci-device')
     return [i for i in interfaces if devtype_implements(vm, devtype, i)]
 
-class VirtioVersionCheck(Test):
+class VirtioVersionCheck(QemuSystemTest):
     """
     Check if virtio-version-specific device types result in the
     same device tree created by `disable-modern` and
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/avocado/virtiofs_submounts.py
index 21ad7d792e..e6dc32ffd4 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/avocado/virtiofs_submounts.py
@@ -6,67 +6,12 @@ import time
 
 from avocado import skipUnless
 from avocado_qemu import LinuxTest, BUILD_DIR
+from avocado_qemu import has_cmds
+from avocado_qemu import run_cmd
 from avocado_qemu import wait_for_console_pattern
 from avocado.utils import ssh
 
 
-def run_cmd(args):
-    subp = subprocess.Popen(args,
-                            stdout=subprocess.PIPE,
-                            stderr=subprocess.PIPE,
-                            universal_newlines=True)
-    stdout, stderr = subp.communicate()
-    ret = subp.returncode
-
-    return (stdout, stderr, ret)
-
-def has_cmd(name, args=None):
-    """
-    This function is for use in a @avocado.skipUnless decorator, e.g.:
-
-        @skipUnless(*has_cmd('sudo -n', ('sudo', '-n', 'true')))
-        def test_something_that_needs_sudo(self):
-            ...
-    """
-
-    if args is None:
-        args = ('which', name)
-
-    try:
-        _, stderr, exitcode = run_cmd(args)
-    except Exception as e:
-        exitcode = -1
-        stderr = str(e)
-
-    if exitcode != 0:
-        cmd_line = ' '.join(args)
-        err = f'{name} required, but "{cmd_line}" failed: {stderr.strip()}'
-        return (False, err)
-    else:
-        return (True, '')
-
-def has_cmds(*cmds):
-    """
-    This function is for use in a @avocado.skipUnless decorator and
-    allows checking for the availability of multiple commands, e.g.:
-
-        @skipUnless(*has_cmds(('cmd1', ('cmd1', '--some-parameter')),
-                              'cmd2', 'cmd3'))
-        def test_something_that_needs_cmd1_and_cmd2(self):
-            ...
-    """
-
-    for cmd in cmds:
-        if isinstance(cmd, str):
-            cmd = (cmd,)
-
-        ok, errstr = has_cmd(*cmd)
-        if not ok:
-            return (False, errstr)
-
-    return (True, '')
-
-
 class VirtiofsSubmountsTest(LinuxTest):
     """
     :avocado: tags=arch:x86_64
diff --git a/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh b/tests/avocado/virtiofs_submounts.py.data/cleanup.sh
index 2a6579a0fe..2a6579a0fe 100644
--- a/tests/acceptance/virtiofs_submounts.py.data/cleanup.sh
+++ b/tests/avocado/virtiofs_submounts.py.data/cleanup.sh
diff --git a/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh b/tests/avocado/virtiofs_submounts.py.data/guest-cleanup.sh
index 729cb2d1a5..729cb2d1a5 100644
--- a/tests/acceptance/virtiofs_submounts.py.data/guest-cleanup.sh
+++ b/tests/avocado/virtiofs_submounts.py.data/guest-cleanup.sh
diff --git a/tests/acceptance/virtiofs_submounts.py.data/guest.sh b/tests/avocado/virtiofs_submounts.py.data/guest.sh
index 59ba40fde1..59ba40fde1 100644
--- a/tests/acceptance/virtiofs_submounts.py.data/guest.sh
+++ b/tests/avocado/virtiofs_submounts.py.data/guest.sh
diff --git a/tests/acceptance/virtiofs_submounts.py.data/host.sh b/tests/avocado/virtiofs_submounts.py.data/host.sh
index d8a9afebdb..d8a9afebdb 100644
--- a/tests/acceptance/virtiofs_submounts.py.data/host.sh
+++ b/tests/avocado/virtiofs_submounts.py.data/host.sh
diff --git a/tests/acceptance/vnc.py b/tests/avocado/vnc.py
index f301fbb4f5..096432988f 100644
--- a/tests/acceptance/vnc.py
+++ b/tests/avocado/vnc.py
@@ -8,10 +8,10 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later.  See the COPYING file in the top-level directory.
 
-from avocado_qemu import Test
+from avocado_qemu import QemuSystemTest
 
 
-class Vnc(Test):
+class Vnc(QemuSystemTest):
     """
     :avocado: tags=vnc,quick
     """
diff --git a/tests/acceptance/x86_cpu_model_versions.py b/tests/avocado/x86_cpu_model_versions.py
index 0e9feda62d..a6edf74c1c 100644
--- a/tests/acceptance/x86_cpu_model_versions.py
+++ b/tests/avocado/x86_cpu_model_versions.py
@@ -24,7 +24,7 @@
 import avocado_qemu
 import re
 
-class X86CPUModelAliases(avocado_qemu.Test):
+class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
     """
     Validation of PC CPU model versions and CPU model aliases
 
@@ -239,7 +239,7 @@ class X86CPUModelAliases(avocado_qemu.Test):
         self.validate_aliases(cpus)
 
 
-class CascadelakeArchCapabilities(avocado_qemu.Test):
+class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
     """
     Validation of Cascadelake arch-capabilities