This is basically the infrastructure around "boot_linux.py" tests, but
now made into a base class for general use.
Signed-off-by: Cleber Rosa <crosa@redhat.com>
---
tests/acceptance/avocado_qemu/__init__.py | 87 +++++++++++++++++++++
tests/acceptance/boot_linux.py | 94 ++---------------------
tests/acceptance/virtiofs_submounts.py | 6 +-
3 files changed, 94 insertions(+), 93 deletions(-)
diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
index bf54e419da..b06692a59d 100644
--- a/tests/acceptance/avocado_qemu/__init__.py
+++ b/tests/acceptance/avocado_qemu/__init__.py
@@ -16,6 +16,13 @@ import tempfile
import avocado
+from avocado.utils import cloudinit
+from avocado.utils import datadrainer
+from avocado.utils import network
+from avocado.utils import vmimage
+from avocado.utils.path import find_command
+
+
#: The QEMU build root directory. It may also be the source directory
#: if building from the source dir, but it's safer to use BUILD_DIR for
#: that purpose. Be aware that if this code is moved outside of a source
@@ -206,3 +213,83 @@ class Test(avocado.Test):
expire=expire,
find_only=find_only,
cancel_on_missing=cancel_on_missing)
+
+
+class LinuxTest(Test):
+ """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.
+ """
+
+ timeout = 900
+ chksum = None
+
+ def setUp(self, ssh_pubkey=None):
+ super(LinuxTest, self).setUp()
+ self.vm.add_args('-smp', '2')
+ self.vm.add_args('-m', '1024')
+ self.set_up_boot()
+ self.set_up_cloudinit(ssh_pubkey)
+
+ def download_boot(self):
+ self.log.debug('Looking for and selecting a qemu-img binary to be '
+ 'used to create the bootable snapshot image')
+ # If qemu-img has been built, use it, otherwise the system wide one
+ # will be used. If none is available, the test will cancel.
+ qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
+ if not os.path.exists(qemu_img):
+ qemu_img = find_command('qemu-img', False)
+ if qemu_img is False:
+ self.cancel('Could not find "qemu-img", which is required to '
+ 'create the bootable image')
+ vmimage.QEMU_IMG = qemu_img
+
+ self.log.info('Downloading/preparing boot image')
+ # Fedora 31 only provides ppc64le images
+ image_arch = self.arch
+ if image_arch == 'ppc64':
+ image_arch = 'ppc64le'
+ try:
+ boot = vmimage.get(
+ 'fedora', arch=image_arch, version='31',
+ checksum=self.chksum,
+ algorithm='sha256',
+ cache_dir=self.cache_dirs[0],
+ snapshot_dir=self.workdir)
+ except:
+ self.cancel('Failed to download/prepare boot image')
+ return boot.path
+
+ def prepare_cloudinit(self, ssh_pubkey=None):
+ self.log.info('Preparing cloudinit image')
+ try:
+ cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
+ self.phone_home_port = network.find_free_port()
+ cloudinit.iso(cloudinit_iso, self.name,
+ username='root',
+ password='password',
+ # QEMU's hard coded usermode router address
+ phone_home_host='10.0.2.2',
+ phone_home_port=self.phone_home_port,
+ authorized_key=ssh_pubkey)
+ except Exception:
+ self.cancel('Failed to prepare the cloudinit image')
+ return cloudinit_iso
+
+ def set_up_boot(self):
+ path = self.download_boot()
+ self.vm.add_args('-drive', 'file=%s' % path)
+
+ def set_up_cloudinit(self, ssh_pubkey=None):
+ cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
+ self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
+
+ def launch_and_wait(self):
+ self.vm.set_console()
+ self.vm.launch()
+ console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
+ logger=self.log.getChild('console'))
+ 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)
diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
index bcd923bb4a..14e89d020d 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/acceptance/boot_linux.py
@@ -10,16 +10,11 @@
import os
-from avocado_qemu import Test, BUILD_DIR
+from avocado_qemu import LinuxTest, BUILD_DIR
from qemu.accel import kvm_available
from qemu.accel import tcg_available
-from avocado.utils import cloudinit
-from avocado.utils import network
-from avocado.utils import vmimage
-from avocado.utils import datadrainer
-from avocado.utils.path import find_command
from avocado import skipIf
ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
@@ -27,86 +22,7 @@ KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
TCG_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "TCG"
-class BootLinuxBase(Test):
- def download_boot(self):
- self.log.debug('Looking for and selecting a qemu-img binary to be '
- 'used to create the bootable snapshot image')
- # If qemu-img has been built, use it, otherwise the system wide one
- # will be used. If none is available, the test will cancel.
- qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
- if not os.path.exists(qemu_img):
- qemu_img = find_command('qemu-img', False)
- if qemu_img is False:
- self.cancel('Could not find "qemu-img", which is required to '
- 'create the bootable image')
- vmimage.QEMU_IMG = qemu_img
-
- self.log.info('Downloading/preparing boot image')
- # Fedora 31 only provides ppc64le images
- image_arch = self.arch
- if image_arch == 'ppc64':
- image_arch = 'ppc64le'
- try:
- boot = vmimage.get(
- 'fedora', arch=image_arch, version='31',
- checksum=self.chksum,
- algorithm='sha256',
- cache_dir=self.cache_dirs[0],
- snapshot_dir=self.workdir)
- except:
- self.cancel('Failed to download/prepare boot image')
- return boot.path
-
- def prepare_cloudinit(self, ssh_pubkey=None):
- self.log.info('Preparing cloudinit image')
- try:
- cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
- self.phone_home_port = network.find_free_port()
- cloudinit.iso(cloudinit_iso, self.name,
- username='root',
- password='password',
- # QEMU's hard coded usermode router address
- phone_home_host='10.0.2.2',
- phone_home_port=self.phone_home_port,
- authorized_key=ssh_pubkey)
- except Exception:
- self.cancel('Failed to prepare the cloudinit image')
- return cloudinit_iso
-
-class BootLinux(BootLinuxBase):
- """
- Boots a Linux system, checking for a successful initialization
- """
-
- timeout = 900
- chksum = None
-
- def setUp(self, ssh_pubkey=None):
- super(BootLinux, self).setUp()
- self.vm.add_args('-smp', '2')
- self.vm.add_args('-m', '1024')
- self.set_up_boot()
- self.set_up_cloudinit(ssh_pubkey)
-
- def set_up_boot(self):
- path = self.download_boot()
- self.vm.add_args('-drive', 'file=%s' % path)
-
- def set_up_cloudinit(self, ssh_pubkey=None):
- cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
- self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
-
- def launch_and_wait(self):
- self.vm.set_console()
- self.vm.launch()
- console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
- logger=self.log.getChild('console'))
- 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)
-
-
-class BootLinuxX8664(BootLinux):
+class BootLinuxX8664(LinuxTest):
"""
:avocado: tags=arch:x86_64
"""
@@ -154,7 +70,7 @@ class BootLinuxX8664(BootLinux):
self.launch_and_wait()
-class BootLinuxAarch64(BootLinux):
+class BootLinuxAarch64(LinuxTest):
"""
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
@@ -212,7 +128,7 @@ class BootLinuxAarch64(BootLinux):
self.launch_and_wait()
-class BootLinuxPPC64(BootLinux):
+class BootLinuxPPC64(LinuxTest):
"""
:avocado: tags=arch:ppc64
"""
@@ -230,7 +146,7 @@ class BootLinuxPPC64(BootLinux):
self.launch_and_wait()
-class BootLinuxS390X(BootLinux):
+class BootLinuxS390X(LinuxTest):
"""
:avocado: tags=arch:s390x
"""
diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
index 1e745f15a2..25ea54b6ff 100644
--- a/tests/acceptance/virtiofs_submounts.py
+++ b/tests/acceptance/virtiofs_submounts.py
@@ -5,15 +5,13 @@ import subprocess
import time
from avocado import skipUnless
-from avocado_qemu import Test, BUILD_DIR
+from avocado_qemu import LinuxTest, BUILD_DIR
from avocado_qemu import wait_for_console_pattern
from avocado.utils import ssh
from qemu.accel import kvm_available
from qemu.utils import get_info_usernet_hostfwd_port
-from boot_linux import BootLinux
-
def run_cmd(args):
subp = subprocess.Popen(args,
@@ -72,7 +70,7 @@ def has_cmds(*cmds):
return (True, '')
-class VirtiofsSubmountsTest(BootLinux):
+class VirtiofsSubmountsTest(LinuxTest):
"""
:avocado: tags=arch:x86_64
:avocado: tags=accel:kvm
--
2.25.4
On 2/3/21 2:23 PM, Cleber Rosa wrote:
> This is basically the infrastructure around "boot_linux.py" tests, but
> now made into a base class for general use.
>
> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> ---
> tests/acceptance/avocado_qemu/__init__.py | 87 +++++++++++++++++++++
> tests/acceptance/boot_linux.py | 94 ++---------------------
> tests/acceptance/virtiofs_submounts.py | 6 +-
> 3 files changed, 94 insertions(+), 93 deletions(-)
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
>
> diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py
> index bf54e419da..b06692a59d 100644
> --- a/tests/acceptance/avocado_qemu/__init__.py
> +++ b/tests/acceptance/avocado_qemu/__init__.py
> @@ -16,6 +16,13 @@ import tempfile
>
> import avocado
>
> +from avocado.utils import cloudinit
> +from avocado.utils import datadrainer
> +from avocado.utils import network
> +from avocado.utils import vmimage
> +from avocado.utils.path import find_command
> +
> +
> #: The QEMU build root directory. It may also be the source directory
> #: if building from the source dir, but it's safer to use BUILD_DIR for
> #: that purpose. Be aware that if this code is moved outside of a source
> @@ -206,3 +213,83 @@ class Test(avocado.Test):
> expire=expire,
> find_only=find_only,
> cancel_on_missing=cancel_on_missing)
> +
> +
> +class LinuxTest(Test):
> + """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.
> + """
> +
> + timeout = 900
> + chksum = None
> +
> + def setUp(self, ssh_pubkey=None):
> + super(LinuxTest, self).setUp()
> + self.vm.add_args('-smp', '2')
> + self.vm.add_args('-m', '1024')
> + self.set_up_boot()
> + self.set_up_cloudinit(ssh_pubkey)
> +
> + def download_boot(self):
> + self.log.debug('Looking for and selecting a qemu-img binary to be '
> + 'used to create the bootable snapshot image')
> + # If qemu-img has been built, use it, otherwise the system wide one
> + # will be used. If none is available, the test will cancel.
> + qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
> + if not os.path.exists(qemu_img):
> + qemu_img = find_command('qemu-img', False)
> + if qemu_img is False:
> + self.cancel('Could not find "qemu-img", which is required to '
> + 'create the bootable image')
> + vmimage.QEMU_IMG = qemu_img
> +
> + self.log.info('Downloading/preparing boot image')
> + # Fedora 31 only provides ppc64le images
> + image_arch = self.arch
> + if image_arch == 'ppc64':
> + image_arch = 'ppc64le'
> + try:
> + boot = vmimage.get(
> + 'fedora', arch=image_arch, version='31',
> + checksum=self.chksum,
> + algorithm='sha256',
> + cache_dir=self.cache_dirs[0],
> + snapshot_dir=self.workdir)
> + except:
> + self.cancel('Failed to download/prepare boot image')
> + return boot.path
> +
> + def prepare_cloudinit(self, ssh_pubkey=None):
> + self.log.info('Preparing cloudinit image')
> + try:
> + cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
> + self.phone_home_port = network.find_free_port()
> + cloudinit.iso(cloudinit_iso, self.name,
> + username='root',
> + password='password',
> + # QEMU's hard coded usermode router address
> + phone_home_host='10.0.2.2',
> + phone_home_port=self.phone_home_port,
> + authorized_key=ssh_pubkey)
> + except Exception:
> + self.cancel('Failed to prepare the cloudinit image')
> + return cloudinit_iso
> +
> + def set_up_boot(self):
> + path = self.download_boot()
> + self.vm.add_args('-drive', 'file=%s' % path)
> +
> + def set_up_cloudinit(self, ssh_pubkey=None):
> + cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
> + self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
> +
> + def launch_and_wait(self):
> + self.vm.set_console()
> + self.vm.launch()
> + console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
> + logger=self.log.getChild('console'))
> + 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)
> diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
> index bcd923bb4a..14e89d020d 100644
> --- a/tests/acceptance/boot_linux.py
> +++ b/tests/acceptance/boot_linux.py
> @@ -10,16 +10,11 @@
>
> import os
>
> -from avocado_qemu import Test, BUILD_DIR
> +from avocado_qemu import LinuxTest, BUILD_DIR
>
> from qemu.accel import kvm_available
> from qemu.accel import tcg_available
>
> -from avocado.utils import cloudinit
> -from avocado.utils import network
> -from avocado.utils import vmimage
> -from avocado.utils import datadrainer
> -from avocado.utils.path import find_command
> from avocado import skipIf
>
> ACCEL_NOT_AVAILABLE_FMT = "%s accelerator does not seem to be available"
> @@ -27,86 +22,7 @@ KVM_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "KVM"
> TCG_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "TCG"
>
>
> -class BootLinuxBase(Test):
> - def download_boot(self):
> - self.log.debug('Looking for and selecting a qemu-img binary to be '
> - 'used to create the bootable snapshot image')
> - # If qemu-img has been built, use it, otherwise the system wide one
> - # will be used. If none is available, the test will cancel.
> - qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
> - if not os.path.exists(qemu_img):
> - qemu_img = find_command('qemu-img', False)
> - if qemu_img is False:
> - self.cancel('Could not find "qemu-img", which is required to '
> - 'create the bootable image')
> - vmimage.QEMU_IMG = qemu_img
> -
> - self.log.info('Downloading/preparing boot image')
> - # Fedora 31 only provides ppc64le images
> - image_arch = self.arch
> - if image_arch == 'ppc64':
> - image_arch = 'ppc64le'
> - try:
> - boot = vmimage.get(
> - 'fedora', arch=image_arch, version='31',
> - checksum=self.chksum,
> - algorithm='sha256',
> - cache_dir=self.cache_dirs[0],
> - snapshot_dir=self.workdir)
> - except:
> - self.cancel('Failed to download/prepare boot image')
> - return boot.path
> -
> - def prepare_cloudinit(self, ssh_pubkey=None):
> - self.log.info('Preparing cloudinit image')
> - try:
> - cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
> - self.phone_home_port = network.find_free_port()
> - cloudinit.iso(cloudinit_iso, self.name,
> - username='root',
> - password='password',
> - # QEMU's hard coded usermode router address
> - phone_home_host='10.0.2.2',
> - phone_home_port=self.phone_home_port,
> - authorized_key=ssh_pubkey)
> - except Exception:
> - self.cancel('Failed to prepare the cloudinit image')
> - return cloudinit_iso
> -
> -class BootLinux(BootLinuxBase):
> - """
> - Boots a Linux system, checking for a successful initialization
> - """
> -
> - timeout = 900
> - chksum = None
> -
> - def setUp(self, ssh_pubkey=None):
> - super(BootLinux, self).setUp()
> - self.vm.add_args('-smp', '2')
> - self.vm.add_args('-m', '1024')
> - self.set_up_boot()
> - self.set_up_cloudinit(ssh_pubkey)
> -
> - def set_up_boot(self):
> - path = self.download_boot()
> - self.vm.add_args('-drive', 'file=%s' % path)
> -
> - def set_up_cloudinit(self, ssh_pubkey=None):
> - cloudinit_iso = self.prepare_cloudinit(ssh_pubkey)
> - self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso)
> -
> - def launch_and_wait(self):
> - self.vm.set_console()
> - self.vm.launch()
> - console_drainer = datadrainer.LineLogger(self.vm.console_socket.fileno(),
> - logger=self.log.getChild('console'))
> - 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)
> -
> -
> -class BootLinuxX8664(BootLinux):
> +class BootLinuxX8664(LinuxTest):
> """
> :avocado: tags=arch:x86_64
> """
> @@ -154,7 +70,7 @@ class BootLinuxX8664(BootLinux):
> self.launch_and_wait()
>
>
> -class BootLinuxAarch64(BootLinux):
> +class BootLinuxAarch64(LinuxTest):
> """
> :avocado: tags=arch:aarch64
> :avocado: tags=machine:virt
> @@ -212,7 +128,7 @@ class BootLinuxAarch64(BootLinux):
> self.launch_and_wait()
>
>
> -class BootLinuxPPC64(BootLinux):
> +class BootLinuxPPC64(LinuxTest):
> """
> :avocado: tags=arch:ppc64
> """
> @@ -230,7 +146,7 @@ class BootLinuxPPC64(BootLinux):
> self.launch_and_wait()
>
>
> -class BootLinuxS390X(BootLinux):
> +class BootLinuxS390X(LinuxTest):
> """
> :avocado: tags=arch:s390x
> """
> diff --git a/tests/acceptance/virtiofs_submounts.py b/tests/acceptance/virtiofs_submounts.py
> index 1e745f15a2..25ea54b6ff 100644
> --- a/tests/acceptance/virtiofs_submounts.py
> +++ b/tests/acceptance/virtiofs_submounts.py
> @@ -5,15 +5,13 @@ import subprocess
> import time
>
> from avocado import skipUnless
> -from avocado_qemu import Test, BUILD_DIR
> +from avocado_qemu import LinuxTest, BUILD_DIR
> from avocado_qemu import wait_for_console_pattern
> from avocado.utils import ssh
>
> from qemu.accel import kvm_available
> from qemu.utils import get_info_usernet_hostfwd_port
>
> -from boot_linux import BootLinux
> -
>
> def run_cmd(args):
> subp = subprocess.Popen(args,
> @@ -72,7 +70,7 @@ def has_cmds(*cmds):
> return (True, '')
>
>
> -class VirtiofsSubmountsTest(BootLinux):
> +class VirtiofsSubmountsTest(LinuxTest):
> """
> :avocado: tags=arch:x86_64
> :avocado: tags=accel:kvm
On Wed, Feb 3, 2021 at 2:24 PM Cleber Rosa <crosa@redhat.com> wrote: > > This is basically the infrastructure around "boot_linux.py" tests, but > now made into a base class for general use. > > Signed-off-by: Cleber Rosa <crosa@redhat.com> > --- > tests/acceptance/avocado_qemu/__init__.py | 87 +++++++++++++++++++++ > tests/acceptance/boot_linux.py | 94 ++--------------------- > tests/acceptance/virtiofs_submounts.py | 6 +- > 3 files changed, 94 insertions(+), 93 deletions(-) > > diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py > index bf54e419da..b06692a59d 100644 > --- a/tests/acceptance/avocado_qemu/__init__.py > +++ b/tests/acceptance/avocado_qemu/__init__.py I found it not so intuitive to have the base class defined here. I see the number of base classes for the tests growing in the future. A common place for base classes for tests would be better, just like the `qemu.utils` you are defining somewhere else. Anyway, this is a design decision that can be changed later, so Reviewed-by: Willian Rampazzo <willianr@redhat.com>
On Mon, Feb 15, 2021 at 04:06:45PM -0300, Willian Rampazzo wrote: > On Wed, Feb 3, 2021 at 2:24 PM Cleber Rosa <crosa@redhat.com> wrote: > > > > This is basically the infrastructure around "boot_linux.py" tests, but > > now made into a base class for general use. > > > > Signed-off-by: Cleber Rosa <crosa@redhat.com> > > --- > > tests/acceptance/avocado_qemu/__init__.py | 87 +++++++++++++++++++++ > > tests/acceptance/boot_linux.py | 94 ++--------------------- > > tests/acceptance/virtiofs_submounts.py | 6 +- > > 3 files changed, 94 insertions(+), 93 deletions(-) > > > > diff --git a/tests/acceptance/avocado_qemu/__init__.py b/tests/acceptance/avocado_qemu/__init__.py > > index bf54e419da..b06692a59d 100644 > > --- a/tests/acceptance/avocado_qemu/__init__.py > > +++ b/tests/acceptance/avocado_qemu/__init__.py > > I found it not so intuitive to have the base class defined here. I see > the number of base classes for the tests growing in the future. A > common place for base classes for tests would be better, just like the > `qemu.utils` you are defining somewhere else. Anyway, this is a design > decision that can be changed later, so > Hi Willian, I tend to agree, and my medium/long term vision is similar. What I expect to be able to do soon (this is connected to John's work) is to have "avocado_qemu" as something like "qemu.testing.functional" which describe its Avocado (and other) dependencies. A "qemu.test.other" could describe its own dependencies (which may not include Avocado). > Reviewed-by: Willian Rampazzo <willianr@redhat.com> > > Thanks for the review, - Cleber.
© 2016 - 2026 Red Hat, Inc.