python-next patches for 2020-05-31
The following changes since commit c86274bc2e34295764fb44c2aef3cf29623f9b4b:
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-tcg-plugins=
-270520-1' into staging (2020-05-29 17:41:45 +0100)
are available in the Git repository at:
https://gitlab.com/philmd/qemu.git tags/python-next-20200531
for you to fetch changes up to 1c80c87c8c2489e4318c93c844aa29bc1d014146:
tests/acceptance: refactor boot_linux to allow code reuse (2020-05-31 18:25=
:31 +0200)
----------------------------------------------------------------
Python queue:
* migration acceptance test fix
* introduce pylintrc & flake8 config
* various cleanups (Python3, style)
* vm-test can set QEMU_LOCAL=3D1 to use locally built binaries
* refactored BootLinuxBase & LinuxKernelTest acceptance classes
https://gitlab.com/philmd/qemu/pipelines/151323210
https://travis-ci.org/github/philmd/qemu/builds/693157969
----------------------------------------------------------------
Dr. David Alan Gilbert (1):
tests/acceptance/migration.py: Wait for both sides
John Snow (11):
scripts/qmp: Fix shebang and imports
python: remove more instances of sys.version_info python/qemu/machine: remove logging configuration python/qemu: delint and add pylintrc python/qemu: delint; add flake8 config python/qemu: remove Python2 style super() calls python/qemu: fix socket.makefile() typing python/qemu: Adjust traceback typing python/qemu/qmp: use True/False for non/blocking modes python/qemu/qmp: assert sockfile is not None python/qemu/qtest: Check before accessing _qtest
Pavel Dovgaluk (3):
tests/acceptance: allow console interaction with specific VMs tests/acceptance: refactor boot_linux_console test to allow code reuse tests/acceptance: refactor boot_linux to allow code reuse
Philippe Mathieu-Daud=C3=A9 (6):
scripts/qemugdb: Remove shebang header scripts/qemu-gdb: Use Python 3 interpreter
scripts/qmp: Use Python 3 interpreter scripts/kvm/vmxcap: Use Python 3 interpreter and add pseudo-main() scripts/modules/module_block: Use Python 3 interpreter & add
pseudo-main
tests/migration/guestperf: Use Python 3 interpreter
Robert Foley (3):
tests/vm: Pass --debug through for vm-boot-ssh tests/vm: Add ability to select QEMU from current build tests/vm: allow wait_ssh() to specify command
Vladimir Sementsov-Ogievskiy (1):
python/qemu/machine: add kill() method
python/qemu/.flake8 | 2 + python/qemu/accel.py | 9 ++- python/qemu/machine.py | 44 +++++++----- python/qemu/pylintrc | 58 ++++++++++++++++ python/qemu/qmp.py | 29 +++++--- python/qemu/qtest.py | 83 +++++++++++++++-------- scripts/analyze-migration.py | 5 -- scripts/decodetree.py | 25 +++---- scripts/kvm/vmxcap | 7 +- scripts/modules/module_block.py | 29 ++++---- scripts/qemu-gdb.py | 4 +- scripts/qemugdb/__init__.py | 3 +- scripts/qemugdb/aio.py | 3 +- scripts/qemugdb/coroutine.py | 3 +- scripts/qemugdb/mtree.py | 4 +- scripts/qemugdb/tcg.py | 1 - scripts/qemugdb/timers.py | 1 - scripts/qmp/qmp | 4 +- scripts/qmp/qmp-shell | 3 - scripts/qmp/qom-fuse | 4 +- scripts/qmp/qom-get | 6 +- scripts/qmp/qom-list | 6 +- scripts/qmp/qom-set | 6 +- scripts/qmp/qom-tree | 6 +- tests/acceptance/avocado_qemu/__init__.py | 13 ++-- tests/acceptance/boot_linux.py | 49 +++++++------ tests/acceptance/boot_linux_console.py | 21 +++--- tests/acceptance/migration.py | 4 ++ tests/docker/docker.py | 5 +- tests/migration/guestperf-batch.py | 2 +- tests/migration/guestperf-plot.py | 2 +- tests/migration/guestperf.py | 2 +- tests/qemu-iotests/nbd-fault-injector.py | 5 +- tests/vm/Makefile.include | 5 ++ tests/vm/basevm.py | 42 ++++++++---- 35 files changed, 317 insertions(+), 178 deletions(-) create mode 100644 python/qemu/.flake8 create mode 100644 python/qemu/pylintrc
--=20
2.21.3
[PULL 01/25] scripts/qemugdb: Remove shebang header
From: Philippe Mathieu-Daudé <[email protected]>
These scripts are loaded as plugin by GDB (and they don't have any __main__ entry point). Remove the shebang header.
Message-Id: <[email protected]>
--- scripts/qemugdb/__init__.py | 3 +-- scripts/qemugdb/aio.py | 3 +-- scripts/qemugdb/coroutine.py | 3 +-- scripts/qemugdb/mtree.py | 4 +--- scripts/qemugdb/tcg.py | 1 - scripts/qemugdb/timers.py | 1 - 6 files changed, 4 insertions(+), 11 deletions(-)
scripts/qemugdb/__init__.py +1 -2
@@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support # # Copyright (c) 2015 Linaro Ltd
scripts/qemugdb/aio.py +1 -2
@@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support: aio/iohandler debug # # Copyright (c) 2015 Red Hat, Inc.
scripts/qemugdb/coroutine.py +1 -2
@@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support # # Copyright 2012 Red Hat, Inc. and/or its affiliates
scripts/qemugdb/mtree.py +1 -3
@@ -1,5 +1,4 @@ -#!/usr/bin/python - +# # GDB debugging support # # Copyright 2012 Red Hat, Inc. and/or its affiliates
@@ -84,4 +83,3 @@ def print_item(self, ptr, offset = gdb.Value(0), level = 0): while not isnull(subregion): self.print_item(subregion, addr, level) subregion = subregion['subregions_link']['tqe_next'] -
scripts/qemugdb/tcg.py +0 -1
@@ -1,4 +1,3 @@ -#!/usr/bin/python # -*- coding: utf-8 -*- # # GDB debugging support, TCG status
scripts/qemugdb/timers.py +0 -1
@@ -1,4 +1,3 @@ -#!/usr/bin/python # -*- coding: utf-8 -*- # GDB debugging support #
Signature · 1 line
2.21.3
[PULL 02/25] scripts/qemu-gdb: Use Python 3 interpreter
In reply to Philippe Mathieu-DaudéFrom: Philippe Mathieu-Daudé <[email protected]>
Message-Id: <[email protected]>
--- scripts/qemu-gdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
scripts/qemu-gdb.py +2 -2
@@ -1,5 +1,5 @@ -#!/usr/bin/python - +#!/usr/bin/env python3 +# # GDB debugging support # # Copyright 2012 Red Hat, Inc. and/or its affiliates
Signature · 1 line
2.21.3
[PULL 03/25] scripts/qmp: Use Python 3 interpreter
In reply to Philippe Mathieu-DaudéFrom: Philippe Mathieu-Daudé <[email protected]>
Message-Id: <[email protected]>
--- scripts/qmp/qom-get | 2 +- scripts/qmp/qom-list | 2 +- scripts/qmp/qom-set | 2 +- scripts/qmp/qom-tree | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
scripts/qmp/qom-get +1 -1
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools #
scripts/qmp/qom-list +1 -1
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools #
scripts/qmp/qom-set +1 -1
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools #
scripts/qmp/qom-tree +1 -1
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 ## # QEMU Object Model test tools #
Signature · 1 line
2.21.3
[PULL 04/25] scripts/kvm/vmxcap: Use Python 3 interpreter and add pseudo-main()
In reply to Philippe Mathieu-DaudéMessage-Id: <[email protected]>
--- scripts/kvm/vmxcap | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
scripts/kvm/vmxcap +4 -3
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # tool for querying VMX capabilities #
@@ -275,5 +275,6 @@ controls = [ ), ] -for c in controls: - c.show() +if __name__ == '__main__': + for c in controls: + c.show()
Signature · 1 line
2.21.3
[PULL 05/25] scripts/modules/module_block: Use Python 3 interpreter & add pseudo-main
In reply to Philippe Mathieu-DaudéMessage-Id: <[email protected]>
--- scripts/modules/module_block.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-)
scripts/modules/module_block.py +15 -14
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # Module information generator #
@@ -80,19 +80,20 @@ def print_bottom(fheader): #endif ''') -# First argument: output file -# All other arguments: modules source files (.c) -output_file = sys.argv[1] -with open(output_file, 'w') as fheader: - print_top(fheader) +if __name__ == '__main__': + # First argument: output file + # All other arguments: modules source files (.c) + output_file = sys.argv[1] + with open(output_file, 'w') as fheader: + print_top(fheader) - for filename in sys.argv[2:]: - if os.path.isfile(filename): - process_file(fheader, filename) - else: - print("File " + filename + " does not exist.", file=sys.stderr) - sys.exit(1) + for filename in sys.argv[2:]: + if os.path.isfile(filename): + process_file(fheader, filename) + else: + print("File " + filename + " does not exist.", file=sys.stderr) + sys.exit(1) - print_bottom(fheader) + print_bottom(fheader) -sys.exit(0) + sys.exit(0)
Signature · 1 line
2.21.3
[PULL 06/25] scripts/qmp: Fix shebang and imports
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
There's more wrong with these scripts; They are in various stages of disrepair. That's beyond the scope of this current patchset.
This just mechanically corrects the imports and the shebangs, as part of ensuring that the python/qemu/lib refactoring didn't break anything needlessly.
Message-Id: <[email protected]>
--- scripts/qmp/qmp | 4 +++- scripts/qmp/qom-fuse | 4 +++- scripts/qmp/qom-get | 4 +++- scripts/qmp/qom-list | 4 +++- scripts/qmp/qom-set | 4 +++- scripts/qmp/qom-tree | 4 +++- 6 files changed, 18 insertions(+), 6 deletions(-)
scripts/qmp/qmp +3 -1
@@ -11,7 +11,9 @@ # See the COPYING file in the top-level directory. import sys, os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol def print_response(rsp, prefix=[]): if type(rsp) == list:
scripts/qmp/qom-fuse +3 -1
@@ -15,7 +15,9 @@ import fuse, stat from fuse import Fuse import os, posix from errno import * -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol fuse.fuse_python_api = (0, 2)
scripts/qmp/qom-get +3 -1
@@ -13,7 +13,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None
scripts/qmp/qom-list +3 -1
@@ -13,7 +13,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None
scripts/qmp/qom-set +3 -1
@@ -13,7 +13,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None
scripts/qmp/qom-tree +3 -1
@@ -15,7 +15,9 @@ import sys import os -from qmp import QEMUMonitorProtocol + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) +from qemu.qmp import QEMUMonitorProtocol cmd, args = sys.argv[0], sys.argv[1:] socket_path = None
Signature · 1 line
2.21.3
[PULL 07/25] python: remove more instances of sys.version_info
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
We guarantee 3.5+ everywhere; remove more dead checks. In general, try to avoid using version checks and instead prefer to attempt behavior when possible.
Message-Id: <[email protected]>
--- scripts/analyze-migration.py | 5 ----- scripts/decodetree.py | 25 +++++++++--------------- scripts/qmp/qmp-shell | 3 --- tests/docker/docker.py | 5 +++-- tests/qemu-iotests/nbd-fault-injector.py | 5 +---- 5 files changed, 13 insertions(+), 30 deletions(-)
scripts/analyze-migration.py +0 -5
@@ -25,11 +25,6 @@ import sys -MIN_PYTHON = (3, 2) -if sys.version_info < MIN_PYTHON: - sys.exit("Python %s.%s or later is required.\n" % MIN_PYTHON) - - def mkdir_p(path): try: os.makedirs(path)
scripts/decodetree.py +9 -16
@@ -75,13 +75,6 @@ def output(*args): output_fd.write(a) -if sys.version_info >= (3, 4): - re_fullmatch = re.fullmatch -else: - def re_fullmatch(pat, str): - return re.match('^' + pat + '$', str) - - def output_autogen(): output('/* This file is autogenerated by scripts/decodetree.py. */\n\n')
@@ -428,18 +421,18 @@ def parse_field(lineno, name, toks): width = 0 func = None for t in toks: - if re_fullmatch('!function=' + re_ident, t): + if re.fullmatch('!function=' + re_ident, t): if func: error(lineno, 'duplicate function') func = t.split('=') func = func[1] continue - if re_fullmatch('[0-9]+:s[0-9]+', t): + if re.fullmatch('[0-9]+:s[0-9]+', t): # Signed field extract subtoks = t.split(':s') sign = True - elif re_fullmatch('[0-9]+:[0-9]+', t): + elif re.fullmatch('[0-9]+:[0-9]+', t): # Unsigned field extract subtoks = t.split(':') sign = False
@@ -488,11 +481,11 @@ def parse_arguments(lineno, name, toks): flds = [] extern = False for t in toks: - if re_fullmatch('!extern', t): + if re.fullmatch('!extern', t): extern = True anyextern = True continue - if not re_fullmatch(re_ident, t): + if not re.fullmatch(re_ident, t): error(lineno, 'invalid argument set token "{0}"'.format(t)) if t in flds: error(lineno, 'duplicate argument "{0}"'.format(t))
@@ -621,13 +614,13 @@ def parse_generic(lineno, is_format, name, toks): continue # 'Foo=%Bar' imports a field with a different name. - if re_fullmatch(re_ident + '=%' + re_ident, t): + if re.fullmatch(re_ident + '=%' + re_ident, t): (fname, iname) = t.split('=%') flds = add_field_byname(lineno, flds, fname, iname) continue # 'Foo=number' sets an argument field to a constant value - if re_fullmatch(re_ident + '=[+-]?[0-9]+', t): + if re.fullmatch(re_ident + '=[+-]?[0-9]+', t): (fname, value) = t.split('=') value = int(value) flds = add_field(lineno, flds, fname, ConstField(value))
@@ -635,7 +628,7 @@ def parse_generic(lineno, is_format, name, toks): # Pattern of 0s, 1s, dots and dashes indicate required zeros, # required ones, or dont-cares. - if re_fullmatch('[01.-]+', t): + if re.fullmatch('[01.-]+', t): shift = len(t) fms = t.replace('0', '1') fms = fms.replace('.', '0')
@@ -652,7 +645,7 @@ def parse_generic(lineno, is_format, name, toks): fixedmask = (fixedmask << shift) | fms undefmask = (undefmask << shift) | ubm # Otherwise, fieldname:fieldwidth - elif re_fullmatch(re_ident + ':s?[0-9]+', t): + elif re.fullmatch(re_ident + ':s?[0-9]+', t): (fname, flen) = t.split(':') sign = False if flen[0] == 's':
scripts/qmp/qmp-shell +0 -3
@@ -77,9 +77,6 @@ import re sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python')) from qemu import qmp -if sys.version_info[0] == 2: - input = raw_input - class QMPCompleter(list): def complete(self, text, state): for cmd in self:
tests/docker/docker.py +3 -2
@@ -258,12 +258,13 @@ def _kill_instances(self, *args, **kwargs): return self._do_kill_instances(True) def _output(self, cmd, **kwargs): - if sys.version_info[1] >= 6: + try: return subprocess.check_output(self._command + cmd, stderr=subprocess.STDOUT, encoding='utf-8', **kwargs) - else: + except TypeError: + # 'encoding' argument was added in 3.6+ return subprocess.check_output(self._command + cmd, stderr=subprocess.STDOUT, **kwargs).decode('utf-8')
tests/qemu-iotests/nbd-fault-injector.py +1 -4
@@ -47,10 +47,7 @@ import socket import struct import collections -if sys.version_info.major >= 3: - import configparser -else: - import ConfigParser as configparser +import configparser FAKE_DISK_SIZE = 8 * 1024 * 1024 * 1024 # 8 GB
Signature · 1 line
2.21.3
[PULL 08/25] python/qemu/machine: add kill() method
In reply to Philippe Mathieu-DaudéFrom: Vladimir Sementsov-Ogievskiy <[email protected]>
Add method to hard-kill vm, without any quit commands.
Message-Id: <[email protected]>
--- python/qemu/machine.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
python/qemu/machine.py +9 -3
@@ -342,7 +342,7 @@ def wait(self): self._load_io_log() self._post_shutdown() - def shutdown(self, has_quit=False): + def shutdown(self, has_quit=False, hard=False): """ Terminate the VM and clean up """
@@ -354,7 +354,9 @@ def shutdown(self, has_quit=False): self._console_socket = None if self.is_running(): - if self._qmp: + if hard: + self._popen.kill() + elif self._qmp: try: if not has_quit: self._qmp.cmd('quit')
@@ -368,7 +370,8 @@ def shutdown(self, has_quit=False): self._post_shutdown() exitcode = self.exitcode() - if exitcode is not None and exitcode < 0: + if exitcode is not None and exitcode < 0 and \ + not (exitcode == -9 and hard): msg = 'qemu received signal %i: %s' if self._qemu_full_args: command = ' '.join(self._qemu_full_args)
@@ -378,6 +381,9 @@ def shutdown(self, has_quit=False): self._launched = False + def kill(self): + self.shutdown(hard=True) + def set_qmp_monitor(self, enabled=True): """ Set the QMP monitor.
Signature · 1 line
2.21.3
[PULL 09/25] python/qemu/machine: remove logging configuration
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
Python 3.5 and above do not print a warning when logging is not configured. As a library, it's best practice to leave logging configuration to the client executable.
Message-Id: <[email protected]>
--- python/qemu/machine.py | 3 --- 1 file changed, 3 deletions(-)
python/qemu/machine.py +0 -3
@@ -119,9 +119,6 @@ def __init__(self, binary, args=None, wrapper=None, name=None, self._console_socket = None self._remove_files = [] - # just in case logging wasn't configured by the main script: - logging.basicConfig() - def __enter__(self): return self
Signature · 1 line
2.21.3
[PULL 10/25] python/qemu: delint and add pylintrc
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
Bring our these files up to speed with pylint 2.5.0. Add a pylintrc file to formalize which pylint subset we are targeting.
The similarity ignore is there to suppress similarity reports across imports, which for typing constants, are going to trigger this report erroneously.
Message-Id: <[email protected]>
--- python/qemu/machine.py | 6 ++--- python/qemu/pylintrc | 58 ++++++++++++++++++++++++++++++++++++++++++ python/qemu/qtest.py | 42 +++++++++++++++++++----------- 3 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 python/qemu/pylintrc
python/qemu/machine.py +3 -3
@@ -58,7 +58,7 @@ def __init__(self, reply): self.reply = reply -class QEMUMachine(object): +class QEMUMachine: """ A QEMU VM
@@ -239,7 +239,7 @@ def _base_args(self): 'chardev=mon,mode=control']) if self._machine is not None: args.extend(['-machine', self._machine]) - for i in range(self._console_index): + for _ in range(self._console_index): args.extend(['-serial', 'null']) if self._console_set: self._console_address = os.path.join(self._sock_dir,
@@ -374,7 +374,7 @@ def shutdown(self, has_quit=False, hard=False): command = ' '.join(self._qemu_full_args) else: command = '' - LOG.warning(msg, -exitcode, command) + LOG.warning(msg, -int(exitcode), command) self._launched = False
python/qemu/pylintrc new file +58 -0
58 lines not on this page · raw message
python/qemu/qtest.py +27 -15
66 lines not on this page · raw message
Signature · 1 line
2.21.3
[PULL 11/25] python/qemu: delint; add flake8 config
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
Mostly, ignore the "no bare except" rule, because flake8 is not contextual and cannot determine if we re-raise. Pylint can, though, so always prefer pylint for that.
Message-Id: <[email protected]>
--- python/qemu/.flake8 | 2 ++ python/qemu/accel.py | 9 ++++++--- python/qemu/machine.py | 13 +++++++++---- python/qemu/qmp.py | 4 ++-- 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 python/qemu/.flake8
python/qemu/.flake8 new file +2 -0
@@ -0,0 +1,2 @@ +[flake8] +extend-ignore = E722 # Pylint handles this, but smarter.
python/qemu/accel.py +6 -3
@@ -23,11 +23,12 @@ # Mapping host architecture to any additional architectures it can # support which often includes its 32 bit cousin. ADDITIONAL_ARCHES = { - "x86_64" : "i386", - "aarch64" : "armhf", - "ppc64le" : "ppc64", + "x86_64": "i386", + "aarch64": "armhf", + "ppc64le": "ppc64", } + def list_accel(qemu_bin): """ List accelerators enabled in the QEMU binary.
@@ -47,6 +48,7 @@ def list_accel(qemu_bin): # Skip the first line which is the header. return [acc.strip() for acc in out.splitlines()[1:]] + def kvm_available(target_arch=None, qemu_bin=None): """ Check if KVM is available using the following heuristic:
@@ -69,6 +71,7 @@ def kvm_available(target_arch=None, qemu_bin=None): return False return True + def tcg_available(qemu_bin): """ Check if TCG is available.
python/qemu/machine.py +9 -4
@@ -29,6 +29,7 @@ LOG = logging.getLogger(__name__) + class QEMUMachineError(Exception): """ Exception called when an error in QEMUMachine happens.
@@ -62,7 +63,8 @@ class QEMUMachine: """ A QEMU VM - Use this object as a context manager to ensure the QEMU process terminates:: + Use this object as a context manager to ensure + the QEMU process terminates:: with VM(binary) as vm: ...
@@ -185,8 +187,10 @@ def send_fd_scm(self, fd=None, file_path=None): fd_param.append(str(fd)) devnull = open(os.path.devnull, 'rb') - proc = subprocess.Popen(fd_param, stdin=devnull, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, close_fds=False) + proc = subprocess.Popen( + fd_param, stdin=devnull, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, close_fds=False + ) output = proc.communicate()[0] if output: LOG.debug(output)
@@ -485,7 +489,8 @@ def event_wait(self, name, timeout=60.0, match=None): def events_wait(self, events, timeout=60.0): """ - events_wait waits for and returns a named event from QMP with a timeout. + events_wait waits for and returns a named event + from QMP with a timeout. events: a sequence of (name, match_criteria) tuples. The match criteria are optional and may be None.
python/qemu/qmp.py +2 -2
@@ -168,8 +168,8 @@ def accept(self, timeout=15.0): @param timeout: timeout in seconds (nonnegative float number, or None). The value passed will set the behavior of the - underneath QMP socket as described in [1]. Default value - is set to 15.0. + underneath QMP socket as described in [1]. + Default value is set to 15.0. @return QMP greeting dict @raise OSError on socket connection errors @raise QMPConnectError if the greeting is not received
Signature · 1 line
2.21.3
[PULL 12/25] python/qemu: remove Python2 style super() calls
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
Use the Python3 style instead.
Message-Id: <[email protected]>
--- python/qemu/machine.py | 2 +- python/qemu/qtest.py | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-)
python/qemu/machine.py +1 -1
@@ -55,7 +55,7 @@ def __init__(self, reply): desc = reply["error"]["desc"] except KeyError: desc = reply - super(MonitorResponseError, self).__init__(desc) + super().__init__(desc) self.reply = reply
python/qemu/qtest.py +7 -8
@@ -101,29 +101,28 @@ def __init__(self, binary, args=None, name=None, test_dir="/var/tmp", name = "qemu-%d" % os.getpid() if sock_dir is None: sock_dir = test_dir - super(QEMUQtestMachine, - self).__init__(binary, args, name=name, test_dir=test_dir, - socket_scm_helper=socket_scm_helper, - sock_dir=sock_dir) + super().__init__(binary, args, name=name, test_dir=test_dir, + socket_scm_helper=socket_scm_helper, + sock_dir=sock_dir) self._qtest = None self._qtest_path = os.path.join(sock_dir, name + "-qtest.sock") def _base_args(self): - args = super(QEMUQtestMachine, self)._base_args() + args = super()._base_args() args.extend(['-qtest', 'unix:path=' + self._qtest_path, '-accel', 'qtest']) return args def _pre_launch(self): - super(QEMUQtestMachine, self)._pre_launch() + super()._pre_launch() self._qtest = QEMUQtestProtocol(self._qtest_path, server=True) def _post_launch(self): - super(QEMUQtestMachine, self)._post_launch() + super()._post_launch() self._qtest.accept() def _post_shutdown(self): - super(QEMUQtestMachine, self)._post_shutdown() + super()._post_shutdown() self._remove_if_exists(self._qtest_path) def qtest(self, cmd):
Signature · 1 line
2.21.3
[PULL 13/25] python/qemu: fix socket.makefile() typing
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
Note:
A bug in typeshed (https://github.com/python/typeshed/issues/3977)
misinterprets the type of makefile(). Work around this by explicitly stating that we are opening a text-mode file.
Message-Id: <[email protected]>
--- python/qemu/qmp.py | 10 +++++++--- python/qemu/qtest.py | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-)
python/qemu/qmp.py +7 -3
@@ -11,6 +11,10 @@ import errno import socket import logging +from typing import ( + Optional, + TextIO, +) class QMPError(Exception):
@@ -61,7 +65,7 @@ def __init__(self, address, server=False, nickname=None): self.__events = [] self.__address = address self.__sock = self.__get_sock() - self.__sockfile = None + self.__sockfile: Optional[TextIO] = None self._nickname = nickname if self._nickname: self.logger = logging.getLogger('QMP').getChild(self._nickname)
@@ -157,7 +161,7 @@ def connect(self, negotiate=True): @raise QMPCapabilitiesError if fails to negotiate capabilities """ self.__sock.connect(self.__address) - self.__sockfile = self.__sock.makefile() + self.__sockfile = self.__sock.makefile(mode='r') if negotiate: return self.__negotiate_capabilities() return None
@@ -180,7 +184,7 @@ def accept(self, timeout=15.0): """ self.__sock.settimeout(timeout) self.__sock, _ = self.__sock.accept() - self.__sockfile = self.__sock.makefile() + self.__sockfile = self.__sock.makefile(mode='r') return self.__negotiate_capabilities() def cmd_obj(self, qmp_cmd):
python/qemu/qtest.py +8 -4
@@ -19,6 +19,7 @@ import socket import os +from typing import Optional, TextIO from .machine import QEMUMachine
@@ -40,7 +41,7 @@ class QEMUQtestProtocol: def __init__(self, address, server=False): self._address = address self._sock = self._get_sock() - self._sockfile = None + self._sockfile: Optional[TextIO] = None if server: self._sock.bind(self._address) self._sock.listen(1)
@@ -59,7 +60,7 @@ def connect(self): @raise socket.error on socket connection errors """ self._sock.connect(self._address) - self._sockfile = self._sock.makefile() + self._sockfile = self._sock.makefile(mode='r') def accept(self): """
@@ -68,7 +69,7 @@ def accept(self): @raise socket.error on socket connection errors """ self._sock, _ = self._sock.accept() - self._sockfile = self._sock.makefile() + self._sockfile = self._sock.makefile(mode='r') def cmd(self, qtest_cmd): """
@@ -76,6 +77,7 @@ def cmd(self, qtest_cmd): @param qtest_cmd: qtest command text to be sent """ + assert self._sockfile is not None self._sock.sendall((qtest_cmd + "\n").encode('utf-8')) resp = self._sockfile.readline() return resp
@@ -83,7 +85,9 @@ def cmd(self, qtest_cmd): def close(self): """Close this socket.""" self._sock.close() - self._sockfile.close() + if self._sockfile: + self._sockfile.close() + self._sockfile = None def settimeout(self, timeout): """Set a timeout, in seconds."""
Signature · 1 line
2.21.3
[PULL 14/25] python/qemu: Adjust traceback typing
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
mypy considers it incorrect to use bool to statically return false, because it will assume that it could conceivably return True, and gives different analysis in that case. Use a None return to achieve the same effect, but make mypy happy.
Note: Pylint considers function signatures as code that might trip the duplicate-code checker. I'd rather not disable this as it does not trigger often in practice, so I'm disabling it as a one-off and filed a change request; see https://github.com/PyCQA/pylint/issues/3619
Message-Id: <[email protected]>
--- python/qemu/machine.py | 8 ++++++-- python/qemu/qmp.py | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-)
python/qemu/machine.py +6 -2
@@ -24,6 +24,8 @@ import shutil import socket import tempfile +from typing import Optional, Type +from types import TracebackType from . import qmp
@@ -124,9 +126,11 @@ def __init__(self, binary, args=None, wrapper=None, name=None, def __enter__(self): return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: self.shutdown() - return False def add_monitor_null(self): """
python/qemu/qmp.py +8 -2
@@ -14,7 +14,9 @@ from typing import ( Optional, TextIO, + Type, ) +from types import TracebackType class QMPError(Exception):
@@ -146,10 +148,14 @@ def __enter__(self): # Implement context manager enter function. return self - def __exit__(self, exc_type, exc_value, exc_traceback): + def __exit__(self, + # pylint: disable=duplicate-code + # see https://github.com/PyCQA/pylint/issues/3619 + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType]) -> None: # Implement context manager exit function. self.close() - return False def connect(self, negotiate=True): """
Signature · 1 line
2.21.3
[PULL 15/25] python/qemu/qmp: use True/False for non/blocking modes
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
The type system doesn't want integers.
Message-Id: <[email protected]>
--- python/qemu/qmp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
python/qemu/qmp.py +2 -2
@@ -120,14 +120,14 @@ def __get_events(self, wait=False): """ # Check for new events regardless and pull them into the cache: - self.__sock.setblocking(0) + self.__sock.setblocking(False) try: self.__json_read() except OSError as err: if err.errno == errno.EAGAIN: # No data available pass - self.__sock.setblocking(1) + self.__sock.setblocking(True) # Wait for new events, if needed. # if wait is 0.0, this means "no wait" and is also implicitly false.
Signature · 1 line
2.21.3
[PULL 16/25] python/qemu/qmp: assert sockfile is not None
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
In truth, if you don't do this, you'll just get a TypeError exception. Now, you'll get an AssertionError.
Is this tangibly better? No.
Does mypy complain less? Yes.
Message-Id: <[email protected]>
--- python/qemu/qmp.py | 1 + 1 file changed, 1 insertion(+)
python/qemu/qmp.py +1 -0
@@ -94,6 +94,7 @@ def __negotiate_capabilities(self): raise QMPCapabilitiesError def __json_read(self, only_event=False): + assert self.__sockfile is not None while True: data = self.__sockfile.readline() if not data:
Signature · 1 line
2.21.3
[PULL 17/25] python/qemu/qtest: Check before accessing _qtest
In reply to Philippe Mathieu-DaudéFrom: John Snow <[email protected]>
It can be None; so add assertions or exceptions where appropriate to guard the access accordingly.
Message-Id: <[email protected]>
--- python/qemu/qtest.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
python/qemu/qtest.py +11 -3
@@ -121,7 +121,8 @@ def _pre_launch(self): super()._pre_launch() self._qtest = QEMUQtestProtocol(self._qtest_path, server=True) - def _post_launch(self): + def _post_launch(self) -> None: + assert self._qtest is not None super()._post_launch() self._qtest.accept()
@@ -129,6 +130,13 @@ def _post_shutdown(self): super()._post_shutdown() self._remove_if_exists(self._qtest_path) - def qtest(self, cmd): - '''Send a qtest command to guest''' + def qtest(self, cmd: str) -> str: + """ + Send a qtest command to the guest. + + :param cmd: qtest command to send + :return: qtest server response + """ + if self._qtest is None: + raise RuntimeError("qtest socket not available") return self._qtest.cmd(cmd)
Signature · 1 line
2.21.3
[PULL 18/25] tests/vm: Pass --debug through for vm-boot-ssh
In reply to Philippe Mathieu-DaudéFrom: Robert Foley <[email protected]>
This helps debug issues that occur during the boot sequence.
Message-Id: <[email protected]>
--- tests/vm/Makefile.include | 1 + 1 file changed, 1 insertion(+)
tests/vm/Makefile.include +1 -0
@@ -91,6 +91,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img $(call quiet-command, \ $(PYTHON) $(SRC_PATH)/tests/vm/$* \ $(if $(J),--jobs $(J)) \ + $(if $(V)$(DEBUG), --debug) \ --image "$<" \ --interactive \ false, \
Signature · 1 line
2.21.3
[PULL 19/25] tests/vm: Add ability to select QEMU from current build
In reply to Philippe Mathieu-DaudéFrom: Robert Foley <[email protected]>
Added a new special variable QEMU_LOCAL=1, which will indicate to take the QEMU binary from the current build.
Message-Id: <[email protected]>
--- tests/vm/Makefile.include | 4 ++++ tests/vm/basevm.py | 28 +++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-)
tests/vm/Makefile.include +4 -0
@@ -41,6 +41,7 @@ endif @echo " J=[0..9]* - Override the -jN parameter for make commands" @echo " DEBUG=1 - Enable verbose output on host and interactive debugging" @echo " V=1 - Enable verbose ouput on host and guest commands" + @echo " QEMU_LOCAL=1 - Use QEMU binary local to this build." @echo " QEMU=/path/to/qemu - Change path to QEMU binary" @echo " QEMU_IMG=/path/to/qemu-img - Change path to qemu-img tool"
@@ -57,6 +58,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \ $(PYTHON) $< \ $(if $(V)$(DEBUG), --debug) \ $(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \ + $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \ --image "$@" \ --force \ --build-image $@, \
@@ -71,6 +73,7 @@ vm-build-%: $(IMAGES_DIR)/%.img $(if $(DEBUG), --interactive) \ $(if $(J),--jobs $(J)) \ $(if $(V),--verbose) \ + $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \ --image "$<" \ $(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \ --snapshot \
@@ -92,6 +95,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img $(PYTHON) $(SRC_PATH)/tests/vm/$* \ $(if $(J),--jobs $(J)) \ $(if $(V)$(DEBUG), --debug) \ + $(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \ --image "$<" \ --interactive \ false, \
tests/vm/basevm.py +23 -5
@@ -61,9 +61,11 @@ class BaseVM(object): # 4 is arbitrary, but greater than 2, # since we found we need to wait more than twice as long. tcg_ssh_timeout_multiplier = 4 - def __init__(self, debug=False, vcpus=None, genisoimage=None): + def __init__(self, debug=False, vcpus=None, genisoimage=None, + build_path=None): self._guest = None self._genisoimage = genisoimage + self._build_path = build_path self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-", suffix=".tmp", dir="."))
@@ -184,15 +186,15 @@ def boot(self, img, extra_args=[]): "-device", "virtio-blk,drive=drive0,bootindex=0"] args += self._data_args + extra_args logging.debug("QEMU args: %s", " ".join(args)) - qemu_bin = os.environ.get("QEMU", "qemu-system-" + self.arch) - guest = QEMUMachine(binary=qemu_bin, args=args) + qemu_path = get_qemu_path(self.arch, self._build_path) + guest = QEMUMachine(binary=qemu_path, args=args) guest.set_machine('pc') guest.set_console() try: guest.launch() except: logging.error("Failed to launch QEMU, command line:") - logging.error(" ".join([qemu_bin] + args)) + logging.error(" ".join([qemu_path] + args)) logging.error("Log:") logging.error(guest.get_log()) logging.error("QEMU version >= 2.10 is required")
@@ -391,6 +393,19 @@ def gen_cloud_init_iso(self): return os.path.join(cidir, "cloud-init.iso") +def get_qemu_path(arch, build_path=None): + """Fetch the path to the qemu binary.""" + # If QEMU environment variable set, it takes precedence + if "QEMU" in os.environ: + qemu_path = os.environ["QEMU"] + elif build_path: + qemu_path = os.path.join(build_path, arch + "-softmmu") + qemu_path = os.path.join(qemu_path, "qemu-system-" + arch) + else: + # Default is to use system path for qemu. + qemu_path = "qemu-system-" + arch + return qemu_path + def parse_args(vmcls): def get_default_jobs():
@@ -421,6 +436,9 @@ def get_default_jobs(): help="build QEMU from source in guest") parser.add_option("--build-target", help="QEMU build target", default="check") + parser.add_option("--build-path", default=None, + help="Path of build directory, "\ + "for using build tree QEMU binary. ") parser.add_option("--interactive", "-I", action="store_true", help="Interactively run command") parser.add_option("--snapshot", "-s", action="store_true",
@@ -439,7 +457,7 @@ def main(vmcls): logging.basicConfig(level=(logging.DEBUG if args.debug else logging.WARN)) vm = vmcls(debug=args.debug, vcpus=args.jobs, - genisoimage=args.genisoimage) + genisoimage=args.genisoimage, build_path=args.build_path) if args.build_image: if os.path.exists(args.image) and not args.force: sys.stderr.writelines(["Image file exists: %s\n" % args.image,
Signature · 1 line
2.21.3
[PULL 20/25] tests/vm: allow wait_ssh() to specify command
In reply to Philippe Mathieu-DaudéFrom: Robert Foley <[email protected]>
This allows for waiting for completion of arbitrary commands.
Message-Id: <[email protected]>
--- tests/vm/basevm.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
tests/vm/basevm.py +7 -7
@@ -320,24 +320,24 @@ def console_sshd_config(self, prompt): def print_step(self, text): sys.stderr.write("### %s ...\n" % text) - def wait_ssh(self, wait_root=False, seconds=300): + def wait_ssh(self, wait_root=False, seconds=300, cmd="exit 0"): # Allow more time for VM to boot under TCG. if not kvm_available(self.arch): seconds *= self.tcg_ssh_timeout_multiplier starttime = datetime.datetime.now() endtime = starttime + datetime.timedelta(seconds=seconds) - guest_up = False + cmd_success = False while datetime.datetime.now() < endtime: - if wait_root and self.ssh_root("exit 0") == 0: - guest_up = True + if wait_root and self.ssh_root(cmd) == 0: + cmd_success = True break - elif self.ssh("exit 0") == 0: - guest_up = True + elif self.ssh(cmd) == 0: + cmd_success = True break seconds = (endtime - datetime.datetime.now()).total_seconds() logging.debug("%ds before timeout", seconds) time.sleep(1) - if not guest_up: + if not cmd_success: raise Exception("Timeout while waiting for guest ssh") def shutdown(self):
Signature · 1 line
2.21.3
[PULL 21/25] tests/migration/guestperf: Use Python 3 interpreter
In reply to Philippe Mathieu-DaudéMessage-Id: <[email protected]>
--- tests/migration/guestperf-batch.py | 2 +- tests/migration/guestperf-plot.py | 2 +- tests/migration/guestperf.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
tests/migration/guestperf-batch.py +1 -1
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # Migration test batch comparison invokation #
tests/migration/guestperf-plot.py +1 -1
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # Migration test graph plotting command #
tests/migration/guestperf.py +1 -1
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # # Migration test direct invokation command #
Signature · 1 line
2.21.3
[PULL 22/25] tests/acceptance/migration.py: Wait for both sides
In reply to Philippe Mathieu-DaudéFrom: "Dr. David Alan Gilbert" <[email protected]>
When the source finishes migration the destination will still be receiving the data sent by the source, so it might not have quite finished yet, so won't quite have reached 'completed'. This lead to occasional asserts in the next few checks.
After the source has finished, check the destination as well. (We can't just switch to checking the destination, because it doesn't give a status until it has started receiving the migration).
Message-Id: <[email protected]>
--- tests/acceptance/migration.py | 4 ++++ 1 file changed, 4 insertions(+)
tests/acceptance/migration.py +4 -0
@@ -35,6 +35,10 @@ def assert_migration(self, src_vm, dst_vm): timeout=self.timeout, step=0.1, args=(src_vm,)) + wait.wait_for(self.migration_finished, + timeout=self.timeout, + step=0.1, + args=(dst_vm,)) self.assertEqual(src_vm.command('query-migrate')['status'], 'completed') self.assertEqual(dst_vm.command('query-migrate')['status'], 'completed') self.assertEqual(dst_vm.command('query-status')['status'], 'running')
Signature · 1 line
2.21.3
[PULL 23/25] tests/acceptance: allow console interaction with specific VMs
In reply to Philippe Mathieu-DaudéFrom: Pavel Dovgalyuk <[email protected]>
Console interaction in avocado scripts was possible only with single default VM.
This patch modifies the function parameters to allow passing a specific VM as a parameter to interact with it.
Message-Id: <159073587933.20809.5122618715976660635.stgit@pasha-ThinkPad-X280>
--- tests/acceptance/avocado_qemu/__init__.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
tests/acceptance/avocado_qemu/__init__.py +8 -5
@@ -69,13 +69,15 @@ def pick_default_qemu_bin(arch=None): def _console_interaction(test, success_message, failure_message, - send_string, keep_sending=False): + send_string, keep_sending=False, vm=None): assert not keep_sending or send_string - console = test.vm.console_socket.makefile() + if vm is None: + vm = test.vm + console = vm.console_socket.makefile() console_logger = logging.getLogger('console') while True: if send_string: - test.vm.console_socket.sendall(send_string.encode()) + vm.console_socket.sendall(send_string.encode()) if not keep_sending: send_string = None # send only once msg = console.readline().strip()
@@ -115,7 +117,8 @@ def interrupt_interactive_console_until_pattern(test, success_message, _console_interaction(test, success_message, failure_message, interrupt_string, True) -def wait_for_console_pattern(test, success_message, failure_message=None): +def wait_for_console_pattern(test, success_message, failure_message=None, + vm=None): """ Waits for messages to appear on the console, while logging the content
@@ -125,7 +128,7 @@ def wait_for_console_pattern(test, success_message, failure_message=None): :param success_message: if this message appears, test succeeds :param failure_message: if this message appears, test fails """ - _console_interaction(test, success_message, failure_message, None) + _console_interaction(test, success_message, failure_message, None, vm=vm) def exec_command_and_wait_for_pattern(test, command, success_message, failure_message=None):
Signature · 1 line
2.21.3
[PULL 24/25] tests/acceptance: refactor boot_linux_console test to allow code reuse
In reply to Philippe Mathieu-DaudéFrom: Pavel Dovgalyuk <[email protected]>
This patch splits code in BootLinuxConsole class into two different classes to allow reusing it by record/replay tests.
Message-Id: <159073588490.20809.13942096070255577558.stgit@pasha-ThinkPad-X280>
--- tests/acceptance/boot_linux_console.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
tests/acceptance/boot_linux_console.py +11 -10
@@ -28,19 +28,13 @@ except CmdNotFoundError: P7ZIP_AVAILABLE = False -class BootLinuxConsole(Test): - """ - Boots a Linux kernel and checks that the console is operational and the - kernel command line is properly passed from QEMU to the kernel - """ - - timeout = 90 - +class LinuxKernelTest(Test): KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' - def wait_for_console_pattern(self, success_message): + def wait_for_console_pattern(self, success_message, vm=None): wait_for_console_pattern(self, success_message, - failure_message='Kernel panic - not syncing') + failure_message='Kernel panic - not syncing', + vm=vm) def extract_from_deb(self, deb, path): """
@@ -79,6 +73,13 @@ def extract_from_rpm(self, rpm, path): os.chdir(cwd) return os.path.normpath(os.path.join(self.workdir, path)) +class BootLinuxConsole(LinuxKernelTest): + """ + Boots a Linux kernel and checks that the console is operational and the + kernel command line is properly passed from QEMU to the kernel + """ + timeout = 90 + def test_x86_64_pc(self): """ :avocado: tags=arch:x86_64
Signature · 1 line
2.21.3
[PULL 25/25] tests/acceptance: refactor boot_linux to allow code reuse
In reply to Philippe Mathieu-DaudéFrom: Pavel Dovgalyuk <[email protected]>
This patch moves image downloading functions to the separate class to allow reusing them from record/replay tests.
Message-Id: <159073593167.20809.17582679291556188984.stgit@pasha-ThinkPad-X280>
--- tests/acceptance/boot_linux.py | 49 ++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 20 deletions(-)
tests/acceptance/boot_linux.py +29 -20
@@ -26,22 +26,8 @@ TCG_NOT_AVAILABLE = ACCEL_NOT_AVAILABLE_FMT % "TCG" -class BootLinux(Test): - """ - Boots a Linux system, checking for a successful initialization - """ - - timeout = 900 - chksum = None - - def setUp(self): - super(BootLinux, self).setUp() - self.vm.add_args('-smp', '2') - self.vm.add_args('-m', '1024') - self.prepare_boot() - self.prepare_cloudinit() - - def prepare_boot(self): +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
@@ -60,17 +46,17 @@ def prepare_boot(self): if image_arch == 'ppc64': image_arch = 'ppc64le' try: - self.boot = vmimage.get( + boot = vmimage.get( 'fedora', arch=image_arch, version='31', checksum=self.chksum, algorithm='sha256', cache_dir=self.cache_dirs[0], snapshot_dir=self.workdir) - self.vm.add_args('-drive', 'file=%s' % self.boot.path) except: self.cancel('Failed to download/prepare boot image') + return boot.path - def prepare_cloudinit(self): + def download_cloudinit(self): self.log.info('Preparing cloudinit image') try: cloudinit_iso = os.path.join(self.workdir, 'cloudinit.iso')
@@ -81,9 +67,32 @@ def prepare_cloudinit(self): # QEMU's hard coded usermode router address phone_home_host='10.0.2.2', phone_home_port=self.phone_home_port) - self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso) except Exception: self.cancel('Failed to prepared cloudinit image') + return cloudinit_iso + +class BootLinux(BootLinuxBase): + """ + Boots a Linux system, checking for a successful initialization + """ + + timeout = 900 + chksum = None + + def setUp(self): + super(BootLinux, self).setUp() + self.vm.add_args('-smp', '2') + self.vm.add_args('-m', '1024') + self.prepare_boot() + self.prepare_cloudinit() + + def prepare_boot(self): + path = self.download_boot() + self.vm.add_args('-drive', 'file=%s' % path) + + def prepare_cloudinit(self): + cloudinit_iso = self.download_cloudinit() + self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso) def launch_and_wait(self): self.vm.set_console()
Signature · 1 line
2.21.3
Peter Maydell
AppliedQuoted 18 lines · Philippe Mathieu-Daudé
The following changes since commit
c86274bc2e34295764fb44c2aef3cf29623f9b4b:Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-tcg-plugins=
-270520-1' into staging (2020-05-29 17:41:45 +0100)are available in the Git repository at:
https://gitlab.com/philmd/qemu.git tags/python-next-20200531
for you to fetch changes up to
1c80c87c8c2489e4318c93c844aa29bc1d014146:tests/acceptance: refactor
boot_linuxto allow code reuse (2020-05-31 18:25=
:31 +0200)----------------------------------------------------------------
Python queue:
Quoted 9 lines
* migration acceptance test fix
* introduce pylintrc & flake8 config
* various cleanups (Python3, style)
* vm-test can set QEMU_LOCAL=3D1 to use locally built binaries
* refactored BootLinuxBase & LinuxKernelTest acceptance classeshttps://gitlab.com/philmd/qemu/pipelines/151323210
https://travis-ci.org/github/philmd/qemu/builds/693157969
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/5.1
for any user-visible changes.
-- PMM