Commit 62a23835 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/cleber/tags/python-next-pull-request' into staging



Python (acceptance tests) queue, 2019-10-28

# gpg: Signature made Mon 28 Oct 2019 23:43:11 GMT
# gpg:                using RSA key 7ABB96EB8B46B94D5E0FE9BB657E8D33A5F209F3
# gpg: Good signature from "Cleber Rosa <crosa@redhat.com>" [marginal]
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 7ABB 96EB 8B46 B94D 5E0F  E9BB 657E 8D33 A5F2 09F3

* remotes/cleber/tags/python-next-pull-request:
  tests/boot_linux_console: Run BusyBox on 5KEc 64-bit cpu
  tests/boot_linux_console: Add initrd test for the Exynos4210
  tests/boot_linux_console: Add a test for the Raspberry Pi 2
  tests/boot_linux_console: Use Avocado archive::gzip_uncompress()
  .travis.yml: Let the avocado job run the 40p tests
  tests/acceptance: Test OpenBIOS on the PReP/40p
  tests/acceptance: Add test that runs NetBSD 4.0 installer on PRep/40p
  .travis.yml: Let the avocado job run the Leon3 test
  tests/acceptance: Add test that boots the HelenOS microkernel on Leon3
  tests/acceptance: Refactor exec_command_and_wait_for_pattern()
  tests/acceptance: Send <carriage return> on serial lines
  tests/acceptance: Fix wait_for_console_pattern() hangs
  Acceptance tests: refactor wait_for_console_pattern
  Python libs: close console sockets before shutting down the VMs
  Acceptance tests: work around socket dir
  MAINTAINERS: update location of Python libraries

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 844178e7 efdb45bf
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ matrix:

    # Acceptance (Functional) tests
    - env:
        - CONFIG="--python=/usr/bin/python3 --target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu,ppc64-softmmu,m68k-softmmu"
        - CONFIG="--python=/usr/bin/python3 --target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,sparc-softmmu"
        - TEST_CMD="make check-acceptance"
      after_failure:
        - cat tests/results/latest/job.log
+3 −1
Original line number Diff line number Diff line
@@ -1082,6 +1082,7 @@ F: hw/rtc/m48t59-isa.c
F: include/hw/isa/pc87312.h
F: include/hw/rtc/m48t59.h
F: pc-bios/ppc_rom.bin
F: tests/acceptance/ppc_prep_40p.py

sPAPR
M: David Gibson <david@gibson.dropbear.id.au>
@@ -1187,6 +1188,7 @@ S: Maintained
F: hw/sparc/leon3.c
F: hw/*/grlib*
F: include/hw/*/grlib*
F: tests/acceptance/machine_sparc_leon3.py

S390 Machines
-------------
@@ -2022,7 +2024,7 @@ Python scripts
M: Eduardo Habkost <ehabkost@redhat.com>
M: Cleber Rosa <crosa@redhat.com>
S: Odd fixes
F: scripts/qmp/*
F: python/qemu/*py
F: scripts/*.py
F: tests/*.py

+7 −4
Original line number Diff line number Diff line
@@ -277,10 +277,6 @@ class QEMUMachine(object):

        self._qemu_log_path = None

        if self._console_socket is not None:
            self._console_socket.close()
            self._console_socket = None

        if self._temp_dir is not None:
            shutil.rmtree(self._temp_dir)
            self._temp_dir = None
@@ -342,6 +338,13 @@ class QEMUMachine(object):
        """
        Terminate the VM and clean up
        """
        # If we keep the console socket open, we may deadlock waiting
        # for QEMU to exit, while QEMU is waiting for the socket to
        # become writeable.
        if self._console_socket is not None:
            self._console_socket.close()
            self._console_socket = None

        if self.is_running():
            try:
                if not has_quit:
+47 −1
Original line number Diff line number Diff line
@@ -8,9 +8,11 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later.  See the COPYING file in the top-level directory.

import logging
import os
import sys
import uuid
import tempfile

import avocado

@@ -53,6 +55,50 @@ def pick_default_qemu_bin(arch=None):
        return qemu_bin_from_src_dir_path


def wait_for_console_pattern(test, success_message, failure_message=None):
    """
    Waits for messages to appear on the console, while logging the content

    :param test: an Avocado test containing a VM that will have its console
                 read and probed for a success or failure message
    :type test: :class:`avocado_qemu.Test`
    :param success_message: if this message appears, test succeeds
    :param failure_message: if this message appears, test fails
    """
    console = test.vm.console_socket.makefile()
    console_logger = logging.getLogger('console')
    while True:
        msg = console.readline().strip()
        if not msg:
            continue
        console_logger.debug(msg)
        if success_message in msg:
            break
        if failure_message and failure_message in msg:
            console.close()
            fail = 'Failure message found in console: %s' % failure_message
            test.fail(fail)


def exec_command_and_wait_for_pattern(test, command,
                                      success_message, failure_message=None):
    """
    Send a command to a console (appending CRLF characters), then wait
    for success_message to appear on the console, while logging the.
    content. Mark the test as failed if failure_message is found instead.

    :param test: an Avocado test containing a VM that will have its console
                 read and probed for a success or failure message
    :type test: :class:`avocado_qemu.Test`
    :param command: the command to send
    :param success_message: if this message appears, test succeeds
    :param failure_message: if this message appears, test fails
    """
    command += '\r'
    test.vm.console_socket.sendall(command.encode())
    wait_for_console_pattern(test, success_message, failure_message)


class Test(avocado.Test):
    def setUp(self):
        self._vms = {}
@@ -69,7 +115,7 @@ class Test(avocado.Test):
            self.cancel("No QEMU binary defined or found in the source tree")

    def _new_vm(self, *args):
        vm = QEMUMachine(self.qemu_bin)
        vm = QEMUMachine(self.qemu_bin, sock_dir=tempfile.mkdtemp())
        if args:
            vm.add_args(*args)
        return vm
+131 −36
Original line number Diff line number Diff line
@@ -9,12 +9,14 @@
# later.  See the COPYING file in the top-level directory.

import os
import logging
import lzma
import gzip
import shutil

from avocado import skipUnless
from avocado_qemu import Test
from avocado_qemu import exec_command_and_wait_for_pattern
from avocado_qemu import wait_for_console_pattern
from avocado.utils import process
from avocado.utils import archive

@@ -29,31 +31,9 @@ class BootLinuxConsole(Test):

    KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '

    def wait_for_console_pattern(self, success_message,
                                 failure_message='Kernel panic - not syncing'):
        """
        Waits for messages to appear on the console, while logging the content

        :param success_message: if this message appears, test succeeds
        :param failure_message: if this message appears, test fails
        """
        console = self.vm.console_socket.makefile()
        console_logger = logging.getLogger('console')
        while True:
            msg = console.readline().strip()
            if not msg:
                continue
            console_logger.debug(msg)
            if success_message in msg:
                break
            if failure_message in msg:
                fail = 'Failure message found in console: %s' % failure_message
                self.fail(fail)

    def exec_command_and_wait_for_pattern(self, command, success_message):
        command += '\n'
        self.vm.console_socket.sendall(command.encode())
        self.wait_for_console_pattern(success_message)
    def wait_for_console_pattern(self, success_message):
        wait_for_console_pattern(self, success_message,
                                 failure_message='Kernel panic - not syncing')

    def extract_from_deb(self, deb, path):
        """
@@ -166,10 +146,7 @@ class BootLinuxConsole(Test):
        initrd_hash = 'bf806e17009360a866bf537f6de66590de349a99'
        initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
        initrd_path = self.workdir + "rootfs.cpio"

        with gzip.open(initrd_path_gz, 'rb') as f_in:
            with open(initrd_path, 'wb') as f_out:
                shutil.copyfileobj(f_in, f_out)
        archive.gzip_uncompress(initrd_path_gz, initrd_path)

        self.vm.set_machine('malta')
        self.vm.set_console()
@@ -183,11 +160,52 @@ class BootLinuxConsole(Test):
        self.vm.launch()
        self.wait_for_console_pattern('Boot successful.')

        self.exec_command_and_wait_for_pattern('cat /proc/cpuinfo',
        exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
                                                'BogoMIPS')
        self.exec_command_and_wait_for_pattern('uname -a',
        exec_command_and_wait_for_pattern(self, 'uname -a',
                                                'Debian')
        self.exec_command_and_wait_for_pattern('reboot',
        exec_command_and_wait_for_pattern(self, 'reboot',
                                                'reboot: Restarting system')

    @skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
    def test_mips64el_malta_5KEc_cpio(self):
        """
        :avocado: tags=arch:mips64el
        :avocado: tags=machine:malta
        :avocado: tags=endian:little
        """
        kernel_url = ('https://github.com/philmd/qemu-testing-blob/'
                      'raw/9ad2df38/mips/malta/mips64el/'
                      'vmlinux-3.19.3.mtoman.20150408')
        kernel_hash = '00d1d268fb9f7d8beda1de6bebcc46e884d71754'
        kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
        initrd_url = ('https://github.com/groeck/linux-build-test/'
                      'raw/8584a59e/rootfs/'
                      'mipsel64/rootfs.mipsel64r1.cpio.gz')
        initrd_hash = '1dbb8a396e916847325284dbe2151167'
        initrd_path_gz = self.fetch_asset(initrd_url, algorithm='md5',
                                          asset_hash=initrd_hash)
        initrd_path = self.workdir + "rootfs.cpio"
        archive.gzip_uncompress(initrd_path_gz, initrd_path)

        self.vm.set_machine('malta')
        self.vm.set_console()
        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
                               + 'console=ttyS0 console=tty '
                               + 'rdinit=/sbin/init noreboot')
        self.vm.add_args('-cpu', '5KEc',
                         '-kernel', kernel_path,
                         '-initrd', initrd_path,
                         '-append', kernel_command_line,
                         '-no-reboot')
        self.vm.launch()
        wait_for_console_pattern(self, 'Boot successful.')

        exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
                                                'MIPS 5KE')
        exec_command_and_wait_for_pattern(self, 'uname -a',
                                                '3.19.3.mtoman.20150408')
        exec_command_and_wait_for_pattern(self, 'reboot',
                                                'reboot: Restarting system')

    def do_test_mips_malta32el_nanomips(self, kernel_url, kernel_hash):
@@ -316,6 +334,83 @@ class BootLinuxConsole(Test):
        self.vm.launch()
        self.wait_for_console_pattern('init started: BusyBox')

    def do_test_arm_raspi2(self, uart_id):
        """
        The kernel can be rebuilt using the kernel source referenced
        and following the instructions on the on:
        https://www.raspberrypi.org/documentation/linux/kernel/building.md
        """
        serial_kernel_cmdline = {
            0: 'earlycon=pl011,0x3f201000 console=ttyAMA0',
        }
        deb_url = ('http://archive.raspberrypi.org/debian/'
                   'pool/main/r/raspberrypi-firmware/'
                   'raspberrypi-kernel_1.20190215-1_armhf.deb')
        deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
        deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
        kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
        dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')

        self.vm.set_machine('raspi2')
        self.vm.set_console()
        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
                               serial_kernel_cmdline[uart_id])
        self.vm.add_args('-kernel', kernel_path,
                         '-dtb', dtb_path,
                         '-append', kernel_command_line)
        self.vm.launch()
        console_pattern = 'Kernel command line: %s' % kernel_command_line
        self.wait_for_console_pattern(console_pattern)

    def test_arm_raspi2_uart0(self):
        """
        :avocado: tags=arch:arm
        :avocado: tags=machine:raspi2
        :avocado: tags=device:pl011
        """
        self.do_test_arm_raspi2(0)

    def test_arm_exynos4210_initrd(self):
        """
        :avocado: tags=arch:arm
        :avocado: tags=machine:smdkc210
        """
        deb_url = ('https://snapshot.debian.org/archive/debian/'
                   '20190928T224601Z/pool/main/l/linux/'
                   'linux-image-4.19.0-6-armmp_4.19.67-2+deb10u1_armhf.deb')
        deb_hash = 'fa9df4a0d38936cb50084838f2cb933f570d7d82'
        deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
        kernel_path = self.extract_from_deb(deb_path,
                                            '/boot/vmlinuz-4.19.0-6-armmp')
        dtb_path = '/usr/lib/linux-image-4.19.0-6-armmp/exynos4210-smdkv310.dtb'
        dtb_path = self.extract_from_deb(deb_path, dtb_path)

        initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
                      '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
                      'arm/rootfs-armv5.cpio.gz')
        initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b'
        initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
        initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
        archive.gzip_uncompress(initrd_path_gz, initrd_path)

        self.vm.set_machine('smdkc210')
        self.vm.set_console()
        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
                               'earlycon=exynos4210,0x13800000 earlyprintk ' +
                               'console=ttySAC0,115200n8 ' +
                               'random.trust_cpu=off cryptomgr.notests ' +
                               'cpuidle.off=1 panic=-1 noreboot')

        self.vm.add_args('-kernel', kernel_path,
                         '-dtb', dtb_path,
                         '-initrd', initrd_path,
                         '-append', kernel_command_line,
                         '-no-reboot')
        self.vm.launch()

        self.wait_for_console_pattern('Boot successful.')
        # TODO user command, for now the uart is stuck

    def test_s390x_s390_ccw_virtio(self):
        """
        :avocado: tags=arch:s390x
Loading