qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 4/4] BootLinuxSshTest: Test some userspace co


From: Eduardo Habkost
Subject: Re: [Qemu-devel] [PATCH v2 4/4] BootLinuxSshTest: Test some userspace commands on Malta
Date: Fri, 24 May 2019 15:42:25 -0300
User-agent: Mutt/1.10.1 (2018-07-13)

On Thu, May 23, 2019 at 06:18:32PM +0200, Philippe Mathieu-Daudé wrote:
> This tests boot a full VM and check the serial console until
> the SSH daemon is running, then start a SSH session and run
> some commands.
> 
> This test can be run using:
> 
>   $ avocado --show=ssh run -t arch:mips 
> tests/acceptance/linux_ssh_mips_malta.py
>   ssh: Entering interactive session.
>   ssh: # uname -a
>   ssh: Linux debian-mips 3.2.0-4-4kc-malta #1 Debian 3.2.51-1 mips GNU/Linux
>   ssh: # lspci -d 11ab:4620
>   ssh: 00:00.0 Host bridge: Marvell Technology Group Ltd. 
> GT-64120/64120A/64121A System Controller (rev 10)
>   ssh: # cat /sys/bus/i2c/devices/i2c-0/name
>   ssh: SMBus PIIX4 adapter at 1100
>   ssh: # cat /proc/mtd
>   ssh: dev:    size   erasesize  name
>   ssh: mtd0: 00100000 00010000 "YAMON"
>   ssh: mtd1: 002e0000 00010000 "User FS"
>   ssh: mtd2: 00020000 00010000 "Board Config"
>   ssh: # md5sum /dev/mtd2ro
>   ssh: 0dfbe8aa4c20b52e1b8bf3cb6cbdf193  /dev/mtd2ro
>   ssh: # poweroff
> 
> Acked-by: Aleksandar Markovic <address@hidden>
> Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
> ---
> v2: Add skipIf(getenv(CONTINUOUS_INTEGRATION))

This will make the behavior of "make check-acceptance" different
inside and outside Travis, in a way that is not documented
anywhere.  I thought we would be using Avocado tags to indicate
which tests we want to skip.

But if it solves our immediate problems we're having, I won't
NACK this.  Can we at least add TODO comments indicating we
should eventually get rid of the hack?

Reviewed-by: Eduardo Habkost <address@hidden>

> ---
>  MAINTAINERS                              |   1 +
>  tests/acceptance/linux_ssh_mips_malta.py | 230 +++++++++++++++++++++++
>  tests/requirements.txt                   |   1 +
>  3 files changed, 232 insertions(+)
>  create mode 100644 tests/acceptance/linux_ssh_mips_malta.py
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3cacd751bf..8c34d5c34b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -934,6 +934,7 @@ M: Aurelien Jarno <address@hidden>
>  R: Aleksandar Rikalo <address@hidden>
>  S: Maintained
>  F: hw/mips/mips_malta.c
> +F: tests/acceptance/linux_ssh_mips_malta.py
>  
>  Mipssim
>  M: Aleksandar Markovic <address@hidden>
> diff --git a/tests/acceptance/linux_ssh_mips_malta.py 
> b/tests/acceptance/linux_ssh_mips_malta.py
> new file mode 100644
> index 0000000000..aafb0c39f6
> --- /dev/null
> +++ b/tests/acceptance/linux_ssh_mips_malta.py
> @@ -0,0 +1,230 @@
> +# Functional test that boots a VM and run commands via a SSH session
> +#
> +# Copyright (c) Philippe Mathieu-Daudé <address@hidden>
> +#
> +# 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 re
> +import base64
> +import logging
> +import paramiko
> +import time
> +
> +from avocado import skipIf
> +from avocado_qemu import Test
> +from avocado.utils import process
> +from avocado.utils import archive
> +
> +
> +class LinuxSSH(Test):
> +
> +    timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
> +
> +    KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
> +    VM_IP = '127.0.0.1'
> +
> +    IMAGE_INFO = {
> +        'be': {
> +            'image_url': 'https://people.debian.org/~aurel32/qemu/mips/'
> +                         'debian_wheezy_mips_standard.qcow2',
> +            'image_hash': '8987a63270df67345b2135a6b7a4885a35e392d5',
> +            'rsa_hostkey': b'AAAAB3NzaC1yc2EAAAADAQABAAABAQCca1VitiyLAdQOld'
> +                           b'zT43IOEVJZ0wHD78GJi8wDAjMiYWUzNSSn0rXGQsINHuH5'
> +                           b'IlF+kBZsHinb/FtKCAyS9a8uCHhQI4SuB4QhAb0+39MlUw'
> +                           b'Mm0CLkctgM2eUUZ6MQMQvDlqnue6CCkxN62EZYbaxmby7j'
> +                           b'CQa1125o1HRKBvdGm2zrJWxXAfA+f1v6jHLyE8Jnu83eQ+'
> +                           b'BFY25G+Vzx1PVc3zQBwJ8r0NGTRqy2//oWQP0h+bMsgeFe'
> +                           b'KH/J3RJM22vg6+I4JAdBFcxnK+l781h1FuRxOn4O/Xslbg'
> +                           b'go6WtB4V4TOsw2E/KfxI5IZ/icxF+swVcnvF46Hf3uQc/0'
> +                           b'BBqb',
> +        },
> +        'le': {
> +            'image_url': 'https://people.debian.org/~aurel32/qemu/mipsel/'
> +                         'debian_wheezy_mipsel_standard.qcow2',
> +            'image_hash': '7866764d9de3ef536ffca24c9fb9f04ffdb45802',
> +            'rsa_hostkey': b'AAAAB3NzaC1yc2EAAAADAQABAAABAQClXJlBT71HL5yKvv'
> +                           b'gfC7jmxSWx5zSBCzET6CLZczwAafSIs7YKfNOy/dQTxhuk'
> +                           b'yIGFUugZFoF3E9PzdhunuyvyTd56MPoNIqFbb5rGokwU5I'
> +                           b'TOx3dBHZR0mClypL6MVrwe0bsiIb8GhF1zioNwcsaAZnAi'
> +                           b'KfXStVDtXvn/kLLq+xLABYt48CC5KYWoFaCoICskLAY+qo'
> +                           b'L+LWyAnQisj4jAH8VSaSKIImFpfkHWEXPhHcC4ZBlDKtnH'
> +                           b'po9vhfCHgnfW3Pzrqmk8BI4HysqPFVmJWkJGlGUL+sGeg3'
> +                           b'ZZolAYuDXGuBrw8ooPJq2v2dOH+z6dyD2q/ypmAbyPqj5C'
> +                           b'rc8H',
> +        },
> +    }
> +
> +    def wait_for_console_pattern(self, success_message,
> +                                 failure_message='Oops'):
> +        console = self.vm.console_socket.makefile()
> +        console_logger = logging.getLogger('console')
> +        while True:
> +            msg = console.readline()
> +            console_logger.debug(msg.strip())
> +            if success_message in msg:
> +                break
> +            if failure_message in msg:
> +                fail = 'Failure message found in console: %s' % 
> failure_message
> +                self.fail(fail)
> +
> +    def get_portfwd(self):
> +        res = self.vm.command('human-monitor-command',
> +                              command_line='info usernet')
> +        line = res.split('\r\n')[2]
> +        port = re.split(r'.*TCP.HOST_FORWARD.*127\.0\.0\.1 (\d+)\s+10\..*',
> +                        line)[1]
> +        self.log.debug("sshd listening on port:" + port)
> +        return port
> +
> +    def ssh_connect(self, username, password, rsa_hostkey_b64=None):
> +        self.ssh_logger = logging.getLogger('ssh')
> +        self.ssh_username = username
> +        self.ssh_ps1 = '# ' if username is 'root' else '$ '
> +        self.ssh_client = paramiko.SSHClient()
> +        port = self.get_portfwd()
> +        if rsa_hostkey_b64:
> +            rsa_hostkey_bin = base64.b64decode(rsa_hostkey_b64)
> +            rsa_hostkey = paramiko.RSAKey(data = rsa_hostkey_bin)
> +            ipport = '[%s]:%s' % (self.VM_IP, port)
> +            self.ssh_logger.debug('ipport ' + ipport)
> +            self.ssh_client.get_host_keys().add(ipport, 'ssh-rsa', 
> rsa_hostkey)
> +        for i in range(10):
> +            try:
> +                self.ssh_client.connect(self.VM_IP, int(port),
> +                                        username, password, 
> banner_timeout=90)
> +                self.ssh_logger.info("Entering interactive session.")
> +                return
> +            except:
> +                time.sleep(4)
> +                pass
> +        self.fail("sshd timeout")
> +
> +    def ssh_disconnect_vm(self):
> +        self.ssh_client.close()
> +
> +    def ssh_command(self, command, is_root=True):
> +        self.ssh_logger.info(self.ssh_ps1 + command)
> +        stdin, stdout, stderr = self.ssh_client.exec_command(command)
> +        stdout_lines = [line.strip('\n') for line in stdout]
> +        for line in stdout_lines:
> +            self.ssh_logger.info(line)
> +        stderr_lines = [line.strip('\n') for line in stderr]
> +        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 = self.IMAGE_INFO[endianess]['image_url']
> +        image_hash = self.IMAGE_INFO[endianess]['image_hash']
> +        image_path = self.fetch_asset(image_url, asset_hash=image_hash)
> +        rsa_hostkey_b64 = self.IMAGE_INFO[endianess]['rsa_hostkey']
> +
> +        self.vm.set_machine('malta')
> +        self.vm.set_console()
> +        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
> +                               + 'console=ttyS0 root=/dev/sda1')
> +        self.vm.add_args('-no-reboot',
> +                         '-kernel', kernel_path,
> +                         '-append', kernel_command_line,
> +                         '-hda', image_path,
> +                         '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
> +                         '-device', 'pcnet,netdev=vnet')
> +        self.vm.launch()
> +
> +        self.log.info('VM launched, waiting for sshd')
> +        console_pattern = 'Starting OpenBSD Secure Shell server: sshd'
> +        self.wait_for_console_pattern(console_pattern)
> +        self.log.info('sshd ready')
> +
> +        self.ssh_connect('root', 'root', rsa_hostkey_b64=rsa_hostkey_b64)
> +
> +    def shutdown_via_ssh(self):
> +        self.ssh_command('poweroff')
> +        self.ssh_disconnect_vm()
> +        self.wait_for_console_pattern('Power down')
> +
> +    def run_common_commands(self):
> +        stdout, stderr = self.ssh_command('lspci -d 11ab:4620')
> +        self.assertIn(True, ["GT-64120" in line for line in stdout])
> +
> +        stdout, stderr = self.ssh_command('cat 
> /sys/bus/i2c/devices/i2c-0/name')
> +        self.assertIn(True, ["SMBus PIIX4 adapter" in line
> +                             for line in stdout])
> +
> +        stdout, stderr = self.ssh_command('cat /proc/mtd')
> +        self.assertIn(True, ["YAMON" in line
> +                             for line in stdout])
> +
> +        # Empty 'Board Config'
> +        stdout, stderr = self.ssh_command('md5sum /dev/mtd2ro')
> +        self.assertIn(True, ["0dfbe8aa4c20b52e1b8bf3cb6cbdf193" in line
> +                             for line in stdout])
> +
> +    def do_test_mips_malta(self, endianess, kernel_path, uname_m):
> +        self.boot_debian_wheezy_image_and_ssh_login(endianess, kernel_path)
> +
> +        stdout, stderr = self.ssh_command('uname -a')
> +        self.assertIn(True, [uname_m + " GNU/Linux" in line for line in 
> stdout])
> +
> +        self.run_common_commands()
> +        self.shutdown_via_ssh()
> +
> +    @skipIf(os.getenv('CONTINUOUS_INTEGRATION'), 'Running on Travis-CI')
> +    def test_mips_malta32eb_kernel3_2_0(self):
> +        """
> +        :avocado: tags=arch:mips
> +        :avocado: tags=machine:malta
> +        :avocado: tags=endian:big
> +        :avocado: tags=device:pcnet32
> +        """
> +        kernel_url = ('https://people.debian.org/~aurel32/qemu/mips/'
> +                      'vmlinux-3.2.0-4-4kc-malta')
> +        kernel_hash = '592e384a4edc16dade52a6cd5c785c637bcbc9ad'
> +        kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
> +
> +        self.do_test_mips_malta('be', kernel_path, 'mips')
> +
> +    @skipIf(os.getenv('CONTINUOUS_INTEGRATION'), 'Running on Travis-CI')
> +    def test_mips_malta32el_kernel3_2_0(self):
> +        """
> +        :avocado: tags=arch:mipsel
> +        :avocado: tags=machine:malta
> +        :avocado: tags=endian:little
> +        :avocado: tags=device:pcnet32
> +        """
> +        kernel_url = ('https://people.debian.org/~aurel32/qemu/mipsel/'
> +                      'vmlinux-3.2.0-4-4kc-malta')
> +        kernel_hash = 'a66bea5a8adaa2cb3d36a1d4e0ccdb01be8f6c2a'
> +        kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
> +
> +        self.do_test_mips_malta('le', kernel_path, 'mips')
> +
> +    @skipIf(os.getenv('CONTINUOUS_INTEGRATION'), 'Running on Travis-CI')
> +    def test_mips_malta64eb_kernel3_2_0(self):
> +        """
> +        :avocado: tags=arch:mips64
> +        :avocado: tags=machine:malta
> +        :avocado: tags=endian:big
> +        :avocado: tags=device:pcnet32
> +        """
> +        kernel_url = ('https://people.debian.org/~aurel32/qemu/mips/'
> +                      'vmlinux-3.2.0-4-5kc-malta')
> +        kernel_hash = 'db6eea7de35d36c77d8c165b6bcb222e16eb91db'
> +        kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
> +        self.do_test_mips_malta('be', kernel_path, 'mips64')
> +
> +    @skipIf(os.getenv('CONTINUOUS_INTEGRATION'), 'Running on Travis-CI')
> +    def test_mips_malta64el_kernel3_2_0(self):
> +        """
> +        :avocado: tags=arch:mips64el
> +        :avocado: tags=machine:malta
> +        :avocado: tags=endian:little
> +        :avocado: tags=device:pcnet32
> +        """
> +        kernel_url = ('https://people.debian.org/~aurel32/qemu/mipsel/'
> +                      'vmlinux-3.2.0-4-5kc-malta')
> +        kernel_hash = '6a7f77245acf231415a0e8b725d91ed2f3487794'
> +        kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
> +        self.do_test_mips_malta('le', kernel_path, 'mips64')
> diff --git a/tests/requirements.txt b/tests/requirements.txt
> index 002ded6a22..3ae0e29ad7 100644
> --- a/tests/requirements.txt
> +++ b/tests/requirements.txt
> @@ -2,3 +2,4 @@
>  # in the tests/venv Python virtual environment. For more info,
>  # refer to: https://pip.pypa.io/en/stable/user_guide/#id1
>  avocado-framework==68.0
> +paramiko
> -- 
> 2.19.1
> 

-- 
Eduardo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]