aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-06-02 11:42:22 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-06-02 11:42:23 +0100
commit49ba51adec7928fe7cf3cb43acbf0b953e5c637e (patch)
treeab441e4ca6df5ec769b329cecaee7a7d6adb7900 /tests
parentdd2db39d78431ab5a0b78777afaab3d61e94533e (diff)
parent6b9c277797879ce41ed20deb6737f4156cc279b3 (diff)
downloadqemu-49ba51adec7928fe7cf3cb43acbf0b953e5c637e.zip
qemu-49ba51adec7928fe7cf3cb43acbf0b953e5c637e.tar.gz
qemu-49ba51adec7928fe7cf3cb43acbf0b953e5c637e.tar.bz2
Merge remote-tracking branch 'remotes/jsnow-gitlab/tags/python-pull-request' into staging
Pull request V2: - Squashed in fixup for 'Python: add utility function for retrieving port redirection' - Rebased on today's upstream CI here: https://gitlab.com/jsnow/qemu/-/pipelines/313202814 # gpg: Signature made Wed 02 Jun 2021 00:29:55 BST # gpg: using RSA key F9B7ABDBBCACDF95BE76CBD07DEF8106AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" [full] # Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB # Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E * remotes/jsnow-gitlab/tags/python-pull-request: (44 commits) gitlab: add python linters to CI python: add tox support python: add .gitignore python: add Makefile for some common tasks python: add avocado-framework and tests python: add devel package requirements to setuptools python/qemu: add qemu package itself to pipenv python/qemu: add isort to pipenv python: move .isort.cfg into setup.cfg python: add mypy to pipenv python: move mypy.ini into setup.cfg python: Add flake8 to pipenv python: add excluded dirs to flake8 config python: move flake8 config to setup.cfg python: add pylint to pipenv python: move pylintrc into setup.cfg python: add pylint import exceptions python: Add pipenv support python: add MANIFEST.in python: add directory structure README.rst files ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/acceptance/avocado_qemu/__init__.py69
-rw-r--r--tests/acceptance/boot_linux.py18
-rw-r--r--tests/acceptance/hotplug_cpu.py37
-rw-r--r--tests/acceptance/info_usernet.py29
-rw-r--r--tests/acceptance/linux_ssh_mips_malta.py42
-rw-r--r--tests/acceptance/virtio-gpu.py2
-rw-r--r--tests/acceptance/virtiofs_submounts.py71
-rw-r--r--tests/docker/dockerfiles/python.docker18
-rwxr-xr-xtests/qemu-iotests/2971
-rwxr-xr-xtests/qemu-iotests/3004
-rw-r--r--tests/qemu-iotests/iotests.py4
-rw-r--r--tests/requirements.txt2
-rw-r--r--tests/vm/aarch64vm.py2
-rw-r--r--tests/vm/basevm.py12
14 files changed, 178 insertions, 133 deletions
diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index 83b1741..93c4b98 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -20,6 +20,7 @@ import avocado
from avocado.utils import cloudinit
from avocado.utils import datadrainer
from avocado.utils import network
+from avocado.utils import ssh
from avocado.utils import vmimage
from avocado.utils.path import find_command
@@ -40,9 +41,12 @@ else:
sys.path.append(os.path.join(SOURCE_DIR, 'python'))
-from qemu.accel import kvm_available
-from qemu.accel import tcg_available
from qemu.machine import QEMUMachine
+from qemu.utils import (
+ get_info_usernet_hostfwd_port,
+ kvm_available,
+ tcg_available,
+)
def is_readable_executable_file(path):
return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
@@ -253,7 +257,50 @@ class Test(avocado.Test):
cancel_on_missing=cancel_on_missing)
-class LinuxTest(Test):
+class LinuxSSHMixIn:
+ """Contains utility methods for interacting with a guest via SSH."""
+
+ def ssh_connect(self, username, credential, credential_is_key=True):
+ self.ssh_logger = logging.getLogger('ssh')
+ res = self.vm.command('human-monitor-command',
+ command_line='info usernet')
+ port = get_info_usernet_hostfwd_port(res)
+ self.assertIsNotNone(port)
+ self.assertGreater(port, 0)
+ self.log.debug('sshd listening on port: %d', port)
+ if credential_is_key:
+ self.ssh_session = ssh.Session('127.0.0.1', port=port,
+ user=username, key=credential)
+ else:
+ self.ssh_session = ssh.Session('127.0.0.1', port=port,
+ user=username, password=credential)
+ for i in range(10):
+ try:
+ self.ssh_session.connect()
+ return
+ except:
+ time.sleep(4)
+ pass
+ self.fail('ssh connection timeout')
+
+ def ssh_command(self, command):
+ self.ssh_logger.info(command)
+ result = self.ssh_session.cmd(command)
+ stdout_lines = [line.rstrip() for line
+ in result.stdout_text.splitlines()]
+ for line in stdout_lines:
+ self.ssh_logger.info(line)
+ stderr_lines = [line.rstrip() for line
+ in result.stderr_text.splitlines()]
+ for line in stderr_lines:
+ self.ssh_logger.warning(line)
+
+ self.assertEqual(result.exit_status, 0,
+ f'Guest command failed: {command}')
+ return stdout_lines, stderr_lines
+
+
+class LinuxTest(Test, LinuxSSHMixIn):
"""Facilitates having a cloud-image Linux based available.
For tests that indend to interact with guests, this is a better choice
@@ -262,11 +309,16 @@ class LinuxTest(Test):
timeout = 900
chksum = None
+ username = 'root'
+ password = 'password'
- def setUp(self, ssh_pubkey=None):
+ def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'):
super(LinuxTest, self).setUp()
self.vm.add_args('-smp', '2')
self.vm.add_args('-m', '1024')
+ # The following network device allows for SSH connections
+ self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+ '-device', '%s,netdev=vnet' % network_device_type)
self.set_up_boot()
if ssh_pubkey is None:
ssh_pubkey, self.ssh_key = self.set_up_existing_ssh_keys()
@@ -322,8 +374,8 @@ class LinuxTest(Test):
with open(ssh_pubkey) as pubkey:
pubkey_content = pubkey.read()
cloudinit.iso(cloudinit_iso, self.name,
- username='root',
- password='password',
+ username=self.username,
+ password=self.password,
# QEMU's hard coded usermode router address
phone_home_host='10.0.2.2',
phone_home_port=self.phone_home_port,
@@ -340,7 +392,7 @@ class LinuxTest(Test):
cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
- def launch_and_wait(self):
+ def launch_and_wait(self, set_up_ssh_connection=True):
self.vm.set_console()
self.vm.launch()
console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
@@ -348,3 +400,6 @@ class LinuxTest(Test):
console_drainer.start()
self.log.info('VM launched, waiting for boot confirmation from guest')
cloudinit.wait_for_phone_home(('0.0.0.0', self.phone_home_port), self.name)
+ if set_up_ssh_connection:
+ self.log.info('Setting up the SSH connection')
+ self.ssh_connect(self.username, self.ssh_key)
diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
index 0d17803..314370f 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/acceptance/boot_linux.py
@@ -29,7 +29,7 @@ class BootLinuxX8664(LinuxTest):
"""
self.require_accelerator("tcg")
self.vm.add_args("-accel", "tcg")
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
def test_pc_i440fx_kvm(self):
"""
@@ -38,7 +38,7 @@ class BootLinuxX8664(LinuxTest):
"""
self.require_accelerator("kvm")
self.vm.add_args("-accel", "kvm")
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
def test_pc_q35_tcg(self):
"""
@@ -47,7 +47,7 @@ class BootLinuxX8664(LinuxTest):
"""
self.require_accelerator("tcg")
self.vm.add_args("-accel", "tcg")
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
def test_pc_q35_kvm(self):
"""
@@ -56,7 +56,7 @@ class BootLinuxX8664(LinuxTest):
"""
self.require_accelerator("kvm")
self.vm.add_args("-accel", "kvm")
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
class BootLinuxAarch64(LinuxTest):
@@ -85,7 +85,7 @@ class BootLinuxAarch64(LinuxTest):
self.vm.add_args("-cpu", "max")
self.vm.add_args("-machine", "virt,gic-version=2")
self.add_common_args()
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
def test_virt_kvm_gicv2(self):
"""
@@ -98,7 +98,7 @@ class BootLinuxAarch64(LinuxTest):
self.vm.add_args("-cpu", "host")
self.vm.add_args("-machine", "virt,gic-version=2")
self.add_common_args()
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
def test_virt_kvm_gicv3(self):
"""
@@ -111,7 +111,7 @@ class BootLinuxAarch64(LinuxTest):
self.vm.add_args("-cpu", "host")
self.vm.add_args("-machine", "virt,gic-version=3")
self.add_common_args()
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
class BootLinuxPPC64(LinuxTest):
@@ -128,7 +128,7 @@ class BootLinuxPPC64(LinuxTest):
"""
self.require_accelerator("tcg")
self.vm.add_args("-accel", "tcg")
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
class BootLinuxS390X(LinuxTest):
@@ -146,4 +146,4 @@ class BootLinuxS390X(LinuxTest):
"""
self.require_accelerator("tcg")
self.vm.add_args("-accel", "tcg")
- self.launch_and_wait()
+ self.launch_and_wait(set_up_ssh_connection=False)
diff --git a/tests/acceptance/hotplug_cpu.py b/tests/acceptance/hotplug_cpu.py
new file mode 100644
index 0000000..6374bf1
--- /dev/null
+++ b/tests/acceptance/hotplug_cpu.py
@@ -0,0 +1,37 @@
+# Functional test that hotplugs a CPU and checks it on a Linux guest
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+# Cleber Rosa <crosa@redhat.com>
+#
+# 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 LinuxTest
+
+
+class HotPlugCPU(LinuxTest):
+
+ def test(self):
+ """
+ :avocado: tags=arch:x86_64
+ :avocado: tags=machine:q35
+ :avocado: tags=accel:kvm
+ """
+ self.require_accelerator('kvm')
+ self.vm.add_args('-accel', 'kvm')
+ self.vm.add_args('-cpu', 'Haswell')
+ self.vm.add_args('-smp', '1,sockets=1,cores=2,threads=1,maxcpus=2')
+ self.launch_and_wait()
+
+ self.ssh_command('test -e /sys/devices/system/cpu/cpu0')
+ with self.assertRaises(AssertionError):
+ self.ssh_command('test -e /sys/devices/system/cpu/cpu1')
+
+ self.vm.command('device_add',
+ driver='Haswell-x86_64-cpu',
+ socket_id=0,
+ core_id=1,
+ thread_id=0)
+ self.ssh_command('test -e /sys/devices/system/cpu/cpu1')
diff --git a/tests/acceptance/info_usernet.py b/tests/acceptance/info_usernet.py
new file mode 100644
index 0000000..9c1fd90
--- /dev/null
+++ b/tests/acceptance/info_usernet.py
@@ -0,0 +1,29 @@
+# Test for the hmp command "info usernet"
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+# Cleber Rosa <crosa@redhat.com>
+#
+# 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 qemu.utils import get_info_usernet_hostfwd_port
+
+
+class InfoUsernet(Test):
+
+ def test_hostfwd(self):
+ self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22')
+ self.vm.launch()
+ res = self.vm.command('human-monitor-command',
+ command_line='info usernet')
+ port = get_info_usernet_hostfwd_port(res)
+ self.assertIsNotNone(port,
+ ('"info usernet" output content does not seem to '
+ 'contain the redirected port'))
+ self.assertGreater(port, 0,
+ ('Found a redirected port that is not greater than'
+ ' zero'))
diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py
index 6dbd02d..61c9079 100644
--- a/tests/acceptance/linux_ssh_mips_malta.py
+++ b/tests/acceptance/linux_ssh_mips_malta.py
@@ -12,14 +12,14 @@ import logging
import time
from avocado import skipUnless
-from avocado_qemu import Test
+from avocado_qemu import Test, LinuxSSHMixIn
from avocado_qemu import wait_for_console_pattern
from avocado.utils import process
from avocado.utils import archive
from avocado.utils import ssh
-class LinuxSSH(Test):
+class LinuxSSH(Test, LinuxSSHMixIn):
timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
@@ -70,45 +70,9 @@ class LinuxSSH(Test):
def setUp(self):
super(LinuxSSH, self).setUp()
- def get_portfwd(self):
- res = self.vm.command('human-monitor-command',
- command_line='info usernet')
- line = res.split('\r\n')[2]
- port = re.split(r'.*TCP.HOST_FORWARD.*127\.0\.0\.1 (\d+)\s+10\..*',
- line)[1]
- self.log.debug("sshd listening on port:" + port)
- return port
-
- def ssh_connect(self, username, password):
- self.ssh_logger = logging.getLogger('ssh')
- port = self.get_portfwd()
- self.ssh_session = ssh.Session(self.VM_IP, port=int(port),
- user=username, password=password)
- for i in range(10):
- try:
- self.ssh_session.connect()
- return
- except:
- time.sleep(4)
- pass
- self.fail("ssh connection timeout")
-
def ssh_disconnect_vm(self):
self.ssh_session.quit()
- def ssh_command(self, command, is_root=True):
- self.ssh_logger.info(command)
- result = self.ssh_session.cmd(command)
- stdout_lines = [line.rstrip() for line
- in result.stdout_text.splitlines()]
- for line in stdout_lines:
- self.ssh_logger.info(line)
- stderr_lines = [line.rstrip() for line
- in result.stderr_text.splitlines()]
- for line in stderr_lines:
- self.ssh_logger.warning(line)
- return stdout_lines, stderr_lines
-
def boot_debian_wheezy_image_and_ssh_login(self, endianess, kernel_path):
image_url, image_hash = self.get_image_info(endianess)
image_path = self.fetch_asset(image_url, asset_hash=image_hash)
@@ -129,7 +93,7 @@ class LinuxSSH(Test):
wait_for_console_pattern(self, console_pattern, 'Oops')
self.log.info('sshd ready')
- self.ssh_connect('root', 'root')
+ self.ssh_connect('root', 'root', False)
def shutdown_via_ssh(self):
self.ssh_command('poweroff')
diff --git a/tests/acceptance/virtio-gpu.py b/tests/acceptance/virtio-gpu.py
index ab18cdd..e797934 100644
--- a/tests/acceptance/virtio-gpu.py
+++ b/tests/acceptance/virtio-gpu.py
@@ -10,7 +10,7 @@ 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
-from qemu.accel import kvm_available
+from qemu.utils import kvm_available
import os
import socket
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index 46fa653..21ad7d7 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -70,56 +70,9 @@ def has_cmds(*cmds):
class VirtiofsSubmountsTest(LinuxTest):
"""
:avocado: tags=arch:x86_64
+ :avocado: tags=accel:kvm
"""
- def get_portfwd(self):
- port = None
-
- res = self.vm.command('human-monitor-command',
- command_line='info usernet')
- for line in res.split('\r\n'):
- match = \
- re.search(r'TCP.HOST_FORWARD.*127\.0\.0\.1\s+(\d+)\s+10\.',
- line)
- if match is not None:
- port = int(match[1])
- break
-
- self.assertIsNotNone(port)
- self.assertGreater(port, 0)
- self.log.debug('sshd listening on port: %d', port)
- return port
-
- def ssh_connect(self, username, keyfile):
- self.ssh_logger = logging.getLogger('ssh')
- port = self.get_portfwd()
- self.ssh_session = ssh.Session('127.0.0.1', port=port,
- user=username, key=keyfile)
- for i in range(10):
- try:
- self.ssh_session.connect()
- return
- except:
- time.sleep(4)
- pass
- self.fail('ssh connection timeout')
-
- def ssh_command(self, command):
- self.ssh_logger.info(command)
- result = self.ssh_session.cmd(command)
- stdout_lines = [line.rstrip() for line
- in result.stdout_text.splitlines()]
- for line in stdout_lines:
- self.ssh_logger.info(line)
- stderr_lines = [line.rstrip() for line
- in result.stderr_text.splitlines()]
- for line in stderr_lines:
- self.ssh_logger.warning(line)
-
- self.assertEqual(result.exit_status, 0,
- f'Guest command failed: {command}')
- return stdout_lines, stderr_lines
-
def run(self, args, ignore_error=False):
stdout, stderr, ret = run_cmd(args)
@@ -181,10 +134,6 @@ class VirtiofsSubmountsTest(LinuxTest):
'-numa',
'node,memdev=mem')
- def launch_vm(self):
- self.launch_and_wait()
- self.ssh_connect('root', self.ssh_key)
-
def set_up_nested_mounts(self):
scratch_dir = os.path.join(self.shared_dir, 'scratch')
try:
@@ -246,18 +195,14 @@ class VirtiofsSubmountsTest(LinuxTest):
self.run(('ssh-keygen', '-N', '', '-t', 'ed25519', '-f', self.ssh_key))
- pubkey = open(self.ssh_key + '.pub').read()
+ pubkey = self.ssh_key + '.pub'
super(VirtiofsSubmountsTest, self).setUp(pubkey)
- if len(vmlinuz) > 0:
+ if vmlinuz:
self.vm.add_args('-kernel', vmlinuz,
'-append', 'console=ttyS0 root=/dev/sda1')
- # Allow us to connect to SSH
- self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
- '-device', 'virtio-net,netdev=vnet')
-
self.require_accelerator("kvm")
self.vm.add_args('-accel', 'kvm')
@@ -277,7 +222,7 @@ class VirtiofsSubmountsTest(LinuxTest):
self.set_up_nested_mounts()
self.set_up_virtiofs()
- self.launch_vm()
+ self.launch_and_wait()
self.mount_in_guest()
self.check_in_guest()
@@ -287,14 +232,14 @@ class VirtiofsSubmountsTest(LinuxTest):
self.set_up_nested_mounts()
- self.launch_vm()
+ self.launch_and_wait()
self.mount_in_guest()
self.check_in_guest()
def test_post_launch_set_up(self):
self.set_up_shared_dir()
self.set_up_virtiofs()
- self.launch_vm()
+ self.launch_and_wait()
self.set_up_nested_mounts()
@@ -304,7 +249,7 @@ class VirtiofsSubmountsTest(LinuxTest):
def test_post_mount_set_up(self):
self.set_up_shared_dir()
self.set_up_virtiofs()
- self.launch_vm()
+ self.launch_and_wait()
self.mount_in_guest()
self.set_up_nested_mounts()
@@ -317,7 +262,7 @@ class VirtiofsSubmountsTest(LinuxTest):
self.set_up_nested_mounts()
self.set_up_virtiofs()
- self.launch_vm()
+ self.launch_and_wait()
self.mount_in_guest()
self.check_in_guest()
diff --git a/tests/docker/dockerfiles/python.docker b/tests/docker/dockerfiles/python.docker
new file mode 100644
index 0000000..56d8841
--- /dev/null
+++ b/tests/docker/dockerfiles/python.docker
@@ -0,0 +1,18 @@
+# Python library testing environment
+
+FROM fedora:latest
+MAINTAINER John Snow <jsnow@redhat.com>
+
+# Please keep this list sorted alphabetically
+ENV PACKAGES \
+ gcc \
+ make \
+ pipenv \
+ python3 \
+ python3-pip \
+ python3-tox \
+ python3-virtualenv \
+ python3.10
+
+RUN dnf install -y $PACKAGES
+RUN rpm -q $PACKAGES | sort > /packages.txt
diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
index a37910b..433b732 100755
--- a/tests/qemu-iotests/297
+++ b/tests/qemu-iotests/297
@@ -95,6 +95,7 @@ def run_linters():
'--warn-redundant-casts',
'--warn-unused-ignores',
'--no-implicit-reexport',
+ '--namespace-packages',
filename),
env=env,
check=False,
diff --git a/tests/qemu-iotests/300 b/tests/qemu-iotests/300
index b475a92..fe94de8 100755
--- a/tests/qemu-iotests/300
+++ b/tests/qemu-iotests/300
@@ -28,7 +28,7 @@ import iotests
# Import qemu after iotests.py has amended sys.path
# pylint: disable=wrong-import-order
-import qemu
+from qemu.machine import machine
BlockBitmapMapping = List[Dict[str, object]]
@@ -466,7 +466,7 @@ class TestBlockBitmapMappingErrors(TestDirtyBitmapMigration):
# the failed migration
try:
self.vm_b.shutdown()
- except qemu.machine.AbnormalShutdown:
+ except machine.AbnormalShutdown:
pass
def test_aliased_bitmap_name_too_long(self) -> None:
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 777fa2e..89663da 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -38,7 +38,7 @@ from contextlib import contextmanager
# pylint: disable=import-error, wrong-import-position
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu import qtest
+from qemu.machine import qtest
from qemu.qmp import QMPMessage
# Use this logger for logging messages directly from the iotests module
@@ -571,7 +571,7 @@ class VM(qtest.QEMUQtestMachine):
def __init__(self, path_suffix=''):
name = "qemu%s-%d" % (path_suffix, os.getpid())
super().__init__(qemu_prog, qemu_opts, name=name,
- test_dir=test_dir,
+ base_temp_dir=test_dir,
socket_scm_helper=socket_scm_helper,
sock_dir=sock_dir)
self._num_drives = 0
diff --git a/tests/requirements.txt b/tests/requirements.txt
index 91f3a34..a21b59b 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -1,5 +1,5 @@
# Add Python module requirements, one per line, to be installed
# in the tests/venv Python virtual environment. For more info,
# refer to: https://pip.pypa.io/en/stable/user_guide/#id1
-avocado-framework==85.0
+avocado-framework==88.1
pycdlib==1.11.0
diff --git a/tests/vm/aarch64vm.py b/tests/vm/aarch64vm.py
index d70ab84..b00cce0 100644
--- a/tests/vm/aarch64vm.py
+++ b/tests/vm/aarch64vm.py
@@ -14,7 +14,7 @@ import os
import sys
import subprocess
import basevm
-from qemu.accel import kvm_available
+from qemu.utils import kvm_available
# This is the config needed for current version of QEMU.
# This works for both kvm and tcg.
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index 00f1d5c..0f2e436 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -19,8 +19,8 @@ import logging
import time
import datetime
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu.accel import kvm_available
from qemu.machine import QEMUMachine
+from qemu.utils import get_info_usernet_hostfwd_port, kvm_available
import subprocess
import hashlib
import argparse
@@ -227,7 +227,7 @@ class BaseVM(object):
"-o", "UserKnownHostsFile=" + os.devnull,
"-o",
"ConnectTimeout={}".format(self._config["ssh_timeout"]),
- "-p", self.ssh_port, "-i", self._ssh_tmp_key_file]
+ "-p", str(self.ssh_port), "-i", self._ssh_tmp_key_file]
# If not in debug mode, set ssh to quiet mode to
# avoid printing the results of commands.
if not self.debug:
@@ -305,12 +305,8 @@ class BaseVM(object):
# Init console so we can start consuming the chars.
self.console_init()
usernet_info = guest.qmp("human-monitor-command",
- command_line="info usernet")
- self.ssh_port = None
- for l in usernet_info["return"].splitlines():
- fields = l.split()
- if "TCP[HOST_FORWARD]" in fields and "22" in fields:
- self.ssh_port = l.split()[3]
+ command_line="info usernet").get("return")
+ self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
if not self.ssh_port:
raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
usernet_info)