From 2ca6e26cea73fa1d270f73392e8b87f3e67e6a2b Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Thu, 11 Feb 2021 17:01:42 -0500 Subject: Python: expose QEMUMachine's temporary directory Each instance of qemu.machine.QEMUMachine currently has a "test directory", which may not have any relation to a "test", and it's really a temporary directory. Users instantiating the QEMUMachine class will be able to set the location of the directory that will *contain* the QEMUMachine unique temporary directory, so that parameter name has been changed from test_dir to base_temp_dir. A property has been added to allow users to access it without using private attributes, and with that, the directory is created on first use of the property. Signed-off-by: Cleber Rosa Message-Id: <20210211220146.2525771-3-crosa@redhat.com> Reviewed-by: Wainer dos Santos Moschetta Signed-off-by: Cleber Rosa Signed-off-by: John Snow --- tests/qemu-iotests/iotests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 777fa2e..9268190 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -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 -- cgit v1.1 From f084e148aa401f71c33da4268f73815e0dc2b262 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:34 -0400 Subject: tests/acceptance/virtiofs_submounts.py: add missing accel tag The tag is useful to select tests that depend/use a particular feature. Signed-off-by: Cleber Rosa Reviewed-by: Wainer dos Santos Moschetta Reviewed-by: Willian Rampazzo Reviewed-by: Eric Auger Message-Id: <20210412044644.55083-2-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/virtiofs_submounts.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index 46fa653..5b74ce2 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -70,6 +70,7 @@ def has_cmds(*cmds): class VirtiofsSubmountsTest(LinuxTest): """ :avocado: tags=arch:x86_64 + :avocado: tags=accel:kvm """ def get_portfwd(self): -- cgit v1.1 From c028691e65b9f45e7a8ff8ffbfb9a3818478b572 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:35 -0400 Subject: tests/acceptance/virtiofs_submounts.py: evaluate string not length If the vmlinuz variable is set to anything that evaluates to True, then the respective arguments should be set. If the variable contains an empty string, than it will evaluate to False, and the extra arguments will not be set. This keeps the same logic, but improves readability a bit. Signed-off-by: Cleber Rosa Reviewed-by: Beraldo Leal Reviewed-by: Eric Auger Reviewed-by: Willian Rampazzo Message-Id: <20210412044644.55083-3-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/virtiofs_submounts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index 5b74ce2..ca64b76 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -251,7 +251,7 @@ class VirtiofsSubmountsTest(LinuxTest): super(VirtiofsSubmountsTest, self).setUp(pubkey) - if len(vmlinuz) > 0: + if vmlinuz: self.vm.add_args('-kernel', vmlinuz, '-append', 'console=ttyS0 root=/dev/sda1') -- cgit v1.1 From 976218cbe792c37c1af7840ca5113e37b5a51d95 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:36 -0400 Subject: Python: add utility function for retrieving port redirection Slightly different versions for the same utility code are currently present on different locations. This unifies them all, giving preference to the version from virtiofs_submounts.py, because of the last tweaks added to it. While at it, this adds a "qemu.utils" module to host the utility function and a test. Signed-off-by: Cleber Rosa Reviewed-by: Wainer dos Santos Moschetta Reviewed-by: Eric Auger Reviewed-by: Willian Rampazzo Message-Id: <20210412044644.55083-4-crosa@redhat.com> Signed-off-by: John Snow [Squashed in below fix. --js] Signed-off-by: John Snow Signed-off-by: Cleber Rosa Message-Id: <20210601154546.130870-2-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/info_usernet.py | 29 +++++++++++++++++++++++++++++ tests/acceptance/linux_ssh_mips_malta.py | 16 +++++++--------- tests/acceptance/virtiofs_submounts.py | 21 +++++---------------- tests/vm/basevm.py | 11 ++++------- 4 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 tests/acceptance/info_usernet.py (limited to 'tests') 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 +# +# 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..052008f 100644 --- a/tests/acceptance/linux_ssh_mips_malta.py +++ b/tests/acceptance/linux_ssh_mips_malta.py @@ -18,6 +18,8 @@ from avocado.utils import process from avocado.utils import archive from avocado.utils import ssh +from qemu.utils import get_info_usernet_hostfwd_port + class LinuxSSH(Test): @@ -70,18 +72,14 @@ class LinuxSSH(Test): def setUp(self): super(LinuxSSH, self).setUp() - def get_portfwd(self): + def ssh_connect(self, username, password): + self.ssh_logger = logging.getLogger('ssh') 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] + port = get_info_usernet_hostfwd_port(res) + if not port: + self.cancel("Failed to retrieve SSH port") 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): diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index ca64b76..57a7047 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -9,6 +9,8 @@ from avocado_qemu import LinuxTest, BUILD_DIR from avocado_qemu import wait_for_console_pattern from avocado.utils import ssh +from qemu.utils import get_info_usernet_hostfwd_port + def run_cmd(args): subp = subprocess.Popen(args, @@ -73,27 +75,14 @@ class VirtiofsSubmountsTest(LinuxTest): :avocado: tags=accel:kvm """ - def get_portfwd(self): - port = None - + def ssh_connect(self, username, keyfile): + self.ssh_logger = logging.getLogger('ssh') 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 - + port = get_info_usernet_hostfwd_port(res) 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): diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 00f1d5c..995e642 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -21,6 +21,7 @@ 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 import subprocess import hashlib import argparse @@ -227,7 +228,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 +306,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) -- cgit v1.1 From 7edee7ad9408696b9b8d40b5842a07a0c4e9b7a2 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:37 -0400 Subject: Acceptance Tests: move useful ssh methods to base class Both the virtiofs submounts and the linux ssh mips malta tests contains useful methods related to ssh that deserve to be made available to other tests. Let's move them to an auxiliary, mix-in class that will be used on the base LinuxTest class. The method that helps with setting up an ssh connection will now support both key and password based authentication, defaulting to key based. Signed-off-by: Cleber Rosa Reviewed-by: Wainer dos Santos Moschetta Reviewed-by: Willian Rampazzo Reviewed-by: Eric Auger Signed-off-by: Cleber Rosa Message-Id: <20210412044644.55083-5-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/avocado_qemu/__init__.py | 48 ++++++++++++++++++++++++++++++- tests/acceptance/linux_ssh_mips_malta.py | 40 ++------------------------ tests/acceptance/virtiofs_submounts.py | 37 ------------------------ 3 files changed, 50 insertions(+), 75 deletions(-) (limited to 'tests') diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 83b1741..67f75f6 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 @@ -43,6 +44,8 @@ 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 + def is_readable_executable_file(path): return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK) @@ -253,7 +256,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 diff --git a/tests/acceptance/linux_ssh_mips_malta.py b/tests/acceptance/linux_ssh_mips_malta.py index 052008f..61c9079 100644 --- a/tests/acceptance/linux_ssh_mips_malta.py +++ b/tests/acceptance/linux_ssh_mips_malta.py @@ -12,16 +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 -from qemu.utils import get_info_usernet_hostfwd_port - -class LinuxSSH(Test): +class LinuxSSH(Test, LinuxSSHMixIn): timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg' @@ -72,41 +70,9 @@ class LinuxSSH(Test): def setUp(self): super(LinuxSSH, self).setUp() - def ssh_connect(self, username, password): - self.ssh_logger = logging.getLogger('ssh') - res = self.vm.command('human-monitor-command', - command_line='info usernet') - port = get_info_usernet_hostfwd_port(res) - if not port: - self.cancel("Failed to retrieve SSH port") - self.log.debug("sshd listening on port:" + port) - 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) @@ -127,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/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index 57a7047..bed8ce4 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -9,8 +9,6 @@ from avocado_qemu import LinuxTest, BUILD_DIR from avocado_qemu import wait_for_console_pattern from avocado.utils import ssh -from qemu.utils import get_info_usernet_hostfwd_port - def run_cmd(args): subp = subprocess.Popen(args, @@ -75,41 +73,6 @@ class VirtiofsSubmountsTest(LinuxTest): :avocado: tags=accel:kvm """ - def ssh_connect(self, username, keyfile): - 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) - 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) -- cgit v1.1 From 54914114aff5008b58d3cf01bf9e2274144875ca Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:38 -0400 Subject: Acceptance Tests: add port redirection for ssh by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For users of the LinuxTest class, let's set up the VM with the port redirection for SSH, instead of requiring each test to set the same arguments. It also sets the network device, by default, to virtio-net. Signed-off-by: Cleber Rosa Reviewed-by: Marc-André Lureau Reviewed-by: Eric Auger Reviewed-by: Willian Rampazzo Message-Id: <20210412044644.55083-6-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/avocado_qemu/__init__.py | 5 ++++- tests/acceptance/virtiofs_submounts.py | 4 ---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 67f75f6..0856880 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -309,10 +309,13 @@ class LinuxTest(Test, LinuxSSHMixIn): timeout = 900 chksum = None - 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() diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index bed8ce4..e10a935 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -207,10 +207,6 @@ class VirtiofsSubmountsTest(LinuxTest): 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') -- cgit v1.1 From d8c6a89968906af24ab27acd936013d3f937fc16 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:39 -0400 Subject: Acceptance Tests: make username/password configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes the username/password used for authentication configurable, because some guest operating systems may have restrictions on accounts to be used for logins, and it just makes it better documented. Signed-off-by: Cleber Rosa Reviewed-by: Marc-André Lureau Reviewed-by: Eric Auger Reviewed-by: Willian Rampazzo Message-Id: <20210412044644.55083-7-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/avocado_qemu/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 0856880..25f871f 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -308,6 +308,8 @@ class LinuxTest(Test, LinuxSSHMixIn): timeout = 900 chksum = None + username = 'root' + password = 'password' def setUp(self, ssh_pubkey=None, network_device_type='virtio-net'): super(LinuxTest, self).setUp() @@ -371,8 +373,8 @@ class LinuxTest(Test, LinuxSSHMixIn): 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, -- cgit v1.1 From c6620c443d076bc0c80357e41f8f8d7fcdade6df Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:40 -0400 Subject: Acceptance Tests: set up SSH connection by default after boot for LinuxTest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LinuxTest specifically targets users that need to interact with Linux guests. So, it makes sense to give a connection by default, and avoid requiring it as boiler-plate code. Signed-off-by: Cleber Rosa Reviewed-by: Marc-André Lureau Reviewed-by: Willian Rampazzo Message-Id: <20210412044644.55083-8-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/avocado_qemu/__init__.py | 5 ++++- tests/acceptance/boot_linux.py | 18 +++++++++--------- tests/acceptance/virtiofs_submounts.py | 1 - 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 25f871f..1062a85 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -391,7 +391,7 @@ class LinuxTest(Test, LinuxSSHMixIn): 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(), @@ -399,3 +399,6 @@ class LinuxTest(Test, LinuxSSHMixIn): 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/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index e10a935..e019d3b 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -136,7 +136,6 @@ class VirtiofsSubmountsTest(LinuxTest): 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') -- cgit v1.1 From a273387aec43d2f2cff19b232c8c3e569a669971 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:41 -0400 Subject: tests/acceptance/virtiofs_submounts.py: remove launch_vm() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LinuxTest class' launch_and_wait() method now behaves the same way as this test's custom launch_vm(), so let's just use the upper layer (common) method. Signed-off-by: Cleber Rosa Reviewed-by: Marc-André Lureau Reviewed-by: Eric Auger Reviewed-by: Willian Rampazzo Message-Id: <20210412044644.55083-9-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/virtiofs_submounts.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index e019d3b..d77ee35 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -134,9 +134,6 @@ class VirtiofsSubmountsTest(LinuxTest): '-numa', 'node,memdev=mem') - def launch_vm(self): - self.launch_and_wait() - def set_up_nested_mounts(self): scratch_dir = os.path.join(self.shared_dir, 'scratch') try: @@ -225,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() @@ -235,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() @@ -252,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() @@ -265,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() -- cgit v1.1 From fd1ce58d901bbe982db8c19ca6e1a63b30643150 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:43 -0400 Subject: Acceptance Tests: introduce CPU hotplug test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even though there are qtest based tests for hotplugging CPUs (from which this test took some inspiration from), this one adds checks from a Linux guest point of view. It should also serve as an example for tests that follow a similar pattern and need to interact with QEMU (via qmp) and with the Linux guest via SSH. Signed-off-by: Cleber Rosa Reviewed-by: Marc-André Lureau Reviewed-by: Willian Rampazzo Reviewed-by: Eric Auger Message-Id: <20210412044644.55083-11-crosa@redhat.com> Signed-off-by: John Snow --- tests/acceptance/hotplug_cpu.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/acceptance/hotplug_cpu.py (limited to 'tests') 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 +# +# 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') -- cgit v1.1 From d214740c994f51370112ceda33a9d5546ff21c84 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Mon, 12 Apr 2021 00:46:44 -0400 Subject: tests/acceptance/virtiofs_submounts.py: fix setup of SSH pubkey The public key argument should be a path to a file, and not the public key data. Reported-by: Wainer dos Santos Moschetta Signed-off-by: Cleber Rosa Message-Id: <20210412044644.55083-12-crosa@redhat.com> Reviewed-by: Willian Rampazzo Reviewed-by: Wainer dos Santos Moschetta Signed-off-by: John Snow --- tests/acceptance/virtiofs_submounts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py index d77ee35..21ad7d7 100644 --- a/tests/acceptance/virtiofs_submounts.py +++ b/tests/acceptance/virtiofs_submounts.py @@ -195,7 +195,7 @@ 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) -- cgit v1.1 From 41787552de447733debe0616b716a0aa138242c7 Mon Sep 17 00:00:00 2001 From: Willian Rampazzo Date: Thu, 20 May 2021 17:47:47 -0300 Subject: acceptance tests: bump Avocado version to 88.1 Besides some internal changes, new features, and bug fixes, on the QEMU side, this version fixes the following message seen when running the acceptance tests: "Error running method "pre_tests" of plugin "fetchasset": 'bytes' object has no attribute 'encode'". The release notes are available at https://avocado-framework.readthedocs.io/en/latest/releases/88_0.html. Signed-off-by: Willian Rampazzo Message-Id: <20210520204747.210764-2-willianr@redhat.com> Acked-by: Cleber Rosa Signed-off-by: John Snow --- tests/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') 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 -- cgit v1.1 From 7f0a143b0cd7b2b7c05b55b1b6814747ef612ce3 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 27 May 2021 17:16:52 -0400 Subject: iotests/297: add --namespace-packages to mypy arguments mypy is kind of weird about how it handles imports. For legacy reasons, it won't load PEP 420 namespaces, because of logic implemented prior to that becoming a standard. So, if you plan on using any, you have to pass --namespace-packages. Alright, fine. Signed-off-by: John Snow Reviewed-by: Cleber Rosa Message-id: 20210527211715.394144-9-jsnow@redhat.com Signed-off-by: John Snow --- tests/qemu-iotests/297 | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') 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, -- cgit v1.1 From beb6b57b3b1a1fe6ebc208d2edc12b504f69e29f Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 27 May 2021 17:16:53 -0400 Subject: python: create qemu packages move python/qemu/*.py to python/qemu/[machine, qmp, utils]/*.py and update import directives across the tree. This is done to create a PEP420 namespace package, in which we may create subpackages. To do this, the namespace directory ("qemu") should not have any modules in it. Those files will go into new 'machine', 'qmp' and 'utils' subpackages instead. Implement machine/__init__.py making the top-level classes and functions from its various modules available directly inside the package. Change qmp.py to qmp/__init__.py similarly, such that all of the useful QMP library classes are available directly from "qemu.qmp" instead of "qemu.qmp.qmp". Signed-off-by: John Snow Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Cleber Rosa Message-id: 20210527211715.394144-10-jsnow@redhat.com Signed-off-by: John Snow --- tests/acceptance/avocado_qemu/__init__.py | 9 +++++---- tests/acceptance/virtio-gpu.py | 2 +- tests/qemu-iotests/300 | 4 ++-- tests/qemu-iotests/iotests.py | 2 +- tests/vm/aarch64vm.py | 2 +- tests/vm/basevm.py | 3 +-- 6 files changed, 11 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py index 1062a85..93c4b98 100644 --- a/tests/acceptance/avocado_qemu/__init__.py +++ b/tests/acceptance/avocado_qemu/__init__.py @@ -41,11 +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 - +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) 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/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 9268190..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 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 995e642..0f2e436 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -19,9 +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 +from qemu.utils import get_info_usernet_hostfwd_port, kvm_available import subprocess import hashlib import argparse -- cgit v1.1 From 6b9c277797879ce41ed20deb6737f4156cc279b3 Mon Sep 17 00:00:00 2001 From: John Snow Date: Thu, 27 May 2021 17:17:15 -0400 Subject: gitlab: add python linters to CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a Python container that has just enough juice for us to run the Python code quality analysis tools. Base this container on Fedora, because Fedora has very convenient packaging for testing multiple Python versions. We need python3, pip (for pulling packages), pipenv and virtualenv for creating virtual environments, and tox for running tests. make is needed for running 'make check-tox' and 'make venv-check' targets. Python3.10 is needed explicitly because the tox package only pulls in 3.6-3.9, but we wish to test the forthcoming release of Python as well to help predict any problems. Lastly, we need gcc to compile PyPI packages that may not have a binary distribution available. Add two tests: check-python-pipenv uses pipenv to test a frozen, very explicit set of packages against our minimum supported python version, Python 3.6. This test is not allowed to fail. The dependencies this test uses do not change unless python/Pipfile.lock is changed. check-python-tox uses tox to install the latest versions of required python dependencies against a wide array of Python versions from 3.6 to 3.9, even including the yet-to-be-released Python 3.10. This test is allowed to fail with a warning. Signed-off-by: John Snow Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Alex Bennée Reviewed-by: Cleber Rosa Message-id: 20210527211715.394144-32-jsnow@redhat.com [Fix rebase conflict over .gitlab-ci.yml --js] Signed-off-by: John Snow --- tests/docker/dockerfiles/python.docker | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/docker/dockerfiles/python.docker (limited to 'tests') 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 + +# 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 -- cgit v1.1