From nobody Mon Sep 16 19:10:07 2024 Delivered-To: importer2@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1721382691; cv=none; d=zohomail.com; s=zohoarc; b=ac3HZUW738ZbRHhie76jRUDZmfzYkhnQ7kX4ejGbCsNxrqWN/AH/mN58W3oeylBu43P8AzN4r8zZ5+xIXpUOjUgH6Zc/svfFRNBsi398/tzJEervTgrz58gSUu6YIsoychfgK+NiJ0SgAavioLgpzSx7lLm1jxoRAjsDEnG6f24= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1721382691; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=9y9Ij66/J8exGryiUhQ0gmr+Ps8BviwHqBpAqtIAOIs=; b=YWDN5d9l91AsGV4dPz8dzL8gVF2ZNa2VUyVp6qOJv/BOuOviPpxdROEPp6EPeg2xu2PWrbfh9jREYHmtNt5xBgw6kjZzN39Fj6i2SMFMf4FZS0EfC8SRC0FqhiT5ZP6yuWYEhttl1sxNkmvillCMkHTqdhjmHJPEixYSLIs/jqI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer2=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1721382691517293.6553844175054; Fri, 19 Jul 2024 02:51:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sUkGI-0003tU-8J; Fri, 19 Jul 2024 05:50:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sUkGG-0003sX-Q5 for qemu-devel@nongnu.org; Fri, 19 Jul 2024 05:50:48 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sUkGD-0001D9-Pd for qemu-devel@nongnu.org; Fri, 19 Jul 2024 05:50:48 -0400 Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-480-_HUDpJEoMye9FcM_rmV2Pg-1; Fri, 19 Jul 2024 05:50:40 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A74E51955F65; Fri, 19 Jul 2024 09:50:37 +0000 (UTC) Received: from thuth-p1g4.redhat.com (unknown [10.39.194.113]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 529313000192; Fri, 19 Jul 2024 09:50:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1721382643; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=9y9Ij66/J8exGryiUhQ0gmr+Ps8BviwHqBpAqtIAOIs=; b=B//n3Fotv7h0U+tcV4OkTmKBktl5iDWYVhthBGoPaaVE/pwz4lI9sUxPmwHUs22f3qhIia UxeSJayBXWpQgtA+61gZUpSHBer43uwVZO2EDiTmDQQWn4JWpr3MPSo4p+nA65n1DdEyVK XbjZ2OO9pXBi1kajhHrrDqJSS64ERUc= X-MC-Unique: _HUDpJEoMye9FcM_rmV2Pg-1 From: Thomas Huth To: qemu-devel@nongnu.org Cc: Cleber Rosa , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Wainer dos Santos Moschetta , Beraldo Leal , Pavel Dovgalyuk , Paolo Bonzini , Eric Auger , qemu-arm@nongnu.org Subject: [PATCH] tests/avocado: Move LinuxTest related code into a separate file Date: Fri, 19 Jul 2024 11:50:31 +0200 Message-ID: <20240719095031.32814-1-thuth@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer2=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=thuth@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_FILL_THIS_FORM_FRAUD_PHISH=0.01, T_FILL_THIS_FORM_SHORT=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer2=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer2=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1721382693411116300 Content-Type: text/plain; charset="utf-8" Only some few tests are using the LinuxTest class. Move the related code into a separate file so that this does not pollute the main namespace. Signed-off-by: Thomas Huth Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- tests/avocado/avocado_qemu/__init__.py | 239 +--------------------- tests/avocado/avocado_qemu/linuxtest.py | 253 ++++++++++++++++++++++++ tests/avocado/boot_linux.py | 3 +- tests/avocado/hotplug_blk.py | 2 +- tests/avocado/hotplug_cpu.py | 2 +- tests/avocado/intel_iommu.py | 2 +- tests/avocado/replay_linux.py | 2 +- tests/avocado/smmu.py | 3 +- 8 files changed, 262 insertions(+), 244 deletions(-) create mode 100644 tests/avocado/avocado_qemu/linuxtest.py diff --git a/tests/avocado/avocado_qemu/__init__.py b/tests/avocado/avocado= _qemu/__init__.py index 304c428168..a3da2a96bb 100644 --- a/tests/avocado/avocado_qemu/__init__.py +++ b/tests/avocado/avocado_qemu/__init__.py @@ -10,7 +10,6 @@ =20 import logging import os -import shutil import subprocess import sys import tempfile @@ -18,7 +17,7 @@ import uuid =20 import avocado -from avocado.utils import cloudinit, datadrainer, process, ssh, vmimage +from avocado.utils import ssh from avocado.utils.path import find_command =20 from qemu.machine import QEMUMachine @@ -32,14 +31,6 @@ #: and build tree, it will not be accurate. BUILD_DIR =3D os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirn= ame(__file__)))) =20 -if os.path.islink(os.path.dirname(os.path.dirname(__file__))): - # The link to the avocado tests dir in the source code directory - lnk =3D os.path.dirname(os.path.dirname(__file__)) - #: The QEMU root source directory - SOURCE_DIR =3D os.path.dirname(os.path.dirname(os.readlink(lnk))) -else: - SOURCE_DIR =3D BUILD_DIR - =20 def has_cmd(name, args=3DNone): """ @@ -451,231 +442,3 @@ def ssh_command_output_contains(self, cmd, exp): break else: self.fail('"%s" output does not contain "%s"' % (cmd, exp)) - -class LinuxDistro: - """Represents a Linux distribution - - Holds information of known distros. - """ - #: A collection of known distros and their respective image checksum - KNOWN_DISTROS =3D { - 'fedora': { - '31': { - 'x86_64': - {'checksum': ('e3c1b309d9203604922d6e255c2c5d09' - '8a309c2d46215d8fc026954f3c5c27a0'), - 'pxeboot_url': ('https://archives.fedoraproject.org/' - 'pub/archive/fedora/linux/releases/31/' - 'Everything/x86_64/os/images/pxeboot/'), - 'kernel_params': ('root=3DUUID=3Db1438b9b-2cab-4065-a99a-' - '08a96687f73c ro no_timer_check ' - 'net.ifnames=3D0 console=3Dtty1 ' - 'console=3DttyS0,115200n8'), - }, - 'aarch64': - {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae' - 'd2af0ad0329383d5639c997fdf16fe49'), - 'pxeboot_url': 'https://archives.fedoraproject.org/' - 'pub/archive/fedora/linux/releases/31/' - 'Everything/aarch64/os/images/pxeboot/', - 'kernel_params': ('root=3DUUID=3Db6950a44-9f3c-4076-a9c2-' - '355e8475b0a7 ro earlyprintk=3Dpl011,0x9= 000000' - ' ignore_loglevel no_timer_check' - ' printk.time=3D1 rd_NO_PLYMOUTH' - ' console=3DttyAMA0'), - }, - 'ppc64': - {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4' - '3f991c506f2cc390dc4efa2026ad2f58')}, - 's390x': - {'checksum': ('4caaab5a434fd4d1079149a072fdc789' - '1e354f834d355069ca982fdcaf5a122d')}, - }, - '32': { - 'aarch64': - {'checksum': ('b367755c664a2d7a26955bbfff985855' - 'adfa2ca15e908baf15b4b176d68d3967'), - 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/li= nux/' - 'releases/32/Server/aarch64/os/images/' - 'pxeboot/'), - 'kernel_params': ('root=3DUUID=3D3df75b65-be8d-4db4-8655-' - '14d95c0e90c5 ro no_timer_check net.ifna= mes=3D0' - ' console=3Dtty1 console=3DttyS0,115200n= 8'), - }, - }, - '33': { - 'aarch64': - {'checksum': ('e7f75cdfd523fe5ac2ca9eeece68edc1' - 'a81f386a17f969c1d1c7c87031008a6b'), - 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/li= nux/' - 'releases/33/Server/aarch64/os/images/' - 'pxeboot/'), - 'kernel_params': ('root=3DUUID=3Dd20b3ffa-6397-4a63-a734-' - '1126a0208f8a ro no_timer_check net.ifna= mes=3D0' - ' console=3Dtty1 console=3DttyS0,115200n= 8' - ' console=3Dtty0'), - }, - }, - } - } - - def __init__(self, name, version, arch): - self.name =3D name - self.version =3D version - self.arch =3D arch - try: - info =3D self.KNOWN_DISTROS.get(name).get(version).get(arch) - except AttributeError: - # Unknown distro - info =3D None - self._info =3D info or {} - - @property - def checksum(self): - """Gets the cloud-image file checksum""" - return self._info.get('checksum', None) - - @checksum.setter - def checksum(self, value): - self._info['checksum'] =3D value - - @property - def pxeboot_url(self): - """Gets the repository url where pxeboot files can be found""" - return self._info.get('pxeboot_url', None) - - @property - def default_kernel_params(self): - """Gets the default kernel parameters""" - return self._info.get('kernel_params', None) - - -class LinuxTest(LinuxSSHMixIn, QemuSystemTest): - """Facilitates having a cloud-image Linux based available. - - For tests that intend to interact with guests, this is a better choice - to start with than the more vanilla `QemuSystemTest` class. - """ - - distro =3D None - username =3D 'root' - password =3D 'password' - smp =3D '2' - memory =3D '1024' - - def _set_distro(self): - distro_name =3D self.params.get( - 'distro', - default=3Dself._get_unique_tag_val('distro')) - if not distro_name: - distro_name =3D 'fedora' - - distro_version =3D self.params.get( - 'distro_version', - default=3Dself._get_unique_tag_val('distro_version')) - if not distro_version: - distro_version =3D '31' - - self.distro =3D LinuxDistro(distro_name, distro_version, self.arch) - - # The distro checksum behaves differently than distro name and - # version. First, it does not respect a tag with the same - # name, given that it's not expected to be used for filtering - # (distro name versions are the natural choice). Second, the - # order of precedence is: parameter, attribute and then value - # from KNOWN_DISTROS. - distro_checksum =3D self.params.get('distro_checksum', - default=3DNone) - if distro_checksum: - self.distro.checksum =3D distro_checksum - - def setUp(self, ssh_pubkey=3DNone, network_device_type=3D'virtio-net'): - super().setUp() - self.require_netdev('user') - self._set_distro() - self.vm.add_args('-smp', self.smp) - self.vm.add_args('-m', self.memory) - # The following network device allows for SSH connections - self.vm.add_args('-netdev', 'user,id=3Dvnet,hostfwd=3D:127.0.0.1:0= -:22', - '-device', '%s,netdev=3Dvnet' % network_device_ty= pe) - self.set_up_boot() - if ssh_pubkey is None: - ssh_pubkey, self.ssh_key =3D self.set_up_existing_ssh_keys() - self.set_up_cloudinit(ssh_pubkey) - - def set_up_existing_ssh_keys(self): - ssh_public_key =3D os.path.join(SOURCE_DIR, 'tests', 'keys', 'id_r= sa.pub') - source_private_key =3D os.path.join(SOURCE_DIR, 'tests', 'keys', '= id_rsa') - ssh_dir =3D os.path.join(self.workdir, '.ssh') - os.mkdir(ssh_dir, mode=3D0o700) - ssh_private_key =3D os.path.join(ssh_dir, - os.path.basename(source_private_key= )) - shutil.copyfile(source_private_key, ssh_private_key) - os.chmod(ssh_private_key, 0o600) - return (ssh_public_key, ssh_private_key) - - def download_boot(self): - # Set the qemu-img binary. - # If none is available, the test will cancel. - vmimage.QEMU_IMG =3D super().get_qemu_img() - - self.log.info('Downloading/preparing boot image') - # Fedora 31 only provides ppc64le images - image_arch =3D self.arch - if self.distro.name =3D=3D 'fedora': - if image_arch =3D=3D 'ppc64': - image_arch =3D 'ppc64le' - - try: - boot =3D vmimage.get( - self.distro.name, arch=3Dimage_arch, version=3Dself.distro= .version, - checksum=3Dself.distro.checksum, - algorithm=3D'sha256', - cache_dir=3Dself.cache_dirs[0], - snapshot_dir=3Dself.workdir) - except: - self.cancel('Failed to download/prepare boot image') - return boot.path - - def prepare_cloudinit(self, ssh_pubkey=3DNone): - self.log.info('Preparing cloudinit image') - try: - cloudinit_iso =3D os.path.join(self.workdir, 'cloudinit.iso') - pubkey_content =3D None - if ssh_pubkey: - with open(ssh_pubkey) as pubkey: - pubkey_content =3D pubkey.read() - cloudinit.iso(cloudinit_iso, self.name, - username=3Dself.username, - password=3Dself.password, - # QEMU's hard coded usermode router address - phone_home_host=3D'10.0.2.2', - phone_home_port=3Dself.phone_server.server_port, - authorized_key=3Dpubkey_content) - except Exception: - self.cancel('Failed to prepare the cloudinit image') - return cloudinit_iso - - def set_up_boot(self): - path =3D self.download_boot() - self.vm.add_args('-drive', 'file=3D%s' % path) - - def set_up_cloudinit(self, ssh_pubkey=3DNone): - self.phone_server =3D cloudinit.PhoneHomeServer(('0.0.0.0', 0), - self.name) - cloudinit_iso =3D self.prepare_cloudinit(ssh_pubkey) - self.vm.add_args('-drive', 'file=3D%s,format=3Draw' % cloudinit_is= o) - - def launch_and_wait(self, set_up_ssh_connection=3DTrue): - self.vm.set_console() - self.vm.launch() - console_drainer =3D datadrainer.LineLogger(self.vm.console_socket.= fileno(), - logger=3Dself.log.getChil= d('console')) - console_drainer.start() - self.log.info('VM launched, waiting for boot confirmation from gue= st') - while not self.phone_server.instance_phoned_back: - self.phone_server.handle_request() - - 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/avocado/avocado_qemu/linuxtest.py b/tests/avocado/avocad= o_qemu/linuxtest.py new file mode 100644 index 0000000000..e1dc838b1c --- /dev/null +++ b/tests/avocado/avocado_qemu/linuxtest.py @@ -0,0 +1,253 @@ +# Test class and utilities for functional Linux-based tests +# +# Copyright (c) 2018 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. + +import os +import shutil + +from avocado.utils import cloudinit, datadrainer, process, vmimage + +from . import LinuxSSHMixIn +from . import QemuSystemTest + +if os.path.islink(os.path.dirname(os.path.dirname(__file__))): + # The link to the avocado tests dir in the source code directory + lnk =3D os.path.dirname(os.path.dirname(__file__)) + #: The QEMU root source directory + SOURCE_DIR =3D os.path.dirname(os.path.dirname(os.readlink(lnk))) +else: + SOURCE_DIR =3D BUILD_DIR + +class LinuxDistro: + """Represents a Linux distribution + + Holds information of known distros. + """ + #: A collection of known distros and their respective image checksum + KNOWN_DISTROS =3D { + 'fedora': { + '31': { + 'x86_64': + {'checksum': ('e3c1b309d9203604922d6e255c2c5d09' + '8a309c2d46215d8fc026954f3c5c27a0'), + 'pxeboot_url': ('https://archives.fedoraproject.org/' + 'pub/archive/fedora/linux/releases/31/' + 'Everything/x86_64/os/images/pxeboot/'), + 'kernel_params': ('root=3DUUID=3Db1438b9b-2cab-4065-a99a-' + '08a96687f73c ro no_timer_check ' + 'net.ifnames=3D0 console=3Dtty1 ' + 'console=3DttyS0,115200n8'), + }, + 'aarch64': + {'checksum': ('1e18d9c0cf734940c4b5d5ec592facae' + 'd2af0ad0329383d5639c997fdf16fe49'), + 'pxeboot_url': 'https://archives.fedoraproject.org/' + 'pub/archive/fedora/linux/releases/31/' + 'Everything/aarch64/os/images/pxeboot/', + 'kernel_params': ('root=3DUUID=3Db6950a44-9f3c-4076-a9c2-' + '355e8475b0a7 ro earlyprintk=3Dpl011,0x9= 000000' + ' ignore_loglevel no_timer_check' + ' printk.time=3D1 rd_NO_PLYMOUTH' + ' console=3DttyAMA0'), + }, + 'ppc64': + {'checksum': ('7c3528b85a3df4b2306e892199a9e1e4' + '3f991c506f2cc390dc4efa2026ad2f58')}, + 's390x': + {'checksum': ('4caaab5a434fd4d1079149a072fdc789' + '1e354f834d355069ca982fdcaf5a122d')}, + }, + '32': { + 'aarch64': + {'checksum': ('b367755c664a2d7a26955bbfff985855' + 'adfa2ca15e908baf15b4b176d68d3967'), + 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/li= nux/' + 'releases/32/Server/aarch64/os/images/' + 'pxeboot/'), + 'kernel_params': ('root=3DUUID=3D3df75b65-be8d-4db4-8655-' + '14d95c0e90c5 ro no_timer_check net.ifna= mes=3D0' + ' console=3Dtty1 console=3DttyS0,115200n= 8'), + }, + }, + '33': { + 'aarch64': + {'checksum': ('e7f75cdfd523fe5ac2ca9eeece68edc1' + 'a81f386a17f969c1d1c7c87031008a6b'), + 'pxeboot_url': ('http://dl.fedoraproject.org/pub/fedora/li= nux/' + 'releases/33/Server/aarch64/os/images/' + 'pxeboot/'), + 'kernel_params': ('root=3DUUID=3Dd20b3ffa-6397-4a63-a734-' + '1126a0208f8a ro no_timer_check net.ifna= mes=3D0' + ' console=3Dtty1 console=3DttyS0,115200n= 8' + ' console=3Dtty0'), + }, + }, + } + } + + def __init__(self, name, version, arch): + self.name =3D name + self.version =3D version + self.arch =3D arch + try: + info =3D self.KNOWN_DISTROS.get(name).get(version).get(arch) + except AttributeError: + # Unknown distro + info =3D None + self._info =3D info or {} + + @property + def checksum(self): + """Gets the cloud-image file checksum""" + return self._info.get('checksum', None) + + @checksum.setter + def checksum(self, value): + self._info['checksum'] =3D value + + @property + def pxeboot_url(self): + """Gets the repository url where pxeboot files can be found""" + return self._info.get('pxeboot_url', None) + + @property + def default_kernel_params(self): + """Gets the default kernel parameters""" + return self._info.get('kernel_params', None) + + +class LinuxTest(LinuxSSHMixIn, QemuSystemTest): + """Facilitates having a cloud-image Linux based available. + + For tests that intend to interact with guests, this is a better choice + to start with than the more vanilla `QemuSystemTest` class. + """ + + distro =3D None + username =3D 'root' + password =3D 'password' + smp =3D '2' + memory =3D '1024' + + def _set_distro(self): + distro_name =3D self.params.get( + 'distro', + default=3Dself._get_unique_tag_val('distro')) + if not distro_name: + distro_name =3D 'fedora' + + distro_version =3D self.params.get( + 'distro_version', + default=3Dself._get_unique_tag_val('distro_version')) + if not distro_version: + distro_version =3D '31' + + self.distro =3D LinuxDistro(distro_name, distro_version, self.arch) + + # The distro checksum behaves differently than distro name and + # version. First, it does not respect a tag with the same + # name, given that it's not expected to be used for filtering + # (distro name versions are the natural choice). Second, the + # order of precedence is: parameter, attribute and then value + # from KNOWN_DISTROS. + distro_checksum =3D self.params.get('distro_checksum', + default=3DNone) + if distro_checksum: + self.distro.checksum =3D distro_checksum + + def setUp(self, ssh_pubkey=3DNone, network_device_type=3D'virtio-net'): + super().setUp() + self.require_netdev('user') + self._set_distro() + self.vm.add_args('-smp', self.smp) + self.vm.add_args('-m', self.memory) + # The following network device allows for SSH connections + self.vm.add_args('-netdev', 'user,id=3Dvnet,hostfwd=3D:127.0.0.1:0= -:22', + '-device', '%s,netdev=3Dvnet' % network_device_ty= pe) + self.set_up_boot() + if ssh_pubkey is None: + ssh_pubkey, self.ssh_key =3D self.set_up_existing_ssh_keys() + self.set_up_cloudinit(ssh_pubkey) + + def set_up_existing_ssh_keys(self): + ssh_public_key =3D os.path.join(SOURCE_DIR, 'tests', 'keys', 'id_r= sa.pub') + source_private_key =3D os.path.join(SOURCE_DIR, 'tests', 'keys', '= id_rsa') + ssh_dir =3D os.path.join(self.workdir, '.ssh') + os.mkdir(ssh_dir, mode=3D0o700) + ssh_private_key =3D os.path.join(ssh_dir, + os.path.basename(source_private_key= )) + shutil.copyfile(source_private_key, ssh_private_key) + os.chmod(ssh_private_key, 0o600) + return (ssh_public_key, ssh_private_key) + + def download_boot(self): + # Set the qemu-img binary. + # If none is available, the test will cancel. + vmimage.QEMU_IMG =3D super().get_qemu_img() + + self.log.info('Downloading/preparing boot image') + # Fedora 31 only provides ppc64le images + image_arch =3D self.arch + if self.distro.name =3D=3D 'fedora': + if image_arch =3D=3D 'ppc64': + image_arch =3D 'ppc64le' + + try: + boot =3D vmimage.get( + self.distro.name, arch=3Dimage_arch, version=3Dself.distro= .version, + checksum=3Dself.distro.checksum, + algorithm=3D'sha256', + cache_dir=3Dself.cache_dirs[0], + snapshot_dir=3Dself.workdir) + except: + self.cancel('Failed to download/prepare boot image') + return boot.path + + def prepare_cloudinit(self, ssh_pubkey=3DNone): + self.log.info('Preparing cloudinit image') + try: + cloudinit_iso =3D os.path.join(self.workdir, 'cloudinit.iso') + pubkey_content =3D None + if ssh_pubkey: + with open(ssh_pubkey) as pubkey: + pubkey_content =3D pubkey.read() + cloudinit.iso(cloudinit_iso, self.name, + username=3Dself.username, + password=3Dself.password, + # QEMU's hard coded usermode router address + phone_home_host=3D'10.0.2.2', + phone_home_port=3Dself.phone_server.server_port, + authorized_key=3Dpubkey_content) + except Exception: + self.cancel('Failed to prepare the cloudinit image') + return cloudinit_iso + + def set_up_boot(self): + path =3D self.download_boot() + self.vm.add_args('-drive', 'file=3D%s' % path) + + def set_up_cloudinit(self, ssh_pubkey=3DNone): + self.phone_server =3D cloudinit.PhoneHomeServer(('0.0.0.0', 0), + self.name) + cloudinit_iso =3D self.prepare_cloudinit(ssh_pubkey) + self.vm.add_args('-drive', 'file=3D%s,format=3Draw' % cloudinit_is= o) + + def launch_and_wait(self, set_up_ssh_connection=3DTrue): + self.vm.set_console() + self.vm.launch() + console_drainer =3D datadrainer.LineLogger(self.vm.console_socket.= fileno(), + logger=3Dself.log.getChil= d('console')) + console_drainer.start() + self.log.info('VM launched, waiting for boot confirmation from gue= st') + while not self.phone_server.instance_phoned_back: + self.phone_server.handle_request() + + 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/avocado/boot_linux.py b/tests/avocado/boot_linux.py index cdce4cbcba..a029ef4ad1 100644 --- a/tests/avocado/boot_linux.py +++ b/tests/avocado/boot_linux.py @@ -10,7 +10,8 @@ =20 import os =20 -from avocado_qemu import LinuxTest, BUILD_DIR +from avocado_qemu.linuxtest import LinuxTest +from avocado_qemu import BUILD_DIR =20 from avocado import skipUnless =20 diff --git a/tests/avocado/hotplug_blk.py b/tests/avocado/hotplug_blk.py index 5dc30f6616..d55ded1c1d 100644 --- a/tests/avocado/hotplug_blk.py +++ b/tests/avocado/hotplug_blk.py @@ -9,7 +9,7 @@ =20 import time =20 -from avocado_qemu import LinuxTest +from avocado_qemu.linuxtest import LinuxTest =20 =20 class HotPlug(LinuxTest): diff --git a/tests/avocado/hotplug_cpu.py b/tests/avocado/hotplug_cpu.py index 292bb43e4d..342c838539 100644 --- a/tests/avocado/hotplug_cpu.py +++ b/tests/avocado/hotplug_cpu.py @@ -8,7 +8,7 @@ # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. =20 -from avocado_qemu import LinuxTest +from avocado_qemu.linuxtest import LinuxTest =20 =20 class HotPlugCPU(LinuxTest): diff --git a/tests/avocado/intel_iommu.py b/tests/avocado/intel_iommu.py index 09e694bd40..008f214397 100644 --- a/tests/avocado/intel_iommu.py +++ b/tests/avocado/intel_iommu.py @@ -10,7 +10,7 @@ import os =20 from avocado import skipUnless -from avocado_qemu import LinuxTest +from avocado_qemu.linuxtest import LinuxTest =20 @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLa= b') =20 diff --git a/tests/avocado/replay_linux.py b/tests/avocado/replay_linux.py index f3a43dc98c..b4673261ce 100644 --- a/tests/avocado/replay_linux.py +++ b/tests/avocado/replay_linux.py @@ -19,7 +19,7 @@ from avocado.utils import vmimage from avocado.utils import datadrainer from avocado.utils.path import find_command -from avocado_qemu import LinuxTest +from avocado_qemu.linuxtest import LinuxTest =20 class ReplayLinux(LinuxTest): """ diff --git a/tests/avocado/smmu.py b/tests/avocado/smmu.py index 4ebfa7128c..aadda71e4b 100644 --- a/tests/avocado/smmu.py +++ b/tests/avocado/smmu.py @@ -10,7 +10,8 @@ import os =20 from avocado import skipUnless -from avocado_qemu import LinuxTest, BUILD_DIR +from avocado_qemu import BUILD_DIR +from avocado_qemu.linuxtest import LinuxTest =20 @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLa= b') =20 --=20 2.45.2