Python Pullreq

Python PR:
 
 - Use socketpair for all machine.py connections
 - Support Python 3.12
 - Switch iotests over to using raise-on-error QMP command interface
   (Thank you very much, Vladimir!)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+ber27ys35W+dsvQfe+BBqr8OQ4FAmUpldkACgkQfe+BBqr8
 OQ4NtRAAnkEmXsECAxQ2ewvf3yK8PTFm4Oq5nqMIw+KB94ATrsGzk3z1rLvatSl3
 6VLsV2+FWoOEyKrsfu5DIfbuo4d3TZTU7N2DIZpVpvO166K+fXbzp8skAg+n3BMC
 tWkSOcnsT6+8aqyxxyASdHvbbE7pvPw8OA3oIIstsYeZ5/HHpOWXNj1kjCsnL0lW
 7y5h6UUKGmnCPdixyk042+AvKkT7GAKVjFnjUF5JHv0iR2KpQ+O9H7OEalqQT5w5
 eab4oMGuIYhzYe+MNpyybAB3Xd2pxhcppk+sl4dCE8qmMn7KRoTNw1iu+qhsNQfQ
 JILZoCPtYMhpef4X0ulH8PFBMweBptqOjo4lpz9QIdMWTf86IE0yIT9DCy3aSjpp
 ywwxhFKJS43gz4WHkEJlrY9PHwLsULaV/Cz6HKJAU6h9aFtcNdT4pkCOERnZ8X4C
 yHlNReTG5Dz1sYzKJ/k9LTjAaVDasumR8/yadaUCwalj5zexQ27qlIM6oc5wdIRQ
 up1VHi7odF5KHb6GeqdniuuEF6NBCYRAV5nz+dbd6exfKOaxYRrr48yh9SUm8QS6
 JCvMMFFAZCIrI/nkRVajbLi9L5O3fg5abtlzSzh9o4iyf8Rf/1gtKNxZRK1NZIjQ
 cTYBJXpMulNx7bM2CPNsPWGqCTAjAcu10svqTA8luGj4fqdTNyU=
 =02Bd
 -----END PGP SIGNATURE-----

Merge tag 'python-pull-request' of https://gitlab.com/jsnow/qemu into staging

Python Pullreq

Python PR:

- Use socketpair for all machine.py connections
- Support Python 3.12
- Switch iotests over to using raise-on-error QMP command interface
  (Thank you very much, Vladimir!)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+ber27ys35W+dsvQfe+BBqr8OQ4FAmUpldkACgkQfe+BBqr8
# OQ4NtRAAnkEmXsECAxQ2ewvf3yK8PTFm4Oq5nqMIw+KB94ATrsGzk3z1rLvatSl3
# 6VLsV2+FWoOEyKrsfu5DIfbuo4d3TZTU7N2DIZpVpvO166K+fXbzp8skAg+n3BMC
# tWkSOcnsT6+8aqyxxyASdHvbbE7pvPw8OA3oIIstsYeZ5/HHpOWXNj1kjCsnL0lW
# 7y5h6UUKGmnCPdixyk042+AvKkT7GAKVjFnjUF5JHv0iR2KpQ+O9H7OEalqQT5w5
# eab4oMGuIYhzYe+MNpyybAB3Xd2pxhcppk+sl4dCE8qmMn7KRoTNw1iu+qhsNQfQ
# JILZoCPtYMhpef4X0ulH8PFBMweBptqOjo4lpz9QIdMWTf86IE0yIT9DCy3aSjpp
# ywwxhFKJS43gz4WHkEJlrY9PHwLsULaV/Cz6HKJAU6h9aFtcNdT4pkCOERnZ8X4C
# yHlNReTG5Dz1sYzKJ/k9LTjAaVDasumR8/yadaUCwalj5zexQ27qlIM6oc5wdIRQ
# up1VHi7odF5KHb6GeqdniuuEF6NBCYRAV5nz+dbd6exfKOaxYRrr48yh9SUm8QS6
# JCvMMFFAZCIrI/nkRVajbLi9L5O3fg5abtlzSzh9o4iyf8Rf/1gtKNxZRK1NZIjQ
# cTYBJXpMulNx7bM2CPNsPWGqCTAjAcu10svqTA8luGj4fqdTNyU=
# =02Bd
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 13 Oct 2023 15:09:13 EDT
# gpg:                using RSA key F9B7ABDBBCACDF95BE76CBD07DEF8106AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" [full]
# Primary key fingerprint: FAEB 9711 A12C F475 812F  18F2 88A9 064D 1835 61EB
#      Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76  CBD0 7DEF 8106 AAFC 390E

* tag 'python-pull-request' of https://gitlab.com/jsnow/qemu: (25 commits)
  python: use vm.cmd() instead of vm.qmp() where appropriate
  scripts: add python_qmp_updater.py
  tests/vm/basevm.py: use cmd() instead of qmp()
  iotests.py: pause_job(): drop return value
  iotests: drop some extra ** in qmp() call
  iotests: drop some extra semicolons
  iotests: refactor some common qmp result checks into generic pattern
  iotests: add some missed checks of qmp result
  iotests: QemuStorageDaemon: add cmd() method like in QEMUMachine.
  python/machine.py: upgrade vm.cmd() method
  python/qemu: rename command() to cmd()
  python: rename QEMUMonitorProtocol.cmd() to cmd_raw()
  scripts/cpu-x86-uarch-abi.py: use .command() instead of .cmd()
  qmp_shell.py: _fill_completion() use .command() instead of .cmd()
  python/qemu/qmp/legacy: cmd(): drop cmd_id unused argument
  Python: Enable python3.12 support
  configure: fix error message to say Python 3.8
  python/qmp: remove Server.wait_closed() call for Python 3.12
  Python/iotests: Add type hint for nbd module
  python/machine: remove unused sock_dir argument
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2023-10-16 12:37:48 -04:00
commit 800485762e
82 changed files with 1466 additions and 1717 deletions

5
configure vendored
View File

@ -562,7 +562,8 @@ first_python=
if test -z "${PYTHON}"; then if test -z "${PYTHON}"; then
# A bare 'python' is traditionally python 2.x, but some distros # A bare 'python' is traditionally python 2.x, but some distros
# have it as python 3.x, so check in both places. # have it as python 3.x, so check in both places.
for binary in python3 python python3.11 python3.10 python3.9 python3.8; do for binary in python3 python python3.12 python3.11 \
python3.10 python3.9 python3.8; do
if has "$binary"; then if has "$binary"; then
python=$(command -v "$binary") python=$(command -v "$binary")
if check_py_version "$python"; then if check_py_version "$python"; then
@ -948,7 +949,7 @@ then
# If first_python is set, there was a binary somewhere even though # If first_python is set, there was a binary somewhere even though
# it was not suitable. Use it for the error message. # it was not suitable. Use it for the error message.
if test -n "$first_python"; then if test -n "$first_python"; then
error_exit "Cannot use '$first_python', Python >= 3.7 is required." \ error_exit "Cannot use '$first_python', Python >= 3.8 is required." \
"Use --python=/path/to/python to specify a supported Python." "Use --python=/path/to/python to specify a supported Python."
else else
error_exit "Python not found. Use --python=/path/to/python" error_exit "Python not found. Use --python=/path/to/python"

View File

@ -1014,8 +1014,8 @@ class. Here's a simple usage example:
""" """
def test_qmp_human_info_version(self): def test_qmp_human_info_version(self):
self.vm.launch() self.vm.launch()
res = self.vm.command('human-monitor-command', res = self.vm.cmd('human-monitor-command',
command_line='info version') command_line='info version')
self.assertRegexpMatches(res, r'^(\d+\.\d+\.\d)') self.assertRegexpMatches(res, r'^(\d+\.\d+\.\d)')
To execute your test, run: To execute your test, run:
@ -1065,15 +1065,15 @@ and hypothetical example follows:
first_machine.launch() first_machine.launch()
second_machine.launch() second_machine.launch()
first_res = first_machine.command( first_res = first_machine.cmd(
'human-monitor-command', 'human-monitor-command',
command_line='info version') command_line='info version')
second_res = second_machine.command( second_res = second_machine.cmd(
'human-monitor-command', 'human-monitor-command',
command_line='info version') command_line='info version')
third_res = self.get_vm(name='third_machine').command( third_res = self.get_vm(name='third_machine').cmd(
'human-monitor-command', 'human-monitor-command',
command_line='info version') command_line='info version')

View File

@ -24,19 +24,32 @@ class ConsoleSocket(socket.socket):
""" """
ConsoleSocket represents a socket attached to a char device. ConsoleSocket represents a socket attached to a char device.
Optionally (if drain==True), drains the socket and places the bytes :param address: An AF_UNIX path or address.
into an in memory buffer for later processing. :param sock_fd: Optionally, an existing socket file descriptor.
One of address or sock_fd must be specified.
Optionally a file path can be passed in and we will also :param file: Optionally, a filename to log to.
dump the characters to this file for debugging purposes. :param drain: Optionally, drains the socket and places the bytes
into an in memory buffer for later processing.
""" """
def __init__(self, address: str, file: Optional[str] = None, def __init__(self,
address: Optional[str] = None,
sock_fd: Optional[int] = None,
file: Optional[str] = None,
drain: bool = False): drain: bool = False):
if address is None and sock_fd is None:
raise ValueError("one of 'address' or 'sock_fd' must be specified")
if address is not None and sock_fd is not None:
raise ValueError("can't specify both 'address' and 'sock_fd'")
self._recv_timeout_sec = 300.0 self._recv_timeout_sec = 300.0
self._sleep_time = 0.5 self._sleep_time = 0.5
self._buffer: Deque[int] = deque() self._buffer: Deque[int] = deque()
socket.socket.__init__(self, socket.AF_UNIX, socket.SOCK_STREAM) if address is not None:
self.connect(address) socket.socket.__init__(self, socket.AF_UNIX, socket.SOCK_STREAM)
self.connect(address)
else:
assert sock_fd is not None
socket.socket.__init__(self, fileno=sock_fd)
self._logfile = None self._logfile = None
if file: if file:
# pylint: disable=consider-using-with # pylint: disable=consider-using-with

View File

@ -127,7 +127,6 @@ class QEMUMachine:
name: Optional[str] = None, name: Optional[str] = None,
base_temp_dir: str = "/var/tmp", base_temp_dir: str = "/var/tmp",
monitor_address: Optional[SocketAddrT] = None, monitor_address: Optional[SocketAddrT] = None,
sock_dir: Optional[str] = None,
drain_console: bool = False, drain_console: bool = False,
console_log: Optional[str] = None, console_log: Optional[str] = None,
log_dir: Optional[str] = None, log_dir: Optional[str] = None,
@ -141,7 +140,6 @@ class QEMUMachine:
@param name: prefix for socket and log file names (default: qemu-PID) @param name: prefix for socket and log file names (default: qemu-PID)
@param base_temp_dir: default location where temp files are created @param base_temp_dir: default location where temp files are created
@param monitor_address: address for QMP monitor @param monitor_address: address for QMP monitor
@param sock_dir: where to create socket (defaults to base_temp_dir)
@param drain_console: (optional) True to drain console socket to buffer @param drain_console: (optional) True to drain console socket to buffer
@param console_log: (optional) path to console log file @param console_log: (optional) path to console log file
@param log_dir: where to create and keep log files @param log_dir: where to create and keep log files
@ -159,9 +157,10 @@ class QEMUMachine:
self._name = name or f"{id(self):x}" self._name = name or f"{id(self):x}"
self._sock_pair: Optional[Tuple[socket.socket, socket.socket]] = None self._sock_pair: Optional[Tuple[socket.socket, socket.socket]] = None
self._cons_sock_pair: Optional[
Tuple[socket.socket, socket.socket]] = None
self._temp_dir: Optional[str] = None self._temp_dir: Optional[str] = None
self._base_temp_dir = base_temp_dir self._base_temp_dir = base_temp_dir
self._sock_dir = sock_dir
self._log_dir = log_dir self._log_dir = log_dir
self._monitor_address = monitor_address self._monitor_address = monitor_address
@ -187,9 +186,6 @@ class QEMUMachine:
self._console_index = 0 self._console_index = 0
self._console_set = False self._console_set = False
self._console_device_type: Optional[str] = None self._console_device_type: Optional[str] = None
self._console_address = os.path.join(
self.sock_dir, f"{self._name}.con"
)
self._console_socket: Optional[socket.socket] = None self._console_socket: Optional[socket.socket] = None
self._console_file: Optional[socket.SocketIO] = None self._console_file: Optional[socket.SocketIO] = None
self._remove_files: List[str] = [] self._remove_files: List[str] = []
@ -301,9 +297,7 @@ class QEMUMachine:
if self._qmp_set: if self._qmp_set:
if self._sock_pair: if self._sock_pair:
fd = self._sock_pair[0].fileno() moncdev = f"socket,id=mon,fd={self._sock_pair[0].fileno()}"
os.set_inheritable(fd, True)
moncdev = f"socket,id=mon,fd={fd}"
elif isinstance(self._monitor_address, tuple): elif isinstance(self._monitor_address, tuple):
moncdev = "socket,id=mon,host={},port={}".format( moncdev = "socket,id=mon,host={},port={}".format(
*self._monitor_address *self._monitor_address
@ -318,8 +312,9 @@ class QEMUMachine:
for _ in range(self._console_index): for _ in range(self._console_index):
args.extend(['-serial', 'null']) args.extend(['-serial', 'null'])
if self._console_set: if self._console_set:
chardev = ('socket,id=console,path=%s,server=on,wait=off' % assert self._cons_sock_pair is not None
self._console_address) fd = self._cons_sock_pair[0].fileno()
chardev = f"socket,id=console,fd={fd}"
args.extend(['-chardev', chardev]) args.extend(['-chardev', chardev])
if self._console_device_type is None: if self._console_device_type is None:
args.extend(['-serial', 'chardev:console']) args.extend(['-serial', 'chardev:console'])
@ -334,12 +329,10 @@ class QEMUMachine:
return self._args return self._args
def _pre_launch(self) -> None: def _pre_launch(self) -> None:
if self._console_set:
self._remove_files.append(self._console_address)
if self._qmp_set: if self._qmp_set:
if self._monitor_address is None: if self._monitor_address is None:
self._sock_pair = socket.socketpair() self._sock_pair = socket.socketpair()
os.set_inheritable(self._sock_pair[0].fileno(), True)
sock = self._sock_pair[1] sock = self._sock_pair[1]
if isinstance(self._monitor_address, str): if isinstance(self._monitor_address, str):
self._remove_files.append(self._monitor_address) self._remove_files.append(self._monitor_address)
@ -353,6 +346,10 @@ class QEMUMachine:
nickname=self._name nickname=self._name
) )
if self._console_set:
self._cons_sock_pair = socket.socketpair()
os.set_inheritable(self._cons_sock_pair[0].fileno(), True)
# NOTE: Make sure any opened resources are *definitely* freed in # NOTE: Make sure any opened resources are *definitely* freed in
# _post_shutdown()! # _post_shutdown()!
# pylint: disable=consider-using-with # pylint: disable=consider-using-with
@ -370,6 +367,9 @@ class QEMUMachine:
def _post_launch(self) -> None: def _post_launch(self) -> None:
if self._sock_pair: if self._sock_pair:
self._sock_pair[0].close() self._sock_pair[0].close()
if self._cons_sock_pair:
self._cons_sock_pair[0].close()
if self._qmp_connection: if self._qmp_connection:
if self._sock_pair: if self._sock_pair:
self._qmp.connect() self._qmp.connect()
@ -397,6 +397,11 @@ class QEMUMachine:
finally: finally:
assert self._qmp_connection is None assert self._qmp_connection is None
if self._sock_pair:
self._sock_pair[0].close()
self._sock_pair[1].close()
self._sock_pair = None
self._close_qemu_log_file() self._close_qemu_log_file()
self._load_io_log() self._load_io_log()
@ -520,6 +525,11 @@ class QEMUMachine:
self._console_socket.close() self._console_socket.close()
self._console_socket = None self._console_socket = None
if self._cons_sock_pair:
self._cons_sock_pair[0].close()
self._cons_sock_pair[1].close()
self._cons_sock_pair = None
def _hard_shutdown(self) -> None: def _hard_shutdown(self) -> None:
""" """
Perform early cleanup, kill the VM, and wait for it to terminate. Perform early cleanup, kill the VM, and wait for it to terminate.
@ -692,21 +702,31 @@ class QEMUMachine:
conv_keys = True conv_keys = True
qmp_args = self._qmp_args(conv_keys, args) qmp_args = self._qmp_args(conv_keys, args)
ret = self._qmp.cmd(cmd, args=qmp_args) ret = self._qmp.cmd_raw(cmd, args=qmp_args)
if cmd == 'quit' and 'error' not in ret and 'return' in ret: if cmd == 'quit' and 'error' not in ret and 'return' in ret:
self._quit_issued = True self._quit_issued = True
return ret return ret
def command(self, cmd: str, def cmd(self, cmd: str,
conv_keys: bool = True, args_dict: Optional[Dict[str, object]] = None,
**args: Any) -> QMPReturnValue: conv_keys: Optional[bool] = None,
**args: Any) -> QMPReturnValue:
""" """
Invoke a QMP command. Invoke a QMP command.
On success return the response dict. On success return the response dict.
On failure raise an exception. On failure raise an exception.
""" """
if args_dict is not None:
assert not args
assert conv_keys is None
args = args_dict
conv_keys = False
if conv_keys is None:
conv_keys = True
qmp_args = self._qmp_args(conv_keys, args) qmp_args = self._qmp_args(conv_keys, args)
ret = self._qmp.command(cmd, **qmp_args) ret = self._qmp.cmd(cmd, **qmp_args)
if cmd == 'quit': if cmd == 'quit':
self._quit_issued = True self._quit_issued = True
return ret return ret
@ -881,10 +901,19 @@ class QEMUMachine:
""" """
if self._console_socket is None: if self._console_socket is None:
LOG.debug("Opening console socket") LOG.debug("Opening console socket")
if not self._console_set:
raise QEMUMachineError(
"Attempt to access console socket with no connection")
assert self._cons_sock_pair is not None
# os.dup() is used here for sock_fd because otherwise we'd
# have two rich python socket objects that would each try to
# close the same underlying fd when either one gets garbage
# collected.
self._console_socket = console_socket.ConsoleSocket( self._console_socket = console_socket.ConsoleSocket(
self._console_address, sock_fd=os.dup(self._cons_sock_pair[1].fileno()),
file=self._console_log_path, file=self._console_log_path,
drain=self._drain_console) drain=self._drain_console)
self._cons_sock_pair[1].close()
return self._console_socket return self._console_socket
@property @property
@ -909,15 +938,6 @@ class QEMUMachine:
dir=self._base_temp_dir) dir=self._base_temp_dir)
return self._temp_dir return self._temp_dir
@property
def sock_dir(self) -> str:
"""
Returns the directory used for sockfiles by this machine.
"""
if self._sock_dir:
return self._sock_dir
return self.temp_dir
@property @property
def log_dir(self) -> str: def log_dir(self) -> str:
""" """

View File

@ -24,6 +24,7 @@ from typing import (
Optional, Optional,
Sequence, Sequence,
TextIO, TextIO,
Tuple,
) )
from qemu.qmp import SocketAddrT from qemu.qmp import SocketAddrT
@ -38,23 +39,41 @@ class QEMUQtestProtocol:
:param address: QEMU address, can be either a unix socket path (string) :param address: QEMU address, can be either a unix socket path (string)
or a tuple in the form ( address, port ) for a TCP or a tuple in the form ( address, port ) for a TCP
connection connection
:param server: server mode, listens on the socket (bool) :param sock: An existing socket can be provided as an alternative to
an address. One of address or sock must be provided.
:param server: server mode, listens on the socket. Only meaningful
in conjunction with an address and not an existing
socket.
:raise socket.error: on socket connection errors :raise socket.error: on socket connection errors
.. note:: .. note::
No connection is established by __init__(), this is done No connection is established by __init__(), this is done
by the connect() or accept() methods. by the connect() or accept() methods.
""" """
def __init__(self, address: SocketAddrT, def __init__(self,
address: Optional[SocketAddrT] = None,
sock: Optional[socket.socket] = None,
server: bool = False): server: bool = False):
if address is None and sock is None:
raise ValueError("Either 'address' or 'sock' must be specified")
if address is not None and sock is not None:
raise ValueError(
"Either 'address' or 'sock' must be specified, but not both")
if sock is not None and server:
raise ValueError("server=True is meaningless when passing socket")
self._address = address self._address = address
self._sock = self._get_sock() self._sock = sock or self._get_sock()
self._sockfile: Optional[TextIO] = None self._sockfile: Optional[TextIO] = None
if server: if server:
assert self._address is not None
self._sock.bind(self._address) self._sock.bind(self._address)
self._sock.listen(1) self._sock.listen(1)
def _get_sock(self) -> socket.socket: def _get_sock(self) -> socket.socket:
assert self._address is not None
if isinstance(self._address, tuple): if isinstance(self._address, tuple):
family = socket.AF_INET family = socket.AF_INET
else: else:
@ -67,7 +86,8 @@ class QEMUQtestProtocol:
@raise socket.error on socket connection errors @raise socket.error on socket connection errors
""" """
self._sock.connect(self._address) if self._address is not None:
self._sock.connect(self._address)
self._sockfile = self._sock.makefile(mode='r') self._sockfile = self._sock.makefile(mode='r')
def accept(self) -> None: def accept(self) -> None:
@ -115,41 +135,49 @@ class QEMUQtestMachine(QEMUMachine):
wrapper: Sequence[str] = (), wrapper: Sequence[str] = (),
name: Optional[str] = None, name: Optional[str] = None,
base_temp_dir: str = "/var/tmp", base_temp_dir: str = "/var/tmp",
sock_dir: Optional[str] = None,
qmp_timer: Optional[float] = None): qmp_timer: Optional[float] = None):
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
if name is None: if name is None:
name = "qemu-%d" % os.getpid() name = "qemu-%d" % os.getpid()
if sock_dir is None:
sock_dir = base_temp_dir
super().__init__(binary, args, wrapper=wrapper, name=name, super().__init__(binary, args, wrapper=wrapper, name=name,
base_temp_dir=base_temp_dir, base_temp_dir=base_temp_dir,
sock_dir=sock_dir, qmp_timer=qmp_timer) qmp_timer=qmp_timer)
self._qtest: Optional[QEMUQtestProtocol] = None self._qtest: Optional[QEMUQtestProtocol] = None
self._qtest_path = os.path.join(sock_dir, name + "-qtest.sock") self._qtest_sock_pair: Optional[
Tuple[socket.socket, socket.socket]] = None
@property @property
def _base_args(self) -> List[str]: def _base_args(self) -> List[str]:
args = super()._base_args args = super()._base_args
assert self._qtest_sock_pair is not None
fd = self._qtest_sock_pair[0].fileno()
args.extend([ args.extend([
'-qtest', f"unix:path={self._qtest_path}", '-chardev', f"socket,id=qtest,fd={fd}",
'-qtest', 'chardev:qtest',
'-accel', 'qtest' '-accel', 'qtest'
]) ])
return args return args
def _pre_launch(self) -> None: def _pre_launch(self) -> None:
self._qtest_sock_pair = socket.socketpair()
os.set_inheritable(self._qtest_sock_pair[0].fileno(), True)
super()._pre_launch() super()._pre_launch()
self._qtest = QEMUQtestProtocol(self._qtest_path, server=True) self._qtest = QEMUQtestProtocol(sock=self._qtest_sock_pair[1])
def _post_launch(self) -> None: def _post_launch(self) -> None:
assert self._qtest is not None assert self._qtest is not None
super()._post_launch() super()._post_launch()
self._qtest.accept() if self._qtest_sock_pair:
self._qtest_sock_pair[0].close()
self._qtest.connect()
def _post_shutdown(self) -> None: def _post_shutdown(self) -> None:
if self._qtest_sock_pair:
self._qtest_sock_pair[0].close()
self._qtest_sock_pair[1].close()
self._qtest_sock_pair = None
super()._post_shutdown() super()._post_shutdown()
self._remove_if_exists(self._qtest_path)
def qtest(self, cmd: str) -> str: def qtest(self, cmd: str) -> str:
""" """

View File

@ -194,24 +194,20 @@ class QEMUMonitorProtocol:
) )
) )
def cmd(self, name: str, def cmd_raw(self, name: str,
args: Optional[Dict[str, object]] = None, args: Optional[Dict[str, object]] = None) -> QMPMessage:
cmd_id: Optional[object] = None) -> QMPMessage:
""" """
Build a QMP command and send it to the QMP Monitor. Build a QMP command and send it to the QMP Monitor.
:param name: command name (string) :param name: command name (string)
:param args: command arguments (dict) :param args: command arguments (dict)
:param cmd_id: command id (dict, list, string or int)
""" """
qmp_cmd: QMPMessage = {'execute': name} qmp_cmd: QMPMessage = {'execute': name}
if args: if args:
qmp_cmd['arguments'] = args qmp_cmd['arguments'] = args
if cmd_id:
qmp_cmd['id'] = cmd_id
return self.cmd_obj(qmp_cmd) return self.cmd_obj(qmp_cmd)
def command(self, cmd: str, **kwds: object) -> QMPReturnValue: def cmd(self, cmd: str, **kwds: object) -> QMPReturnValue:
""" """
Build and send a QMP command to the monitor, report errors if any Build and send a QMP command to the monitor, report errors if any
""" """

View File

@ -495,7 +495,6 @@ class AsyncProtocol(Generic[T]):
try: try:
self.logger.debug("Stopping server.") self.logger.debug("Stopping server.")
self._server.close() self._server.close()
await self._server.wait_closed()
self.logger.debug("Server stopped.") self.logger.debug("Server stopped.")
finally: finally:
self._server = None self._server = None

View File

@ -91,14 +91,21 @@ from subprocess import Popen
import sys import sys
from typing import ( from typing import (
IO, IO,
Dict,
Iterator, Iterator,
List, List,
NoReturn, NoReturn,
Optional, Optional,
Sequence, Sequence,
cast,
) )
from qemu.qmp import ConnectError, QMPError, SocketAddrT from qemu.qmp import (
ConnectError,
ExecuteError,
QMPError,
SocketAddrT,
)
from qemu.qmp.legacy import ( from qemu.qmp.legacy import (
QEMUMonitorProtocol, QEMUMonitorProtocol,
QMPBadPortError, QMPBadPortError,
@ -194,11 +201,12 @@ class QMPShell(QEMUMonitorProtocol):
super().close() super().close()
def _fill_completion(self) -> None: def _fill_completion(self) -> None:
cmds = self.cmd('query-commands') try:
if 'error' in cmds: cmds = cast(List[Dict[str, str]], self.cmd('query-commands'))
return for cmd in cmds:
for cmd in cmds['return']: self._completer.append(cmd['name'])
self._completer.append(cmd['name']) except ExecuteError:
pass
def _completer_setup(self) -> None: def _completer_setup(self) -> None:
self._completer = QMPCompleter() self._completer = QMPCompleter()

View File

@ -64,7 +64,7 @@ from qemu.qmp.legacy import QEMUMonitorProtocol
class QemuGuestAgent(QEMUMonitorProtocol): class QemuGuestAgent(QEMUMonitorProtocol):
def __getattr__(self, name: str) -> Callable[..., Any]: def __getattr__(self, name: str) -> Callable[..., Any]:
def wrapper(**kwds: object) -> object: def wrapper(**kwds: object) -> object:
return self.command('guest-' + name.replace('_', '-'), **kwds) return self.cmd('guest-' + name.replace('_', '-'), **kwds)
return wrapper return wrapper

View File

@ -84,7 +84,7 @@ class QOMSet(QOMCommand):
self.value = args.value self.value = args.value
def run(self) -> int: def run(self) -> int:
rsp = self.qmp.command( rsp = self.qmp.cmd(
'qom-set', 'qom-set',
path=self.path, path=self.path,
property=self.prop, property=self.prop,
@ -129,7 +129,7 @@ class QOMGet(QOMCommand):
self.prop = tmp[1] self.prop = tmp[1]
def run(self) -> int: def run(self) -> int:
rsp = self.qmp.command( rsp = self.qmp.cmd(
'qom-get', 'qom-get',
path=self.path, path=self.path,
property=self.prop property=self.prop
@ -231,8 +231,8 @@ class QOMTree(QOMCommand):
if item.child: if item.child:
continue continue
try: try:
rsp = self.qmp.command('qom-get', path=path, rsp = self.qmp.cmd('qom-get', path=path,
property=item.name) property=item.name)
print(f" {item.name}: {rsp} ({item.type})") print(f" {item.name}: {rsp} ({item.type})")
except ExecuteError as err: except ExecuteError as err:
print(f" {item.name}: <EXCEPTION: {err!s}> ({item.type})") print(f" {item.name}: <EXCEPTION: {err!s}> ({item.type})")

View File

@ -140,7 +140,7 @@ class QOMCommand:
""" """
:return: a strongly typed list from the 'qom-list' command. :return: a strongly typed list from the 'qom-list' command.
""" """
rsp = self.qmp.command('qom-list', path=path) rsp = self.qmp.cmd('qom-list', path=path)
# qom-list returns List[ObjectPropertyInfo] # qom-list returns List[ObjectPropertyInfo]
assert isinstance(rsp, list) assert isinstance(rsp, list)
return [ObjectPropertyInfo.make(x) for x in rsp] return [ObjectPropertyInfo.make(x) for x in rsp]

View File

@ -137,7 +137,7 @@ class QOMFuse(QOMCommand, Operations):
if path == '': if path == '':
path = '/' path = '/'
try: try:
data = str(self.qmp.command('qom-get', path=path, property=prop)) data = str(self.qmp.cmd('qom-get', path=path, property=prop))
data += '\n' # make values shell friendly data += '\n' # make values shell friendly
except ExecuteError as err: except ExecuteError as err:
raise FuseOSError(EPERM) from err raise FuseOSError(EPERM) from err
@ -152,8 +152,8 @@ class QOMFuse(QOMCommand, Operations):
return False return False
path, prop = path.rsplit('/', 1) path, prop = path.rsplit('/', 1)
prefix = '/'.join(['..'] * (len(path.split('/')) - 1)) prefix = '/'.join(['..'] * (len(path.split('/')) - 1))
return prefix + str(self.qmp.command('qom-get', path=path, return prefix + str(self.qmp.cmd('qom-get', path=path,
property=prop)) property=prop))
def getattr(self, path: str, def getattr(self, path: str,
fh: Optional[IO[bytes]] = None) -> Mapping[str, object]: fh: Optional[IO[bytes]] = None) -> Mapping[str, object]:

View File

@ -18,6 +18,7 @@ classifiers =
Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Typing :: Typed Typing :: Typed
[options] [options]
@ -182,7 +183,7 @@ multi_line_output=3
# of python available on your system to run this test. # of python available on your system to run this test.
[tox:tox] [tox:tox]
envlist = py38, py39, py310, py311 envlist = py38, py39, py310, py311, py312
skip_missing_interpreters = true skip_missing_interpreters = true
[testenv] [testenv]

View File

@ -85,7 +85,7 @@ skip = [
names = [] names = []
for model in models["return"]: for model in models:
if "alias-of" in model: if "alias-of" in model:
continue continue
names.append(model["name"]) names.append(model["name"])
@ -94,11 +94,11 @@ models = {}
for name in sorted(names): for name in sorted(names):
cpu = shell.cmd("query-cpu-model-expansion", cpu = shell.cmd("query-cpu-model-expansion",
{ "type": "static", { "type": "static",
"model": { "name": name }}) "model": { "name": name }})
got = {} got = {}
for (feature, present) in cpu["return"]["model"]["props"].items(): for (feature, present) in cpu["model"]["props"].items():
if present and feature not in skip: if present and feature not in skip:
got[feature] = True got[feature] = True

View File

@ -269,14 +269,14 @@ def formatTestCase(t):
def qomListTypeNames(vm, **kwargs): def qomListTypeNames(vm, **kwargs):
"""Run qom-list-types QMP command, return type names""" """Run qom-list-types QMP command, return type names"""
types = vm.command('qom-list-types', **kwargs) types = vm.cmd('qom-list-types', **kwargs)
return [t['name'] for t in types] return [t['name'] for t in types]
def infoQDM(vm): def infoQDM(vm):
"""Parse 'info qdm' output""" """Parse 'info qdm' output"""
args = {'command-line': 'info qdm'} args = {'command-line': 'info qdm'}
devhelp = vm.command('human-monitor-command', **args) devhelp = vm.cmd('human-monitor-command', **args)
for l in devhelp.split('\n'): for l in devhelp.split('\n'):
l = l.strip() l = l.strip()
if l == '' or l.endswith(':'): if l == '' or l.endswith(':'):
@ -304,9 +304,9 @@ class QemuBinaryInfo(object):
# there's no way to query DeviceClass::user_creatable using QMP, # there's no way to query DeviceClass::user_creatable using QMP,
# so use 'info qdm': # so use 'info qdm':
self.no_user_devs = set([d['name'] for d in infoQDM(vm, ) if d['no-user']]) self.no_user_devs = set([d['name'] for d in infoQDM(vm, ) if d['no-user']])
self.machines = list(m['name'] for m in vm.command('query-machines')) self.machines = list(m['name'] for m in vm.cmd('query-machines'))
self.user_devs = self.alldevs.difference(self.no_user_devs) self.user_devs = self.alldevs.difference(self.no_user_devs)
self.kvm_available = vm.command('query-kvm')['enabled'] self.kvm_available = vm.cmd('query-kvm')['enabled']
finally: finally:
vm.shutdown() vm.shutdown()

136
scripts/python_qmp_updater.py Executable file
View File

@ -0,0 +1,136 @@
#!/usr/bin/env python3
#
# Intended usage:
#
# git grep -l '\.qmp(' | xargs ./scripts/python_qmp_updater.py
#
import re
import sys
from typing import Optional
start_reg = re.compile(r'^(?P<padding> *)(?P<res>\w+) = (?P<vm>.*).qmp\(',
flags=re.MULTILINE)
success_reg_templ = re.sub('\n *', '', r"""
(\n*{padding}(?P<comment>\#.*$))?
\n*{padding}
(
self.assert_qmp\({res},\ 'return',\ {{}}\)
|
assert\ {res}\['return'\]\ ==\ {{}}
|
assert\ {res}\ ==\ {{'return':\ {{}}}}
|
self.assertEqual\({res}\['return'\],\ {{}}\)
)""")
some_check_templ = re.sub('\n *', '', r"""
(\n*{padding}(?P<comment>\#.*$))?
\s*self.assert_qmp\({res},""")
def tmatch(template: str, text: str,
padding: str, res: str) -> Optional[re.Match[str]]:
return re.match(template.format(padding=padding, res=res), text,
flags=re.MULTILINE)
def find_closing_brace(text: str, start: int) -> int:
"""
Having '(' at text[start] search for pairing ')' and return its index.
"""
assert text[start] == '('
height = 1
for i in range(start + 1, len(text)):
if text[i] == '(':
height += 1
elif text[i] == ')':
height -= 1
if height == 0:
return i
raise ValueError
def update(text: str) -> str:
result = ''
while True:
m = start_reg.search(text)
if m is None:
result += text
break
result += text[:m.start()]
args_ind = m.end()
args_end = find_closing_brace(text, args_ind - 1)
all_args = text[args_ind:args_end].split(',', 1)
name = all_args[0]
args = None if len(all_args) == 1 else all_args[1]
unchanged_call = text[m.start():args_end+1]
text = text[args_end+1:]
padding, res, vm = m.group('padding', 'res', 'vm')
m = tmatch(success_reg_templ, text, padding, res)
if m is None:
result += unchanged_call
if ('query-' not in name and
'x-debug-block-dirty-bitmap-sha256' not in name and
not tmatch(some_check_templ, text, padding, res)):
print(unchanged_call + text[:200] + '...\n\n')
continue
if m.group('comment'):
result += f'{padding}{m.group("comment")}\n'
result += f'{padding}{vm}.cmd({name}'
if args:
result += ','
if '\n' in args:
m_args = re.search('(?P<pad> *).*$', args)
assert m_args is not None
cur_padding = len(m_args.group('pad'))
expected = len(f'{padding}{res} = {vm}.qmp(')
drop = len(f'{res} = ')
if cur_padding == expected - 1:
# tolerate this bad style
drop -= 1
elif cur_padding < expected - 1:
# assume nothing to do
drop = 0
if drop:
args = re.sub('\n' + ' ' * drop, '\n', args)
result += args
result += ')'
text = text[m.end():]
return result
for fname in sys.argv[1:]:
print(fname)
with open(fname) as f:
t = f.read()
t = update(t)
with open(fname, 'w') as f:
f.write(t)

View File

@ -43,13 +43,13 @@ def render_block_graph(qmp, filename, format='png'):
representation in @format into "@filename.@format" representation in @format into "@filename.@format"
''' '''
bds_nodes = qmp.command('query-named-block-nodes') bds_nodes = qmp.cmd('query-named-block-nodes')
bds_nodes = {n['node-name']: n for n in bds_nodes} bds_nodes = {n['node-name']: n for n in bds_nodes}
job_nodes = qmp.command('query-block-jobs') job_nodes = qmp.cmd('query-block-jobs')
job_nodes = {n['device']: n for n in job_nodes} job_nodes = {n['device']: n for n in job_nodes}
block_graph = qmp.command('x-debug-query-block-graph') block_graph = qmp.cmd('x-debug-query-block-graph')
graph = Digraph(comment='Block Nodes Graph') graph = Digraph(comment='Block Nodes Graph')
graph.format = format graph.format = format
@ -94,7 +94,7 @@ class LibvirtGuest():
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
def command(self, cmd): def cmd(self, cmd):
# only supports qmp commands without parameters # only supports qmp commands without parameters
m = {'execute': cmd} m = {'execute': cmd}
ar = ['virsh', 'qemu-monitor-command', self.name, json.dumps(m)] ar = ['virsh', 'qemu-monitor-command', self.name, json.dumps(m)]

View File

@ -92,17 +92,14 @@ class QEMUBitsMachine(QEMUMachine): # pylint: disable=too-few-public-methods
base_temp_dir: str = "/var/tmp", base_temp_dir: str = "/var/tmp",
debugcon_log: str = "debugcon-log.txt", debugcon_log: str = "debugcon-log.txt",
debugcon_addr: str = "0x403", debugcon_addr: str = "0x403",
sock_dir: Optional[str] = None,
qmp_timer: Optional[float] = None): qmp_timer: Optional[float] = None):
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
if name is None: if name is None:
name = "qemu-bits-%d" % os.getpid() name = "qemu-bits-%d" % os.getpid()
if sock_dir is None:
sock_dir = base_temp_dir
super().__init__(binary, args, wrapper=wrapper, name=name, super().__init__(binary, args, wrapper=wrapper, name=name,
base_temp_dir=base_temp_dir, base_temp_dir=base_temp_dir,
sock_dir=sock_dir, qmp_timer=qmp_timer) qmp_timer=qmp_timer)
self.debugcon_log = debugcon_log self.debugcon_log = debugcon_log
self.debugcon_addr = debugcon_addr self.debugcon_addr = debugcon_addr
self.base_temp_dir = base_temp_dir self.base_temp_dir = base_temp_dir

View File

@ -322,7 +322,7 @@ class QemuSystemTest(QemuBaseTest):
def _new_vm(self, name, *args): def _new_vm(self, name, *args):
self._sd = tempfile.TemporaryDirectory(prefix="qemu_") self._sd = tempfile.TemporaryDirectory(prefix="qemu_")
vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir, vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir,
sock_dir=self._sd.name, log_dir=self.logdir) log_dir=self.logdir)
self.log.debug('QEMUMachine "%s" created', name) self.log.debug('QEMUMachine "%s" created', name)
self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir) self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir)
self.log.debug('QEMUMachine "%s" log_dir: %s', name, vm.log_dir) self.log.debug('QEMUMachine "%s" log_dir: %s', name, vm.log_dir)
@ -408,8 +408,8 @@ class LinuxSSHMixIn:
def ssh_connect(self, username, credential, credential_is_key=True): def ssh_connect(self, username, credential, credential_is_key=True):
self.ssh_logger = logging.getLogger('ssh') self.ssh_logger = logging.getLogger('ssh')
res = self.vm.command('human-monitor-command', res = self.vm.cmd('human-monitor-command',
command_line='info usernet') command_line='info usernet')
port = get_info_usernet_hostfwd_port(res) port = get_info_usernet_hostfwd_port(res)
self.assertIsNotNone(port) self.assertIsNotNone(port)
self.assertGreater(port, 0) self.assertGreater(port, 0)

View File

@ -23,12 +23,13 @@ class QueryCPUModelExpansion(QemuSystemTest):
self.vm.add_args('-S') self.vm.add_args('-S')
self.vm.launch() self.vm.launch()
cpus = self.vm.command('query-cpu-definitions') cpus = self.vm.cmd('query-cpu-definitions')
for c in cpus: for c in cpus:
self.log.info("Checking CPU: %s", c) self.log.info("Checking CPU: %s", c)
self.assertNotIn('', c['unavailable-features'], c['name']) self.assertNotIn('', c['unavailable-features'], c['name'])
for c in cpus: for c in cpus:
model = {'name': c['name']} model = {'name': c['name']}
e = self.vm.command('query-cpu-model-expansion', model=model, type='full') e = self.vm.cmd('query-cpu-model-expansion', model=model,
type='full')
self.assertEquals(e['model']['name'], c['name']) self.assertEquals(e['model']['name'], c['name'])

View File

@ -29,9 +29,9 @@ class HotPlugCPU(LinuxTest):
with self.assertRaises(AssertionError): with self.assertRaises(AssertionError):
self.ssh_command('test -e /sys/devices/system/cpu/cpu1') self.ssh_command('test -e /sys/devices/system/cpu/cpu1')
self.vm.command('device_add', self.vm.cmd('device_add',
driver='Haswell-x86_64-cpu', driver='Haswell-x86_64-cpu',
socket_id=0, socket_id=0,
core_id=1, core_id=1,
thread_id=0) thread_id=0)
self.ssh_command('test -e /sys/devices/system/cpu/cpu1') self.ssh_command('test -e /sys/devices/system/cpu/cpu1')

View File

@ -22,8 +22,8 @@ class InfoUsernet(QemuSystemTest):
self.require_netdev('user') self.require_netdev('user')
self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22') self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22')
self.vm.launch() self.vm.launch()
res = self.vm.command('human-monitor-command', res = self.vm.cmd('human-monitor-command',
command_line='info usernet') command_line='info usernet')
port = get_info_usernet_hostfwd_port(res) port = get_info_usernet_hostfwd_port(res)
self.assertIsNotNone(port, self.assertIsNotNone(port,
('"info usernet" output content does not seem to ' ('"info usernet" output content does not seem to '

View File

@ -81,9 +81,9 @@ class IntegratorMachine(QemuSystemTest):
self.boot_integratorcp() self.boot_integratorcp()
framebuffer_ready = 'Console: switching to colour frame buffer device' framebuffer_ready = 'Console: switching to colour frame buffer device'
wait_for_console_pattern(self, framebuffer_ready) wait_for_console_pattern(self, framebuffer_ready)
self.vm.command('human-monitor-command', command_line='stop') self.vm.cmd('human-monitor-command', command_line='stop')
self.vm.command('human-monitor-command', self.vm.cmd('human-monitor-command',
command_line='screendump %s' % screendump_path) command_line='screendump %s' % screendump_path)
logger = logging.getLogger('framebuffer') logger = logging.getLogger('framebuffer')
cpu_count = 1 cpu_count = 1

View File

@ -181,8 +181,8 @@ class AST2x00Machine(QemuSystemTest):
'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
exec_command_and_wait_for_pattern(self, exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '0') 'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
self.vm.command('qom-set', path='/machine/peripheral/tmp-test', self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
property='temperature', value=18000); property='temperature', value=18000);
exec_command_and_wait_for_pattern(self, exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
@ -213,8 +213,8 @@ class AST2x00Machine(QemuSystemTest):
'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
exec_command_and_wait_for_pattern(self, exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon0/temp1_input', '0') 'cat /sys/class/hwmon/hwmon0/temp1_input', '0')
self.vm.command('qom-set', path='/machine/peripheral/tmp-test', self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
property='temperature', value=18000); property='temperature', value=18000);
exec_command_and_wait_for_pattern(self, exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon0/temp1_input', '18000') 'cat /sys/class/hwmon/hwmon0/temp1_input', '18000')
@ -247,7 +247,10 @@ class AST2x00Machine(QemuSystemTest):
image_path = self.fetch_asset(image_url, asset_hash=image_hash, image_path = self.fetch_asset(image_url, asset_hash=image_hash,
algorithm='sha256') algorithm='sha256')
socket = os.path.join(self.vm.sock_dir, 'swtpm-socket') # force creation of VM object, which also defines self._sd
vm = self.vm
socket = os.path.join(self._sd.name, 'swtpm-socket')
subprocess.run(['swtpm', 'socket', '-d', '--tpm2', subprocess.run(['swtpm', 'socket', '-d', '--tpm2',
'--tpmstate', f'dir={self.vm.temp_dir}', '--tpmstate', f'dir={self.vm.temp_dir}',
@ -357,8 +360,8 @@ class AST2x00MachineSDK(QemuSystemTest, LinuxSSHMixIn):
'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d'); 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d');
self.ssh_command_output_contains( self.ssh_command_output_contains(
'cat /sys/class/hwmon/hwmon19/temp1_input', '0') 'cat /sys/class/hwmon/hwmon19/temp1_input', '0')
self.vm.command('qom-set', path='/machine/peripheral/tmp-test', self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
property='temperature', value=18000); property='temperature', value=18000);
self.ssh_command_output_contains( self.ssh_command_output_contains(
'cat /sys/class/hwmon/hwmon19/temp1_input', '18000') 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000')

View File

@ -43,8 +43,8 @@ class NextCubeMachine(QemuSystemTest):
# 'displaysurface_create 1120x832' trace-event. # 'displaysurface_create 1120x832' trace-event.
time.sleep(2) time.sleep(2)
self.vm.command('human-monitor-command', self.vm.cmd('human-monitor-command',
command_line='screendump %s' % screenshot_path) command_line='screendump %s' % screenshot_path)
@skipUnless(PIL_AVAILABLE, 'Python PIL not installed') @skipUnless(PIL_AVAILABLE, 'Python PIL not installed')
def test_bootrom_framebuffer_size(self): def test_bootrom_framebuffer_size(self):

View File

@ -71,9 +71,9 @@ class MaltaMachineFramebuffer(QemuSystemTest):
framebuffer_ready = 'Console: switching to colour frame buffer device' framebuffer_ready = 'Console: switching to colour frame buffer device'
wait_for_console_pattern(self, framebuffer_ready, wait_for_console_pattern(self, framebuffer_ready,
failure_message='Kernel panic - not syncing') failure_message='Kernel panic - not syncing')
self.vm.command('human-monitor-command', command_line='stop') self.vm.cmd('human-monitor-command', command_line='stop')
self.vm.command('human-monitor-command', self.vm.cmd('human-monitor-command',
command_line='screendump %s' % screendump_path) command_line='screendump %s' % screendump_path)
logger = logging.getLogger('framebuffer') logger = logging.getLogger('framebuffer')
match_threshold = 0.95 match_threshold = 0.95

View File

@ -107,10 +107,10 @@ class S390CCWVirtioMachine(QemuSystemTest):
'dd if=/dev/hwrng of=/dev/null bs=1k count=10', 'dd if=/dev/hwrng of=/dev/null bs=1k count=10',
'10+0 records out') '10+0 records out')
self.clear_guest_dmesg() self.clear_guest_dmesg()
self.vm.command('device_del', id='rn1') self.vm.cmd('device_del', id='rn1')
self.wait_for_crw_reports() self.wait_for_crw_reports()
self.clear_guest_dmesg() self.clear_guest_dmesg()
self.vm.command('device_del', id='rn2') self.vm.cmd('device_del', id='rn2')
self.wait_for_crw_reports() self.wait_for_crw_reports()
exec_command_and_wait_for_pattern(self, exec_command_and_wait_for_pattern(self,
'dd if=/dev/hwrng of=/dev/null bs=1k count=10', 'dd if=/dev/hwrng of=/dev/null bs=1k count=10',
@ -132,8 +132,8 @@ class S390CCWVirtioMachine(QemuSystemTest):
'0x0000000c') '0x0000000c')
# add another device # add another device
self.clear_guest_dmesg() self.clear_guest_dmesg()
self.vm.command('device_add', driver='virtio-net-ccw', self.vm.cmd('device_add', driver='virtio-net-ccw',
devno='fe.0.4711', id='net_4711') devno='fe.0.4711', id='net_4711')
self.wait_for_crw_reports() self.wait_for_crw_reports()
exec_command_and_wait_for_pattern(self, 'for i in 1 2 3 4 5 6 7 ; do ' exec_command_and_wait_for_pattern(self, 'for i in 1 2 3 4 5 6 7 ; do '
'if [ -e /sys/bus/ccw/devices/*4711 ]; then break; fi ;' 'if [ -e /sys/bus/ccw/devices/*4711 ]; then break; fi ;'
@ -141,7 +141,7 @@ class S390CCWVirtioMachine(QemuSystemTest):
'0.0.4711') '0.0.4711')
# and detach it again # and detach it again
self.clear_guest_dmesg() self.clear_guest_dmesg()
self.vm.command('device_del', id='net_4711') self.vm.cmd('device_del', id='net_4711')
self.vm.event_wait(name='DEVICE_DELETED', self.vm.event_wait(name='DEVICE_DELETED',
match={'data': {'device': 'net_4711'}}) match={'data': {'device': 'net_4711'}})
self.wait_for_crw_reports() self.wait_for_crw_reports()
@ -151,10 +151,10 @@ class S390CCWVirtioMachine(QemuSystemTest):
# test the virtio-balloon device # test the virtio-balloon device
exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo',
'MemTotal: 115640 kB') 'MemTotal: 115640 kB')
self.vm.command('human-monitor-command', command_line='balloon 96') self.vm.cmd('human-monitor-command', command_line='balloon 96')
exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo',
'MemTotal: 82872 kB') 'MemTotal: 82872 kB')
self.vm.command('human-monitor-command', command_line='balloon 128') self.vm.cmd('human-monitor-command', command_line='balloon 128')
exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo', exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo',
'MemTotal: 115640 kB') 'MemTotal: 115640 kB')
@ -245,7 +245,7 @@ class S390CCWVirtioMachine(QemuSystemTest):
'12+0 records out') '12+0 records out')
with tempfile.NamedTemporaryFile(suffix='.ppm', with tempfile.NamedTemporaryFile(suffix='.ppm',
prefix='qemu-scrdump-') as ppmfile: prefix='qemu-scrdump-') as ppmfile:
self.vm.command('screendump', filename=ppmfile.name) self.vm.cmd('screendump', filename=ppmfile.name)
ppmfile.seek(0) ppmfile.seek(0)
line = ppmfile.readline() line = ppmfile.readline()
self.assertEqual(line, b"P6\n") self.assertEqual(line, b"P6\n")
@ -261,16 +261,16 @@ class S390CCWVirtioMachine(QemuSystemTest):
# Hot-plug a virtio-crypto device and see whether it gets accepted # Hot-plug a virtio-crypto device and see whether it gets accepted
self.log.info("Test hot-plug virtio-crypto device") self.log.info("Test hot-plug virtio-crypto device")
self.clear_guest_dmesg() self.clear_guest_dmesg()
self.vm.command('object-add', qom_type='cryptodev-backend-builtin', self.vm.cmd('object-add', qom_type='cryptodev-backend-builtin',
id='cbe0') id='cbe0')
self.vm.command('device_add', driver='virtio-crypto-ccw', id='crypdev0', self.vm.cmd('device_add', driver='virtio-crypto-ccw', id='crypdev0',
cryptodev='cbe0', devno='fe.0.2342') cryptodev='cbe0', devno='fe.0.2342')
exec_command_and_wait_for_pattern(self, exec_command_and_wait_for_pattern(self,
'while ! (dmesg -c | grep Accelerator.device) ; do' 'while ! (dmesg -c | grep Accelerator.device) ; do'
' sleep 1 ; done', 'Accelerator device is ready') ' sleep 1 ; done', 'Accelerator device is ready')
exec_command_and_wait_for_pattern(self, 'lscss', '0.0.2342') exec_command_and_wait_for_pattern(self, 'lscss', '0.0.2342')
self.vm.command('device_del', id='crypdev0') self.vm.cmd('device_del', id='crypdev0')
self.vm.command('object-del', id='cbe0') self.vm.cmd('object-del', id='cbe0')
exec_command_and_wait_for_pattern(self, exec_command_and_wait_for_pattern(self,
'while ! (dmesg -c | grep Start.virtcrypto_remove) ; do' 'while ! (dmesg -c | grep Start.virtcrypto_remove) ; do'
' sleep 1 ; done', 'Start virtcrypto_remove.') ' sleep 1 ; done', 'Start virtcrypto_remove.')

View File

@ -30,7 +30,7 @@ class MigrationTest(QemuSystemTest):
@staticmethod @staticmethod
def migration_finished(vm): def migration_finished(vm):
return vm.command('query-migrate')['status'] in ('completed', 'failed') return vm.cmd('query-migrate')['status'] in ('completed', 'failed')
def assert_migration(self, src_vm, dst_vm): def assert_migration(self, src_vm, dst_vm):
wait.wait_for(self.migration_finished, wait.wait_for(self.migration_finished,
@ -41,10 +41,10 @@ class MigrationTest(QemuSystemTest):
timeout=self.timeout, timeout=self.timeout,
step=0.1, step=0.1,
args=(dst_vm,)) args=(dst_vm,))
self.assertEqual(src_vm.command('query-migrate')['status'], 'completed') self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed')
self.assertEqual(dst_vm.command('query-migrate')['status'], 'completed') self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed')
self.assertEqual(dst_vm.command('query-status')['status'], 'running') self.assertEqual(dst_vm.cmd('query-status')['status'], 'running')
self.assertEqual(src_vm.command('query-status')['status'],'postmigrate') self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate')
def do_migrate(self, dest_uri, src_uri=None): def do_migrate(self, dest_uri, src_uri=None):
dest_vm = self.get_vm('-incoming', dest_uri) dest_vm = self.get_vm('-incoming', dest_uri)

View File

@ -32,4 +32,4 @@ class OmittedCPUProps(QemuSystemTest):
self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8') self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8')
self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0') self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0')
self.vm.launch() self.vm.launch()
self.assertEquals(len(self.vm.command('query-cpus-fast')), 2) self.assertEquals(len(self.vm.cmd('query-cpus-fast')), 2)

View File

@ -20,6 +20,6 @@ class Version(QemuSystemTest):
def test_qmp_human_info_version(self): def test_qmp_human_info_version(self):
self.vm.add_args('-nodefaults') self.vm.add_args('-nodefaults')
self.vm.launch() self.vm.launch()
res = self.vm.command('human-monitor-command', res = self.vm.cmd('human-monitor-command',
command_line='info version') command_line='info version')
self.assertRegexpMatches(res, r'^(\d+\.\d+\.\d)') self.assertRegexpMatches(res, r'^(\d+\.\d+\.\d)')

View File

@ -51,8 +51,8 @@ class VirtioMaxSegSettingsCheck(QemuSystemTest):
error = None error = None
props = None props = None
output = vm.command('human-monitor-command', output = vm.cmd('human-monitor-command',
command_line = 'info qtree') command_line = 'info qtree')
props_list = DEV_TYPES[dev_type_name].values(); props_list = DEV_TYPES[dev_type_name].values();
pattern = self.make_pattern(props_list) pattern = self.make_pattern(props_list)
res = re.findall(pattern, output) res = re.findall(pattern, output)
@ -121,7 +121,7 @@ class VirtioMaxSegSettingsCheck(QemuSystemTest):
# collect all machine types except 'none', 'isapc', 'microvm' # collect all machine types except 'none', 'isapc', 'microvm'
with QEMUMachine(self.qemu_bin) as vm: with QEMUMachine(self.qemu_bin) as vm:
vm.launch() vm.launch()
machines = [m['name'] for m in vm.command('query-machines')] machines = [m['name'] for m in vm.cmd('query-machines')]
vm.shutdown() vm.shutdown()
machines.remove('none') machines.remove('none')
machines.remove('isapc') machines.remove('isapc')

View File

@ -48,7 +48,8 @@ def pci_modern_device_id(virtio_devid):
return virtio_devid + 0x1040 return virtio_devid + 0x1040
def devtype_implements(vm, devtype, implements): def devtype_implements(vm, devtype, implements):
return devtype in [d['name'] for d in vm.command('qom-list-types', implements=implements)] return devtype in [d['name'] for d in
vm.cmd('qom-list-types', implements=implements)]
def get_pci_interfaces(vm, devtype): def get_pci_interfaces(vm, devtype):
interfaces = ('pci-express-device', 'conventional-pci-device') interfaces = ('pci-express-device', 'conventional-pci-device')
@ -78,7 +79,7 @@ class VirtioVersionCheck(QemuSystemTest):
vm.add_args('-S') vm.add_args('-S')
vm.launch() vm.launch()
pcibuses = vm.command('query-pci') pcibuses = vm.cmd('query-pci')
alldevs = [dev for bus in pcibuses for dev in bus['devices']] alldevs = [dev for bus in pcibuses for dev in bus['devices']]
devfortest = [dev for dev in alldevs devfortest = [dev for dev in alldevs
if dev['qdev_id'] == 'devfortest'] if dev['qdev_id'] == 'devfortest']

View File

@ -88,9 +88,8 @@ class Vnc(QemuSystemTest):
self.vm.add_args('-nodefaults', '-S', '-vnc', ':0,password=on') self.vm.add_args('-nodefaults', '-S', '-vnc', ':0,password=on')
self.vm.launch() self.vm.launch()
self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled']) self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
set_password_response = self.vm.qmp('change-vnc-password', self.vm.cmd('change-vnc-password',
password='new_password') password='new_password')
self.assertEqual(set_password_response['return'], {})
def test_change_listen(self): def test_change_listen(self):
a, b, c = find_free_ports(3) a, b, c = find_free_ports(3)
@ -105,12 +104,11 @@ class Vnc(QemuSystemTest):
self.assertFalse(check_connect(b)) self.assertFalse(check_connect(b))
self.assertFalse(check_connect(c)) self.assertFalse(check_connect(c))
res = self.vm.qmp('display-update', type='vnc', self.vm.cmd('display-update', type='vnc',
addresses=[{'type': 'inet', 'host': VNC_ADDR, addresses=[{'type': 'inet', 'host': VNC_ADDR,
'port': str(b)}, 'port': str(b)},
{'type': 'inet', 'host': VNC_ADDR, {'type': 'inet', 'host': VNC_ADDR,
'port': str(c)}]) 'port': str(c)}])
self.assertEqual(res['return'], {})
self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(b)) self.assertEqual(self.vm.qmp('query-vnc')['return']['service'], str(b))
self.assertFalse(check_connect(a)) self.assertFalse(check_connect(a))
self.assertTrue(check_connect(b)) self.assertTrue(check_connect(b))

View File

@ -84,7 +84,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
# with older QEMU versions that didn't have the versioned CPU model # with older QEMU versions that didn't have the versioned CPU model
self.vm.add_args('-S') self.vm.add_args('-S')
self.vm.launch() self.vm.launch()
cpus = dict((m['name'], m) for m in self.vm.command('query-cpu-definitions')) cpus = dict((m['name'], m) for m in
self.vm.cmd('query-cpu-definitions'))
self.assertFalse(cpus['Cascadelake-Server']['static'], self.assertFalse(cpus['Cascadelake-Server']['static'],
'unversioned Cascadelake-Server CPU model must not be static') 'unversioned Cascadelake-Server CPU model must not be static')
@ -115,7 +116,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
self.vm.add_args('-S') self.vm.add_args('-S')
self.vm.launch() self.vm.launch()
cpus = dict((m['name'], m) for m in self.vm.command('query-cpu-definitions')) cpus = dict((m['name'], m) for m in
self.vm.cmd('query-cpu-definitions'))
self.assertFalse(cpus['Cascadelake-Server']['static'], self.assertFalse(cpus['Cascadelake-Server']['static'],
'unversioned Cascadelake-Server CPU model must not be static') 'unversioned Cascadelake-Server CPU model must not be static')
@ -220,7 +222,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
self.vm.add_args('-S') self.vm.add_args('-S')
self.vm.launch() self.vm.launch()
cpus = dict((m['name'], m) for m in self.vm.command('query-cpu-definitions')) cpus = dict((m['name'], m) for m in
self.vm.cmd('query-cpu-definitions'))
self.assertFalse(cpus['Cascadelake-Server']['static'], self.assertFalse(cpus['Cascadelake-Server']['static'],
'unversioned Cascadelake-Server CPU model must not be static') 'unversioned Cascadelake-Server CPU model must not be static')
@ -246,8 +249,8 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
:avocado: tags=arch:x86_64 :avocado: tags=arch:x86_64
""" """
def get_cpu_prop(self, prop): def get_cpu_prop(self, prop):
cpu_path = self.vm.command('query-cpus-fast')[0].get('qom-path') cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
return self.vm.command('qom-get', path=cpu_path, property=prop) return self.vm.cmd('qom-get', path=cpu_path, property=prop)
def test_4_1(self): def test_4_1(self):
""" """

View File

@ -11,7 +11,11 @@ ENV PACKAGES \
python3-pip \ python3-pip \
python3-tox \ python3-tox \
python3-virtualenv \ python3-virtualenv \
python3.10 python3.10 \
python3.11 \
python3.12 \
python3.8 \
python3.9
RUN dnf install -y $PACKAGES RUN dnf install -y $PACKAGES
RUN rpm -q $PACKAGES | sort > /packages.txt RUN rpm -q $PACKAGES | sort > /packages.txt

View File

@ -77,7 +77,7 @@ class Engine(object):
return TimingRecord(pid, now, 1000 * (stime + utime) / jiffies_per_sec) return TimingRecord(pid, now, 1000 * (stime + utime) / jiffies_per_sec)
def _migrate_progress(self, vm): def _migrate_progress(self, vm):
info = vm.command("query-migrate") info = vm.cmd("query-migrate")
if "ram" not in info: if "ram" not in info:
info["ram"] = {} info["ram"] = {}
@ -109,7 +109,7 @@ class Engine(object):
src_vcpu_time = [] src_vcpu_time = []
src_pid = src.get_pid() src_pid = src.get_pid()
vcpus = src.command("query-cpus-fast") vcpus = src.cmd("query-cpus-fast")
src_threads = [] src_threads = []
for vcpu in vcpus: for vcpu in vcpus:
src_threads.append(vcpu["thread-id"]) src_threads.append(vcpu["thread-id"])
@ -128,82 +128,82 @@ class Engine(object):
if self._verbose: if self._verbose:
print("Starting migration") print("Starting migration")
if scenario._auto_converge: if scenario._auto_converge:
resp = src.command("migrate-set-capabilities", resp = src.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "auto-converge", { "capability": "auto-converge",
"state": True } "state": True }
]) ])
resp = src.command("migrate-set-parameters", resp = src.cmd("migrate-set-parameters",
cpu_throttle_increment=scenario._auto_converge_step) cpu_throttle_increment=scenario._auto_converge_step)
if scenario._post_copy: if scenario._post_copy:
resp = src.command("migrate-set-capabilities", resp = src.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "postcopy-ram", { "capability": "postcopy-ram",
"state": True } "state": True }
]) ])
resp = dst.command("migrate-set-capabilities", resp = dst.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "postcopy-ram", { "capability": "postcopy-ram",
"state": True } "state": True }
]) ])
resp = src.command("migrate-set-parameters", resp = src.cmd("migrate-set-parameters",
max_bandwidth=scenario._bandwidth * 1024 * 1024) max_bandwidth=scenario._bandwidth * 1024 * 1024)
resp = src.command("migrate-set-parameters", resp = src.cmd("migrate-set-parameters",
downtime_limit=scenario._downtime) downtime_limit=scenario._downtime)
if scenario._compression_mt: if scenario._compression_mt:
resp = src.command("migrate-set-capabilities", resp = src.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "compress", { "capability": "compress",
"state": True } "state": True }
]) ])
resp = src.command("migrate-set-parameters", resp = src.cmd("migrate-set-parameters",
compress_threads=scenario._compression_mt_threads) compress_threads=scenario._compression_mt_threads)
resp = dst.command("migrate-set-capabilities", resp = dst.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "compress", { "capability": "compress",
"state": True } "state": True }
]) ])
resp = dst.command("migrate-set-parameters", resp = dst.cmd("migrate-set-parameters",
decompress_threads=scenario._compression_mt_threads) decompress_threads=scenario._compression_mt_threads)
if scenario._compression_xbzrle: if scenario._compression_xbzrle:
resp = src.command("migrate-set-capabilities", resp = src.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "xbzrle", { "capability": "xbzrle",
"state": True } "state": True }
]) ])
resp = dst.command("migrate-set-capabilities", resp = dst.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "xbzrle", { "capability": "xbzrle",
"state": True } "state": True }
]) ])
resp = src.command("migrate-set-parameters", resp = src.cmd("migrate-set-parameters",
xbzrle_cache_size=( xbzrle_cache_size=(
hardware._mem * hardware._mem *
1024 * 1024 * 1024 / 100 * 1024 * 1024 * 1024 / 100 *
scenario._compression_xbzrle_cache)) scenario._compression_xbzrle_cache))
if scenario._multifd: if scenario._multifd:
resp = src.command("migrate-set-capabilities", resp = src.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "multifd", { "capability": "multifd",
"state": True } "state": True }
]) ])
resp = src.command("migrate-set-parameters", resp = src.cmd("migrate-set-parameters",
multifd_channels=scenario._multifd_channels) multifd_channels=scenario._multifd_channels)
resp = dst.command("migrate-set-capabilities", resp = dst.cmd("migrate-set-capabilities",
capabilities = [ capabilities = [
{ "capability": "multifd", { "capability": "multifd",
"state": True } "state": True }
]) ])
resp = dst.command("migrate-set-parameters", resp = dst.cmd("migrate-set-parameters",
multifd_channels=scenario._multifd_channels) multifd_channels=scenario._multifd_channels)
resp = src.command("migrate", uri=connect_uri) resp = src.cmd("migrate", uri=connect_uri)
post_copy = False post_copy = False
paused = False paused = False
@ -228,7 +228,7 @@ class Engine(object):
if progress._status in ("completed", "failed", "cancelled"): if progress._status in ("completed", "failed", "cancelled"):
if progress._status == "completed" and paused: if progress._status == "completed" and paused:
dst.command("cont") dst.cmd("cont")
if progress_history[-1] != progress: if progress_history[-1] != progress:
progress_history.append(progress) progress_history.append(progress)
@ -256,13 +256,13 @@ class Engine(object):
if progress._ram._iterations > scenario._max_iters: if progress._ram._iterations > scenario._max_iters:
if self._verbose: if self._verbose:
print("No completion after %d iterations over RAM" % scenario._max_iters) print("No completion after %d iterations over RAM" % scenario._max_iters)
src.command("migrate_cancel") src.cmd("migrate_cancel")
continue continue
if time.time() > (start + scenario._max_time): if time.time() > (start + scenario._max_time):
if self._verbose: if self._verbose:
print("No completion after %d seconds" % scenario._max_time) print("No completion after %d seconds" % scenario._max_time)
src.command("migrate_cancel") src.cmd("migrate_cancel")
continue continue
if (scenario._post_copy and if (scenario._post_copy and
@ -270,7 +270,7 @@ class Engine(object):
not post_copy): not post_copy):
if self._verbose: if self._verbose:
print("Switching to post-copy after %d iterations" % scenario._post_copy_iters) print("Switching to post-copy after %d iterations" % scenario._post_copy_iters)
resp = src.command("migrate-start-postcopy") resp = src.cmd("migrate-start-postcopy")
post_copy = True post_copy = True
if (scenario._pause and if (scenario._pause and
@ -278,7 +278,7 @@ class Engine(object):
not paused): not paused):
if self._verbose: if self._verbose:
print("Pausing VM after %d iterations" % scenario._pause_iters) print("Pausing VM after %d iterations" % scenario._pause_iters)
resp = src.command("stop") resp = src.cmd("stop")
paused = True paused = True
def _is_ppc64le(self): def _is_ppc64le(self):

View File

@ -56,8 +56,7 @@ class TestSingleDrive(iotests.QMPTestCase):
def test_stream(self): def test_stream(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -77,8 +76,7 @@ class TestSingleDrive(iotests.QMPTestCase):
qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', mid_img).stdout, qemu_io('-f', iotests.imgfmt, '-rU', '-c', 'map', mid_img).stdout,
'image file map matches backing file before streaming') 'image file map matches backing file before streaming')
result = self.vm.qmp('block-stream', device='mid', job_id='stream-mid') self.vm.cmd('block-stream', device='mid', job_id='stream-mid')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='stream-mid') self.wait_until_completed(drive='stream-mid')
@ -94,8 +92,7 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
self.pause_job('drive0', wait=False) self.pause_job('drive0', wait=False)
self.vm.resume_drive('drive0') self.vm.resume_drive('drive0')
@ -108,8 +105,7 @@ class TestSingleDrive(iotests.QMPTestCase):
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/offset', offset) self.assert_qmp(result, 'return[0]/offset', offset)
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -129,8 +125,7 @@ class TestSingleDrive(iotests.QMPTestCase):
'-f', iotests.imgfmt, '-rU', '-c', 'map', test_img).stdout '-f', iotests.imgfmt, '-rU', '-c', 'map', test_img).stdout
# This is a no-op: no data should ever be copied from the base image # This is a no-op: no data should ever be copied from the base image
result = self.vm.qmp('block-stream', device='drive0', base=mid_img) self.vm.cmd('block-stream', device='drive0', base=mid_img)
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -144,8 +139,7 @@ class TestSingleDrive(iotests.QMPTestCase):
def test_stream_partial(self): def test_stream_partial(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0', base=backing_img) self.vm.cmd('block-stream', device='drive0', base=backing_img)
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -172,24 +166,22 @@ class TestSingleDrive(iotests.QMPTestCase):
qemu_img('create', '-f', iotests.imgfmt, ro_top_path, qemu_img('create', '-f', iotests.imgfmt, ro_top_path,
str(self.image_len)) str(self.image_len))
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='ro-top', node_name='ro-top',
driver=iotests.imgfmt, driver=iotests.imgfmt,
read_only=True, read_only=True,
file={ file={
'driver': 'file', 'driver': 'file',
'filename': ro_top_path, 'filename': ro_top_path,
'read-only': True 'read-only': True
}, },
backing='mid') backing='mid')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-stream', job_id='stream', result = self.vm.qmp('block-stream', job_id='stream',
device='ro-top', base_node='base') device='ro-top', base_node='base')
self.assert_qmp(result, 'error/desc', 'Block node is read-only') self.assert_qmp(result, 'error/desc', 'Block node is read-only')
result = self.vm.qmp('blockdev-del', node_name='ro-top') self.vm.cmd('blockdev-del', node_name='ro-top')
self.assert_qmp(result, 'return', {})
class TestParallelOps(iotests.QMPTestCase): class TestParallelOps(iotests.QMPTestCase):
@ -254,10 +246,9 @@ class TestParallelOps(iotests.QMPTestCase):
node_name = 'node%d' % i node_name = 'node%d' % i
job_id = 'stream-%s' % node_name job_id = 'stream-%s' % node_name
pending_jobs.append(job_id) pending_jobs.append(job_id)
result = self.vm.qmp('block-stream', device=node_name, self.vm.cmd('block-stream', device=node_name,
job_id=job_id, bottom=f'node{i-1}', job_id=job_id, bottom=f'node{i-1}',
speed=1024) speed=1024)
self.assert_qmp(result, 'return', {})
# Do this in reverse: After unthrottling them, some jobs may finish # Do this in reverse: After unthrottling them, some jobs may finish
# before we have unthrottled all of them. This will drain their # before we have unthrottled all of them. This will drain their
@ -269,8 +260,7 @@ class TestParallelOps(iotests.QMPTestCase):
# Starting from the top (i.e. in reverse) does not have this problem: # Starting from the top (i.e. in reverse) does not have this problem:
# When a job finishes, the ones below it are not advanced. # When a job finishes, the ones below it are not advanced.
for job in reversed(pending_jobs): for job in reversed(pending_jobs):
result = self.vm.qmp('block-job-set-speed', device=job, speed=0) self.vm.cmd('block-job-set-speed', device=job, speed=0)
self.assert_qmp(result, 'return', {})
# Wait for all jobs to be finished. # Wait for all jobs to be finished.
while len(pending_jobs) > 0: while len(pending_jobs) > 0:
@ -297,10 +287,9 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# Set a speed limit to make sure that this job blocks the rest # Set a speed limit to make sure that this job blocks the rest
result = self.vm.qmp('block-stream', device='node4', self.vm.cmd('block-stream', device='node4',
job_id='stream-node4', base=self.imgs[1], job_id='stream-node4', base=self.imgs[1],
filter_node_name='stream-filter', speed=1024*1024) filter_node_name='stream-filter', speed=1024*1024)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-stream', device='node5', job_id='stream-node5', base=self.imgs[2]) result = self.vm.qmp('block-stream', device='node5', job_id='stream-node5', base=self.imgs[2])
self.assert_qmp(result, 'error/desc', self.assert_qmp(result, 'error/desc',
@ -328,8 +317,7 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_qmp(result, 'error/desc', self.assert_qmp(result, 'error/desc',
"Node 'node2' is busy: block device is in use by block job: stream") "Node 'node2' is busy: block device is in use by block job: stream")
result = self.vm.qmp('block-job-set-speed', device='stream-node4', speed=0) self.vm.cmd('block-job-set-speed', device='stream-node4', speed=0)
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='stream-node4') self.wait_until_completed(drive='stream-node4')
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
@ -341,8 +329,7 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# Set a speed limit to make sure that this job blocks the rest # Set a speed limit to make sure that this job blocks the rest
result = self.vm.qmp('block-commit', device='drive0', top=self.imgs[5], base=self.imgs[3], job_id='commit-node3', speed=1024*1024) self.vm.cmd('block-commit', device='drive0', top=self.imgs[5], base=self.imgs[3], job_id='commit-node3', speed=1024*1024)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-stream', device='node3', job_id='stream-node3') result = self.vm.qmp('block-stream', device='node3', job_id='stream-node3')
self.assert_qmp(result, 'error/desc', self.assert_qmp(result, 'error/desc',
@ -365,8 +352,7 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_qmp(result, 'error/desc', self.assert_qmp(result, 'error/desc',
"Node 'drive0' is busy: block device is in use by block job: commit") "Node 'drive0' is busy: block device is in use by block job: commit")
result = self.vm.qmp('block-job-set-speed', device='commit-node3', speed=0) self.vm.cmd('block-job-set-speed', device='commit-node3', speed=0)
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='commit-node3') self.wait_until_completed(drive='commit-node3')
@ -377,23 +363,20 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# Set a speed limit to make sure that this job blocks the rest # Set a speed limit to make sure that this job blocks the rest
result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[3], job_id='commit-drive0', speed=1024*1024) self.vm.cmd('block-commit', device='drive0', base=self.imgs[3], job_id='commit-drive0', speed=1024*1024)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-stream', device='node5', base=self.imgs[3], job_id='stream-node6') result = self.vm.qmp('block-stream', device='node5', base=self.imgs[3], job_id='stream-node6')
self.assert_qmp(result, 'error/desc', self.assert_qmp(result, 'error/desc',
"Node 'node5' is busy: block device is in use by block job: commit") "Node 'node5' is busy: block device is in use by block job: commit")
result = self.vm.qmp('block-job-set-speed', device='commit-drive0', speed=0) self.vm.cmd('block-job-set-speed', device='commit-drive0', speed=0)
self.assert_qmp(result, 'return', {})
event = self.vm.event_wait(name='BLOCK_JOB_READY') event = self.vm.event_wait(name='BLOCK_JOB_READY')
self.assert_qmp(event, 'data/device', 'commit-drive0') self.assert_qmp(event, 'data/device', 'commit-drive0')
self.assert_qmp(event, 'data/type', 'commit') self.assert_qmp(event, 'data/type', 'commit')
self.assert_qmp_absent(event, 'data/error') self.assert_qmp_absent(event, 'data/error')
result = self.vm.qmp('block-job-complete', device='commit-drive0') self.vm.cmd('block-job-complete', device='commit-drive0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='commit-drive0') self.wait_until_completed(drive='commit-drive0')
@ -404,18 +387,16 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# Commit from node2 into node0 # Commit from node2 into node0
result = self.vm.qmp('block-commit', device='drive0', self.vm.cmd('block-commit', device='drive0',
top=self.imgs[2], base=self.imgs[0], top=self.imgs[2], base=self.imgs[0],
filter_node_name='commit-filter', speed=1024*1024) filter_node_name='commit-filter', speed=1024*1024)
self.assert_qmp(result, 'return', {})
# Stream from node2 into node4 # Stream from node2 into node4
result = self.vm.qmp('block-stream', device='node4', base_node='node2', job_id='node4') result = self.vm.qmp('block-stream', device='node4', base_node='node2', job_id='node4')
self.assert_qmp(result, 'error/desc', self.assert_qmp(result, 'error/desc',
"Cannot freeze 'backing' link to 'commit-filter'") "Cannot freeze 'backing' link to 'commit-filter'")
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) self.vm.cmd('block-job-set-speed', device='drive0', speed=0)
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
@ -428,18 +409,15 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# Commit from node2 into node0 # Commit from node2 into node0
result = self.vm.qmp('block-commit', device='drive0', self.vm.cmd('block-commit', device='drive0',
top_node='node2', base_node='node0', top_node='node2', base_node='node0',
filter_node_name='commit-filter', speed=1024*1024) filter_node_name='commit-filter', speed=1024*1024)
self.assert_qmp(result, 'return', {})
# Stream from node2 into node4 # Stream from node2 into node4
result = self.vm.qmp('block-stream', device='node4', self.vm.cmd('block-stream', device='node4',
base_node='commit-filter', job_id='node4') base_node='commit-filter', job_id='node4')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) self.vm.cmd('block-job-set-speed', device='drive0', speed=0)
self.assert_qmp(result, 'return', {})
self.vm.run_job(job='drive0', auto_dismiss=True) self.vm.run_job(job='drive0', auto_dismiss=True)
self.vm.run_job(job='node4', auto_dismiss=True) self.vm.run_job(job='node4', auto_dismiss=True)
@ -458,12 +436,10 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# Stream from node0 into node2 # Stream from node0 into node2
result = self.vm.qmp('block-stream', device='node2', base_node='node0', job_id='node2') self.vm.cmd('block-stream', device='node2', base_node='node0', job_id='node2')
self.assert_qmp(result, 'return', {})
# Commit from the active layer into node3 # Commit from the active layer into node3
result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[3]) self.vm.cmd('block-commit', device='drive0', base=self.imgs[3])
self.assert_qmp(result, 'return', {})
# Wait for all jobs to be finished. # Wait for all jobs to be finished.
pending_jobs = ['node2', 'drive0'] pending_jobs = ['node2', 'drive0']
@ -490,16 +466,13 @@ class TestParallelOps(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# Stream from node0 into node4 # Stream from node0 into node4
result = self.vm.qmp('block-stream', device='node4', base_node='node0', job_id='node4', speed=1024*1024) self.vm.cmd('block-stream', device='node4', base_node='node0', job_id='node4', speed=1024*1024)
self.assert_qmp(result, 'return', {})
# Commit from the active layer into node5 # Commit from the active layer into node5
result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[5], speed=1024*1024) self.vm.cmd('block-commit', device='drive0', base=self.imgs[5], speed=1024*1024)
self.assert_qmp(result, 'return', {})
for job in ['drive0', 'node4']: for job in ['drive0', 'node4']:
result = self.vm.qmp('block-job-set-speed', device=job, speed=0) self.vm.cmd('block-job-set-speed', device=job, speed=0)
self.assert_qmp(result, 'return', {})
# Wait for all jobs to be finished. # Wait for all jobs to be finished.
pending_jobs = ['node4', 'drive0'] pending_jobs = ['node4', 'drive0']
@ -549,8 +522,7 @@ class TestParallelOps(iotests.QMPTestCase):
"'base' and 'base-node' cannot be specified at the same time") "'base' and 'base-node' cannot be specified at the same time")
# Success: the base node is a backing file of the top node # Success: the base node is a backing file of the top node
result = self.vm.qmp('block-stream', device='node4', base_node='node2', job_id='stream') self.vm.cmd('block-stream', device='node4', base_node='node2', job_id='stream')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='stream') self.wait_until_completed(drive='stream')
@ -606,8 +578,7 @@ class TestQuorum(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='node0', job_id='stream-node0') self.vm.cmd('block-stream', device='node0', job_id='stream-node0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='stream-node0') self.wait_until_completed(drive='stream-node0')
@ -636,8 +607,7 @@ class TestSmallerBackingFile(iotests.QMPTestCase):
def test_stream(self): def test_stream(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -694,8 +664,7 @@ class TestEIO(TestErrors):
def test_report(self): def test_report(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
completed = False completed = False
error = False error = False
@ -722,8 +691,7 @@ class TestEIO(TestErrors):
def test_ignore(self): def test_ignore(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0', on_error='ignore') self.vm.cmd('block-stream', device='drive0', on_error='ignore')
self.assert_qmp(result, 'return', {})
error = False error = False
completed = False completed = False
@ -756,8 +724,7 @@ class TestEIO(TestErrors):
def test_stop(self): def test_stop(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0', on_error='stop') self.vm.cmd('block-stream', device='drive0', on_error='stop')
self.assert_qmp(result, 'return', {})
error = False error = False
completed = False completed = False
@ -779,8 +746,7 @@ class TestEIO(TestErrors):
self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE) self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE)
self.assert_qmp(result, 'return[0]/io-status', 'failed') self.assert_qmp(result, 'return[0]/io-status', 'failed')
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
if result == {'return': []}: if result == {'return': []}:
@ -806,8 +772,7 @@ class TestEIO(TestErrors):
def test_enospc(self): def test_enospc(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0', on_error='enospc') self.vm.cmd('block-stream', device='drive0', on_error='enospc')
self.assert_qmp(result, 'return', {})
completed = False completed = False
error = False error = False
@ -852,8 +817,7 @@ class TestENOSPC(TestErrors):
def test_enospc(self): def test_enospc(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0', on_error='enospc') self.vm.cmd('block-stream', device='drive0', on_error='enospc')
self.assert_qmp(result, 'return', {})
error = False error = False
completed = False completed = False
@ -875,8 +839,7 @@ class TestENOSPC(TestErrors):
self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE) self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE)
self.assert_qmp(result, 'return[0]/io-status', 'nospace') self.assert_qmp(result, 'return[0]/io-status', 'nospace')
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
if result == {'return': []}: if result == {'return': []}:
@ -921,8 +884,7 @@ class TestStreamStop(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
time.sleep(0.1) time.sleep(0.1)
events = self.vm.get_qmp_events(wait=False) events = self.vm.get_qmp_events(wait=False)
@ -955,11 +917,9 @@ class TestSetSpeed(iotests.QMPTestCase):
def perf_test_throughput(self): def perf_test_throughput(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) self.vm.cmd('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -969,16 +929,14 @@ class TestSetSpeed(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
# Default speed is 0 # Default speed is 0
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/device', 'drive0')
self.assert_qmp(result, 'return[0]/speed', 0) self.assert_qmp(result, 'return[0]/speed', 0)
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) self.vm.cmd('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
self.assert_qmp(result, 'return', {})
# Ensure the speed we set was accepted # Ensure the speed we set was accepted
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
@ -989,8 +947,7 @@ class TestSetSpeed(iotests.QMPTestCase):
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
# Check setting speed in block-stream works # Check setting speed in block-stream works
result = self.vm.qmp('block-stream', device='drive0', speed=4 * 1024 * 1024) self.vm.cmd('block-stream', device='drive0', speed=4 * 1024 * 1024)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/device', 'drive0')
@ -1007,8 +964,7 @@ class TestSetSpeed(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp('block-stream', device='drive0') self.vm.cmd('block-stream', device='drive0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1) result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
self.assert_qmp(result, 'error/desc', "Parameter 'speed' expects a non-negative value") self.assert_qmp(result, 'error/desc', "Parameter 'speed' expects a non-negative value")

View File

@ -61,16 +61,14 @@ class ImageCommitTestCase(iotests.QMPTestCase):
def run_commit_test(self, top, base, need_ready=False, node_names=False): def run_commit_test(self, top, base, need_ready=False, node_names=False):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
if node_names: if node_names:
result = self.vm.qmp('block-commit', device='drive0', top_node=top, base_node=base) self.vm.cmd('block-commit', device='drive0', top_node=top, base_node=base)
else: else:
result = self.vm.qmp('block-commit', device='drive0', top=top, base=base) self.vm.cmd('block-commit', device='drive0', top=top, base=base)
self.assert_qmp(result, 'return', {})
self.wait_for_complete(need_ready) self.wait_for_complete(need_ready)
def run_default_commit_test(self): def run_default_commit_test(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-commit', device='drive0') self.vm.cmd('block-commit', device='drive0')
self.assert_qmp(result, 'return', {})
self.wait_for_complete() self.wait_for_complete()
class TestSingleDrive(ImageCommitTestCase): class TestSingleDrive(ImageCommitTestCase):
@ -117,38 +115,30 @@ class TestSingleDrive(ImageCommitTestCase):
@iotests.skip_if_unsupported(['throttle']) @iotests.skip_if_unsupported(['throttle'])
def test_commit_with_filter_and_quit(self): def test_commit_with_filter_and_quit(self):
result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg') self.vm.cmd('object-add', qom_type='throttle-group', id='tg')
self.assert_qmp(result, 'return', {})
# Add a filter outside of the backing chain # Add a filter outside of the backing chain
result = self.vm.qmp('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid') self.vm.cmd('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-commit', device='drive0') self.vm.cmd('block-commit', device='drive0')
self.assert_qmp(result, 'return', {})
# Quit immediately, thus forcing a simultaneous cancel of the # Quit immediately, thus forcing a simultaneous cancel of the
# block job and a bdrv_drain_all() # block job and a bdrv_drain_all()
result = self.vm.qmp('quit') self.vm.cmd('quit')
self.assert_qmp(result, 'return', {})
# Same as above, but this time we add the filter after starting the job # Same as above, but this time we add the filter after starting the job
@iotests.skip_if_unsupported(['throttle']) @iotests.skip_if_unsupported(['throttle'])
def test_commit_plus_filter_and_quit(self): def test_commit_plus_filter_and_quit(self):
result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg') self.vm.cmd('object-add', qom_type='throttle-group', id='tg')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-commit', device='drive0') self.vm.cmd('block-commit', device='drive0')
self.assert_qmp(result, 'return', {})
# Add a filter outside of the backing chain # Add a filter outside of the backing chain
result = self.vm.qmp('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid') self.vm.cmd('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid')
self.assert_qmp(result, 'return', {})
# Quit immediately, thus forcing a simultaneous cancel of the # Quit immediately, thus forcing a simultaneous cancel of the
# block job and a bdrv_drain_all() # block job and a bdrv_drain_all()
result = self.vm.qmp('quit') self.vm.cmd('quit')
self.assert_qmp(result, 'return', {})
def test_device_not_found(self): def test_device_not_found(self):
result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img) result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img)
@ -225,8 +215,7 @@ class TestSingleDrive(ImageCommitTestCase):
def test_top_node_in_wrong_chain(self): def test_top_node_in_wrong_chain(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('blockdev-add', driver='null-co', node_name='null') self.vm.cmd('blockdev-add', driver='null-co', node_name='null')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-commit', device='drive0', top_node='null', base_node='base') result = self.vm.qmp('block-commit', device='drive0', top_node='null', base_node='base')
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
@ -239,11 +228,9 @@ class TestSingleDrive(ImageCommitTestCase):
return return
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-commit', device='drive0', top=mid_img, self.vm.cmd('block-commit', device='drive0', top=mid_img,
base=backing_img, speed=(self.image_len // 4)) base=backing_img, speed=(self.image_len // 4))
self.assert_qmp(result, 'return', {}) self.vm.cmd('device_del', id='scsi0')
result = self.vm.qmp('device_del', id='scsi0')
self.assert_qmp(result, 'return', {})
cancelled = False cancelled = False
deleted = False deleted = False
@ -269,9 +256,8 @@ class TestSingleDrive(ImageCommitTestCase):
return return
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('block-commit', device='drive0', top=mid_img, self.vm.cmd('block-commit', device='drive0', top=mid_img,
base=backing_img, speed=(self.image_len // 4)) base=backing_img, speed=(self.image_len // 4))
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/file', test_img) self.assert_qmp(result, 'return[0]/inserted/file', test_img)
@ -406,8 +392,7 @@ class TestSetSpeed(ImageCommitTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp('block-commit', device='drive0', top=mid_img, speed=1024 * 1024) self.vm.cmd('block-commit', device='drive0', top=mid_img, speed=1024 * 1024)
self.assert_qmp(result, 'return', {})
# Ensure the speed we set was accepted # Ensure the speed we set was accepted
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
@ -480,8 +465,7 @@ class TestErrorHandling(iotests.QMPTestCase):
os.remove(backing_img) os.remove(backing_img)
def blockdev_add(self, **kwargs): def blockdev_add(self, **kwargs):
result = self.vm.qmp('blockdev-add', **kwargs) self.vm.cmd('blockdev-add', **kwargs)
self.assert_qmp(result, 'return', {})
def add_block_nodes(self, base_debug=None, mid_debug=None, top_debug=None): def add_block_nodes(self, base_debug=None, mid_debug=None, top_debug=None):
self.blockdev_add(node_name='base-file', driver='file', self.blockdev_add(node_name='base-file', driver='file',
@ -527,11 +511,9 @@ class TestErrorHandling(iotests.QMPTestCase):
completed = True completed = True
elif ev['event'] == 'BLOCK_JOB_ERROR': elif ev['event'] == 'BLOCK_JOB_ERROR':
if error_pauses_job: if error_pauses_job:
result = self.vm.qmp('block-job-resume', device='job0') self.vm.cmd('block-job-resume', device='job0')
self.assert_qmp(result, 'return', {})
elif ev['event'] == 'BLOCK_JOB_READY': elif ev['event'] == 'BLOCK_JOB_READY':
result = self.vm.qmp('block-job-complete', device='job0') self.vm.cmd('block-job-complete', device='job0')
self.assert_qmp(result, 'return', {})
else: else:
self.fail("Unexpected event: %s" % ev) self.fail("Unexpected event: %s" % ev)
log.append(iotests.filter_qmp_event(ev)) log.append(iotests.filter_qmp_event(ev))
@ -594,11 +576,10 @@ class TestErrorHandling(iotests.QMPTestCase):
self.add_block_nodes(top_debug=top_debug, mid_debug=mid_debug, self.add_block_nodes(top_debug=top_debug, mid_debug=mid_debug,
base_debug=base_debug) base_debug=base_debug)
result = self.vm.qmp('block-commit', job_id='job0', device='top-fmt', self.vm.cmd('block-commit', job_id='job0', device='top-fmt',
top_node='top-fmt' if active else 'mid-fmt', top_node='top-fmt' if active else 'mid-fmt',
base_node='mid-fmt' if active else 'base-fmt', base_node='mid-fmt' if active else 'base-fmt',
on_error=on_error) on_error=on_error)
self.assert_qmp(result, 'return', {})
def testActiveReadErrorReport(self): def testActiveReadErrorReport(self):
self.prepare_and_start_job('report', top_event='read_aio') self.prepare_and_start_job('report', top_event='read_aio')
@ -770,10 +751,9 @@ class TestCommitWithFilters(iotests.QMPTestCase):
self.vm = iotests.VM().add_device('virtio-scsi,id=vio-scsi') self.vm = iotests.VM().add_device('virtio-scsi,id=vio-scsi')
self.vm.launch() self.vm.launch()
result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg') self.vm.cmd('object-add', qom_type='throttle-group', id='tg')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', {
'node-name': 'top-filter', 'node-name': 'top-filter',
'driver': 'throttle', 'driver': 'throttle',
'throttle-group': 'tg', 'throttle-group': 'tg',
@ -815,7 +795,6 @@ class TestCommitWithFilters(iotests.QMPTestCase):
} }
} }
}) })
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
self.vm.shutdown() self.vm.shutdown()
@ -832,13 +811,12 @@ class TestCommitWithFilters(iotests.QMPTestCase):
return self.vm.node_info(node)['image']['filename'] return self.vm.node_info(node)['image']['filename']
def test_filterless_commit(self): def test_filterless_commit(self):
result = self.vm.qmp('block-commit', self.vm.cmd('block-commit',
job_id='commit', job_id='commit',
device='top-filter', device='top-filter',
top_node='cow-2', top_node='cow-2',
base_node='cow-1', base_node='cow-1',
backing_file=self.img1) backing_file=self.img1)
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='commit') self.wait_until_completed(drive='commit')
self.assertIsNotNone(self.vm.node_info('cow-3')) self.assertIsNotNone(self.vm.node_info('cow-3'))
@ -849,13 +827,12 @@ class TestCommitWithFilters(iotests.QMPTestCase):
self.pattern_files[2] = self.img1 self.pattern_files[2] = self.img1
def test_commit_through_filter(self): def test_commit_through_filter(self):
result = self.vm.qmp('block-commit', self.vm.cmd('block-commit',
job_id='commit', job_id='commit',
device='top-filter', device='top-filter',
top_node='cow-1', top_node='cow-1',
base_node='cow-0', base_node='cow-0',
backing_file=self.img0) backing_file=self.img0)
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive='commit') self.wait_until_completed(drive='commit')
self.assertIsNotNone(self.vm.node_info('cow-2')) self.assertIsNotNone(self.vm.node_info('cow-2'))
@ -870,9 +847,8 @@ class TestCommitWithFilters(iotests.QMPTestCase):
# Add a device, so the commit job finds a parent it can change # Add a device, so the commit job finds a parent it can change
# to point to the base node (so we can test that top-filter is # to point to the base node (so we can test that top-filter is
# dropped from the graph) # dropped from the graph)
result = self.vm.qmp('device_add', id='drv0', driver='scsi-hd', self.vm.cmd('device_add', id='drv0', driver='scsi-hd',
bus='vio-scsi.0', drive='top-filter') bus='vio-scsi.0', drive='top-filter')
self.assert_qmp(result, 'return', {})
# Try to release our reference to top-filter; that should not # Try to release our reference to top-filter; that should not
# work because drv0 uses it # work because drv0 uses it
@ -880,16 +856,14 @@ class TestCommitWithFilters(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
self.assert_qmp(result, 'error/desc', 'Node top-filter is in use') self.assert_qmp(result, 'error/desc', 'Node top-filter is in use')
result = self.vm.qmp('block-commit', self.vm.cmd('block-commit',
job_id='commit', job_id='commit',
device='top-filter', device='top-filter',
base_node='cow-2') base_node='cow-2')
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive='commit') self.complete_and_wait(drive='commit')
# Try to release our reference to top-filter again # Try to release our reference to top-filter again
result = self.vm.qmp('blockdev-del', node_name='top-filter') self.vm.cmd('blockdev-del', node_name='top-filter')
self.assert_qmp(result, 'return', {})
self.assertIsNone(self.vm.node_info('top-filter')) self.assertIsNone(self.vm.node_info('top-filter'))
self.assertIsNone(self.vm.node_info('cow-3')) self.assertIsNone(self.vm.node_info('cow-3'))
@ -904,12 +878,11 @@ class TestCommitWithFilters(iotests.QMPTestCase):
self.pattern_files[3] = self.img2 self.pattern_files[3] = self.img2
def test_filtered_active_commit_without_filter(self): def test_filtered_active_commit_without_filter(self):
result = self.vm.qmp('block-commit', self.vm.cmd('block-commit',
job_id='commit', job_id='commit',
device='top-filter', device='top-filter',
top_node='cow-3', top_node='cow-3',
base_node='cow-2') base_node='cow-2')
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive='commit') self.complete_and_wait(drive='commit')
self.assertIsNotNone(self.vm.node_info('top-filter')) self.assertIsNotNone(self.vm.node_info('top-filter'))
@ -934,23 +907,22 @@ class TestCommitWithOverriddenBacking(iotests.QMPTestCase):
self.vm.launch() self.vm.launch()
# Use base_b instead of base_a as the backing of top # Use base_b instead of base_a as the backing of top
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', {
'node-name': 'top', 'node-name': 'top',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
'driver': 'file', 'driver': 'file',
'filename': self.img_top 'filename': self.img_top
}, },
'backing': { 'backing': {
'node-name': 'base', 'node-name': 'base',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
'driver': 'file', 'driver': 'file',
'filename': self.img_base_b 'filename': self.img_base_b
} }
} }
}) })
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
self.vm.shutdown() self.vm.shutdown()
@ -970,11 +942,10 @@ class TestCommitWithOverriddenBacking(iotests.QMPTestCase):
def test_commit_to_b(self): def test_commit_to_b(self):
# Try committing to base_b (which should work, since that is # Try committing to base_b (which should work, since that is
# actually top's backing image) # actually top's backing image)
result = self.vm.qmp('block-commit', self.vm.cmd('block-commit',
job_id='commit', job_id='commit',
device='top', device='top',
base=self.img_base_b) base=self.img_base_b)
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_READY') self.vm.event_wait('BLOCK_JOB_READY')
self.vm.qmp('block-job-complete', device='commit') self.vm.qmp('block-job-complete', device='commit')

View File

@ -65,9 +65,8 @@ class TestSingleDrive(iotests.QMPTestCase):
def test_complete(self): def test_complete(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
target=self.qmp_target) target=self.qmp_target)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -79,9 +78,8 @@ class TestSingleDrive(iotests.QMPTestCase):
def test_cancel(self): def test_cancel(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
target=self.qmp_target) target=self.qmp_target)
self.assert_qmp(result, 'return', {})
self.cancel_and_wait(force=True) self.cancel_and_wait(force=True)
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -90,9 +88,8 @@ class TestSingleDrive(iotests.QMPTestCase):
def test_cancel_after_ready(self): def test_cancel_after_ready(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
target=self.qmp_target) target=self.qmp_target)
self.assert_qmp(result, 'return', {})
self.wait_ready_and_cancel() self.wait_ready_and_cancel()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -104,9 +101,8 @@ class TestSingleDrive(iotests.QMPTestCase):
def test_pause(self): def test_pause(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
target=self.qmp_target) target=self.qmp_target)
self.assert_qmp(result, 'return', {})
self.pause_job('drive0') self.pause_job('drive0')
@ -117,8 +113,7 @@ class TestSingleDrive(iotests.QMPTestCase):
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/offset', offset) self.assert_qmp(result, 'return[0]/offset', offset)
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
self.vm.shutdown() self.vm.shutdown()
@ -129,9 +124,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
# A small buffer is rounded up automatically # A small buffer is rounded up automatically
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
buf_size=4096, target=self.qmp_target) buf_size=4096, target=self.qmp_target)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -145,9 +139,8 @@ class TestSingleDrive(iotests.QMPTestCase):
qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,size=%d' qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,size=%d'
% (self.image_len, self.image_len), target_img) % (self.image_len, self.image_len), target_img)
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
buf_size=65536, mode='existing', target=self.qmp_target) buf_size=65536, mode='existing', target=self.qmp_target)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -162,9 +155,8 @@ class TestSingleDrive(iotests.QMPTestCase):
qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s' qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
% (self.image_len, backing_img), % (self.image_len, backing_img),
'-F', 'raw', target_img) '-F', 'raw', target_img)
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
mode='existing', target=self.qmp_target) mode='existing', target=self.qmp_target)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -178,9 +170,8 @@ class TestSingleDrive(iotests.QMPTestCase):
def test_implicit_node(self): def test_implicit_node(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
target=self.qmp_target) target=self.qmp_target)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/file', test_img) self.assert_qmp(result, 'return[0]/inserted/file', test_img)
@ -236,8 +227,7 @@ class TestSingleBlockdev(TestSingleDrive):
args = {'driver': iotests.imgfmt, args = {'driver': iotests.imgfmt,
'node-name': self.qmp_target, 'node-name': self.qmp_target,
'file': { 'filename': target_img, 'driver': 'file' } } 'file': { 'filename': target_img, 'driver': 'file' } }
result = self.vm.qmp("blockdev-add", **args) self.vm.cmd("blockdev-add", args)
self.assert_qmp(result, 'return', {})
def test_mirror_to_self(self): def test_mirror_to_self(self):
result = self.vm.qmp(self.qmp_cmd, job_id='job0', result = self.vm.qmp(self.qmp_cmd, job_id='job0',
@ -254,10 +244,9 @@ class TestSingleBlockdev(TestSingleDrive):
result = self.vm.qmp('block_resize', node_name=node, size=65536) result = self.vm.qmp('block_resize', node_name=node, size=65536)
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
result = self.vm.qmp(self.qmp_cmd, job_id='job0', device='drive0', self.vm.cmd(self.qmp_cmd, job_id='job0', device='drive0',
sync='full', target=self.qmp_target, sync='full', target=self.qmp_target,
auto_finalize=False, auto_dismiss=False) auto_finalize=False, auto_dismiss=False)
self.assert_qmp(result, 'return', {})
result = self.vm.run_job('job0', auto_finalize=False, result = self.vm.run_job('job0', auto_finalize=False,
pre_finalize=pre_finalize) pre_finalize=pre_finalize)
@ -270,14 +259,12 @@ class TestSingleBlockdev(TestSingleDrive):
self.do_test_resize(None, self.qmp_target) self.do_test_resize(None, self.qmp_target)
def do_test_target_size(self, size): def do_test_target_size(self, size):
result = self.vm.qmp('block_resize', node_name=self.qmp_target, self.vm.cmd('block_resize', node_name=self.qmp_target,
size=size) size=size)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp(self.qmp_cmd, job_id='job0', self.vm.cmd(self.qmp_cmd, job_id='job0',
device='drive0', sync='full', auto_dismiss=False, device='drive0', sync='full', auto_dismiss=False,
target=self.qmp_target) target=self.qmp_target)
self.assert_qmp(result, 'return', {})
result = self.vm.run_job('job0') result = self.vm.run_job('job0')
self.assertEqual(result, 'Source and target image have different sizes') self.assertEqual(result, 'Source and target image have different sizes')
@ -337,9 +324,8 @@ class TestMirrorNoBacking(iotests.QMPTestCase):
qemu_img('create', '-f', iotests.imgfmt, qemu_img('create', '-f', iotests.imgfmt,
'-o', 'backing_file=%s' % backing_img, '-F', 'raw', target_img) '-o', 'backing_file=%s' % backing_img, '-F', 'raw', target_img)
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
mode='existing', target=target_img) mode='existing', target=target_img)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -353,9 +339,8 @@ class TestMirrorNoBacking(iotests.QMPTestCase):
qemu_img('create', '-f', iotests.imgfmt, qemu_img('create', '-f', iotests.imgfmt,
'-o', 'backing_file=%s' % backing_img, '-F', 'raw', target_img) '-o', 'backing_file=%s' % backing_img, '-F', 'raw', target_img)
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
mode='existing', target=target_img) mode='existing', target=target_img)
self.assert_qmp(result, 'return', {})
self.wait_ready_and_cancel() self.wait_ready_and_cancel()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -374,9 +359,8 @@ class TestMirrorNoBacking(iotests.QMPTestCase):
% (TestMirrorNoBacking.image_len, target_backing_img), % (TestMirrorNoBacking.image_len, target_backing_img),
'-F', iotests.imgfmt, target_img) '-F', iotests.imgfmt, target_img)
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
mode='existing', target=target_img) mode='existing', target=target_img)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -409,9 +393,8 @@ class TestMirrorResized(iotests.QMPTestCase):
def test_complete_top(self): def test_complete_top(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='top', self.vm.cmd('drive-mirror', device='drive0', sync='top',
target=target_img) target=target_img)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -423,9 +406,8 @@ class TestMirrorResized(iotests.QMPTestCase):
def test_complete_full(self): def test_complete_full(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img) target=target_img)
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
@ -488,9 +470,8 @@ new_state = "1"
def test_report_read(self): def test_report_read(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img) target=target_img)
self.assert_qmp(result, 'return', {})
completed = False completed = False
error = False error = False
@ -516,9 +497,8 @@ new_state = "1"
def test_ignore_read(self): def test_ignore_read(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img, on_source_error='ignore') target=target_img, on_source_error='ignore')
self.assert_qmp(result, 'return', {})
event = self.vm.get_qmp_event(wait=True) event = self.vm.get_qmp_event(wait=True)
while event['event'] == 'JOB_STATUS_CHANGE': while event['event'] == 'JOB_STATUS_CHANGE':
@ -541,10 +521,9 @@ new_state = "1"
qemu_img('create', '-f', iotests.imgfmt, qemu_img('create', '-f', iotests.imgfmt,
'-ocluster_size=131072,backing_file=%s' %(backing_img), '-ocluster_size=131072,backing_file=%s' %(backing_img),
'-F', 'raw', target_img) '-F', 'raw', target_img)
result = self.vm.qmp('drive-mirror', device='drive0', sync='top', self.vm.cmd('drive-mirror', device='drive0', sync='top',
on_source_error='ignore', on_source_error='ignore',
mode='existing', target=target_img) mode='existing', target=target_img)
self.assert_qmp(result, 'return', {})
event = self.vm.get_qmp_event(wait=True) event = self.vm.get_qmp_event(wait=True)
while event['event'] == 'JOB_STATUS_CHANGE': while event['event'] == 'JOB_STATUS_CHANGE':
@ -568,9 +547,8 @@ new_state = "1"
def test_stop_read(self): def test_stop_read(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img, on_source_error='stop') target=target_img, on_source_error='stop')
self.assert_qmp(result, 'return', {})
error = False error = False
ready = False ready = False
@ -590,8 +568,7 @@ new_state = "1"
self.assert_qmp(result, 'return[0]/status', 'paused') self.assert_qmp(result, 'return[0]/status', 'paused')
self.assert_qmp(result, 'return[0]/io-status', 'failed') self.assert_qmp(result, 'return[0]/io-status', 'failed')
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
error = True error = True
elif event['event'] == 'BLOCK_JOB_READY': elif event['event'] == 'BLOCK_JOB_READY':
self.assertTrue(error, 'job completed unexpectedly') self.assertTrue(error, 'job completed unexpectedly')
@ -656,9 +633,8 @@ new_state = "1"
def test_report_write(self): def test_report_write(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
mode='existing', target=self.target_img) mode='existing', target=self.target_img)
self.assert_qmp(result, 'return', {})
completed = False completed = False
error = False error = False
@ -682,10 +658,9 @@ new_state = "1"
def test_ignore_write(self): def test_ignore_write(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
mode='existing', target=self.target_img, mode='existing', target=self.target_img,
on_target_error='ignore') on_target_error='ignore')
self.assert_qmp(result, 'return', {})
event = self.vm.event_wait(name='BLOCK_JOB_ERROR') event = self.vm.event_wait(name='BLOCK_JOB_ERROR')
self.assertEqual(event['event'], 'BLOCK_JOB_ERROR') self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
@ -698,10 +673,9 @@ new_state = "1"
def test_stop_write(self): def test_stop_write(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
mode='existing', target=self.target_img, mode='existing', target=self.target_img,
on_target_error='stop') on_target_error='stop')
self.assert_qmp(result, 'return', {})
error = False error = False
ready = False ready = False
@ -721,8 +695,7 @@ new_state = "1"
self.assert_qmp(result, 'return[0]/status', 'paused') self.assert_qmp(result, 'return[0]/status', 'paused')
self.assert_qmp(result, 'return[0]/io-status', 'failed') self.assert_qmp(result, 'return[0]/io-status', 'failed')
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assertIn(result['return'][0]['status'], ['running', 'ready']) self.assertIn(result['return'][0]['status'], ['running', 'ready'])
@ -755,17 +728,15 @@ class TestSetSpeed(iotests.QMPTestCase):
def test_set_speed(self): def test_set_speed(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img) target=target_img)
self.assert_qmp(result, 'return', {})
# Default speed is 0 # Default speed is 0
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/device', 'drive0')
self.assert_qmp(result, 'return[0]/speed', 0) self.assert_qmp(result, 'return[0]/speed', 0)
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) self.vm.cmd('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
self.assert_qmp(result, 'return', {})
# Ensure the speed we set was accepted # Ensure the speed we set was accepted
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
@ -775,9 +746,8 @@ class TestSetSpeed(iotests.QMPTestCase):
self.wait_ready_and_cancel() self.wait_ready_and_cancel()
# Check setting speed in drive-mirror works # Check setting speed in drive-mirror works
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img, speed=4*1024*1024) target=target_img, speed=4*1024*1024)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/device', 'drive0')
@ -794,9 +764,8 @@ class TestSetSpeed(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img) target=target_img)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1) result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
@ -811,13 +780,12 @@ class TestUnbackedSource(iotests.QMPTestCase):
str(TestUnbackedSource.image_len)) str(TestUnbackedSource.image_len))
self.vm = iotests.VM() self.vm = iotests.VM()
self.vm.launch() self.vm.launch()
result = self.vm.qmp('blockdev-add', node_name='drive0', self.vm.cmd('blockdev-add', node_name='drive0',
driver=iotests.imgfmt, driver=iotests.imgfmt,
file={ file={
'driver': 'file', 'driver': 'file',
'filename': test_img, 'filename': test_img,
}) })
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
self.vm.shutdown() self.vm.shutdown()
@ -826,28 +794,25 @@ class TestUnbackedSource(iotests.QMPTestCase):
def test_absolute_paths_full(self): def test_absolute_paths_full(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0', self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
sync='full', target=target_img, sync='full', target=target_img,
mode='absolute-paths') mode='absolute-paths')
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
def test_absolute_paths_top(self): def test_absolute_paths_top(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0', self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
sync='top', target=target_img, sync='top', target=target_img,
mode='absolute-paths') mode='absolute-paths')
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
def test_absolute_paths_none(self): def test_absolute_paths_none(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0', self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
sync='none', target=target_img, sync='none', target=target_img,
mode='absolute-paths') mode='absolute-paths')
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
@ -857,14 +822,12 @@ class TestUnbackedSource(iotests.QMPTestCase):
qemu_io('-c', 'write -P 42 0 64k', target_img) qemu_io('-c', 'write -P 42 0 64k', target_img)
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0', self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
sync='full', target=target_img, mode='existing') sync='full', target=target_img, mode='existing')
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('blockdev-del', node_name='drive0') self.vm.cmd('blockdev-del', node_name='drive0')
self.assert_qmp(result, 'return', {})
self.assertTrue(iotests.compare_images(test_img, target_img), self.assertTrue(iotests.compare_images(test_img, target_img),
'target image does not match source after mirroring') 'target image does not match source after mirroring')
@ -874,26 +837,22 @@ class TestUnbackedSource(iotests.QMPTestCase):
str(self.image_len)) str(self.image_len))
qemu_io('-c', 'write -P 42 0 64k', target_img) qemu_io('-c', 'write -P 42 0 64k', target_img)
result = self.vm.qmp('blockdev-add', node_name='target', self.vm.cmd('blockdev-add', node_name='target',
driver=iotests.imgfmt, driver=iotests.imgfmt,
file={ file={
'driver': 'file', 'driver': 'file',
'filename': target_img, 'filename': target_img,
}) })
self.assert_qmp(result, 'return', {})
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('blockdev-mirror', job_id='drive0', device='drive0', self.vm.cmd('blockdev-mirror', job_id='drive0', device='drive0',
sync='full', target='target') sync='full', target='target')
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('blockdev-del', node_name='drive0') self.vm.cmd('blockdev-del', node_name='drive0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-del', node_name='target') self.vm.cmd('blockdev-del', node_name='target')
self.assert_qmp(result, 'return', {})
self.assertTrue(iotests.compare_images(test_img, target_img), self.assertTrue(iotests.compare_images(test_img, target_img),
'target image does not match source after mirroring') 'target image does not match source after mirroring')
@ -918,10 +877,9 @@ class TestGranularity(iotests.QMPTestCase):
def test_granularity(self): def test_granularity(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-mirror', device='drive0', self.vm.cmd('drive-mirror', device='drive0',
sync='full', target=target_img, sync='full', target=target_img,
mode='absolute-paths', granularity=8192) mode='absolute-paths', granularity=8192)
self.assert_qmp(result, 'return', {})
event = self.vm.get_qmp_event(wait=60.0) event = self.vm.get_qmp_event(wait=60.0)
while event['event'] == 'JOB_STATUS_CHANGE': while event['event'] == 'JOB_STATUS_CHANGE':
@ -963,8 +921,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
#assemble the quorum block device from the individual files #assemble the quorum block device from the individual files
args = { "driver": "quorum", "node-name": "quorum0", args = { "driver": "quorum", "node-name": "quorum0",
"vote-threshold": 2, "children": [ "img0", "img1", "img2" ] } "vote-threshold": 2, "children": [ "img0", "img1", "img2" ] }
result = self.vm.qmp("blockdev-add", **args) self.vm.cmd("blockdev-add", args)
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
@ -978,10 +935,9 @@ class TestRepairQuorum(iotests.QMPTestCase):
pass pass
def test_complete(self): def test_complete(self):
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0', self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
sync='full', node_name="repair0", replaces="img1", sync='full', node_name="repair0", replaces="img1",
target=quorum_repair_img, format=iotests.imgfmt) target=quorum_repair_img, format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive="job0") self.complete_and_wait(drive="job0")
self.assert_has_block_node("repair0", quorum_repair_img) self.assert_has_block_node("repair0", quorum_repair_img)
@ -991,10 +947,9 @@ class TestRepairQuorum(iotests.QMPTestCase):
'target image does not match source after mirroring') 'target image does not match source after mirroring')
def test_cancel(self): def test_cancel(self):
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0', self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
sync='full', node_name="repair0", replaces="img1", sync='full', node_name="repair0", replaces="img1",
target=quorum_repair_img, format=iotests.imgfmt) target=quorum_repair_img, format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.cancel_and_wait(drive="job0", force=True) self.cancel_and_wait(drive="job0", force=True)
# here we check that the last registered quorum file has not been # here we check that the last registered quorum file has not been
@ -1002,10 +957,9 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_has_block_node(None, quorum_img3) self.assert_has_block_node(None, quorum_img3)
def test_cancel_after_ready(self): def test_cancel_after_ready(self):
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0', self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
sync='full', node_name="repair0", replaces="img1", sync='full', node_name="repair0", replaces="img1",
target=quorum_repair_img, format=iotests.imgfmt) target=quorum_repair_img, format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.wait_ready_and_cancel(drive="job0") self.wait_ready_and_cancel(drive="job0")
# here we check that the last registered quorum file has not been # here we check that the last registered quorum file has not been
@ -1016,10 +970,9 @@ class TestRepairQuorum(iotests.QMPTestCase):
'target image does not match source after mirroring') 'target image does not match source after mirroring')
def test_pause(self): def test_pause(self):
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0', self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
sync='full', node_name="repair0", replaces="img1", sync='full', node_name="repair0", replaces="img1",
target=quorum_repair_img, format=iotests.imgfmt) target=quorum_repair_img, format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.pause_job('job0') self.pause_job('job0')
@ -1030,8 +983,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/offset', offset) self.assert_qmp(result, 'return[0]/offset', offset)
result = self.vm.qmp('block-job-resume', device='job0') self.vm.cmd('block-job-resume', device='job0')
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive="job0") self.complete_and_wait(drive="job0")
self.vm.shutdown() self.vm.shutdown()
@ -1084,19 +1036,18 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
def test_after_a_quorum_snapshot(self): def test_after_a_quorum_snapshot(self):
result = self.vm.qmp('blockdev-snapshot-sync', node_name='img1', self.vm.cmd('blockdev-snapshot-sync', node_name='img1',
snapshot_file=quorum_snapshot_file, snapshot_file=quorum_snapshot_file,
snapshot_node_name="snap1"); snapshot_node_name="snap1")
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0', result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
sync='full', node_name='repair0', replaces="img1", sync='full', node_name='repair0', replaces="img1",
target=quorum_repair_img, format=iotests.imgfmt) target=quorum_repair_img, format=iotests.imgfmt)
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0', self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
sync='full', node_name='repair0', replaces="snap1", sync='full', node_name='repair0', replaces="snap1",
target=quorum_repair_img, format=iotests.imgfmt) target=quorum_repair_img, format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.complete_and_wait('job0') self.complete_and_wait('job0')
self.assert_has_block_node("repair0", quorum_repair_img) self.assert_has_block_node("repair0", quorum_repair_img)
@ -1107,15 +1058,13 @@ class TestRepairQuorum(iotests.QMPTestCase):
Check that we cannot replace a Quorum child when it has other Check that we cannot replace a Quorum child when it has other
parents. parents.
""" """
result = self.vm.qmp('nbd-server-start', self.vm.cmd('nbd-server-start',
addr={ addr={
'type': 'unix', 'type': 'unix',
'data': {'path': nbd_sock_path} 'data': {'path': nbd_sock_path}
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('nbd-server-add', device='img1') self.vm.cmd('nbd-server-add', device='img1')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0', result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0',
sync='full', node_name='repair0', replaces='img1', sync='full', node_name='repair0', replaces='img1',
@ -1130,20 +1079,17 @@ class TestRepairQuorum(iotests.QMPTestCase):
The same as test_with_other_parent(), but add the NBD server The same as test_with_other_parent(), but add the NBD server
only when the mirror job is already running. only when the mirror job is already running.
""" """
result = self.vm.qmp('nbd-server-start', self.vm.cmd('nbd-server-start',
addr={ addr={
'type': 'unix', 'type': 'unix',
'data': {'path': nbd_sock_path} 'data': {'path': nbd_sock_path}
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0', self.vm.cmd('drive-mirror', job_id='mirror', device='quorum0',
sync='full', node_name='repair0', replaces='img1', sync='full', node_name='repair0', replaces='img1',
target=quorum_repair_img, format=iotests.imgfmt) target=quorum_repair_img, format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('nbd-server-add', device='img1') self.vm.cmd('nbd-server-add', device='img1')
self.assert_qmp(result, 'return', {})
# The full error message goes to stderr, we will check it later # The full error message goes to stderr, we will check it later
self.complete_and_wait('mirror', self.complete_and_wait('mirror',
@ -1199,9 +1145,8 @@ class TestOrphanedSource(iotests.QMPTestCase):
def test_success(self): def test_success(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('blockdev-mirror', job_id='job', device='src', self.vm.cmd('blockdev-mirror', job_id='job', device='src',
sync='full', target='dest') sync='full', target='dest')
self.assert_qmp(result, 'return', {})
self.complete_and_wait('job') self.complete_and_wait('job')
@ -1217,27 +1162,24 @@ class TestOrphanedSource(iotests.QMPTestCase):
# Unshare consistent-read on the target # Unshare consistent-read on the target
# (The mirror job does not care) # (The mirror job does not care)
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
driver='blkdebug', driver='blkdebug',
node_name='dest-perm', node_name='dest-perm',
image='dest', image='dest',
unshare_child_perms=['consistent-read']) unshare_child_perms=['consistent-read'])
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-mirror', job_id='job', device='src', self.vm.cmd('blockdev-mirror', job_id='job', device='src',
sync='full', target='dest', sync='full', target='dest',
filter_node_name='mirror-filter') filter_node_name='mirror-filter')
self.assert_qmp(result, 'return', {})
# Require consistent-read on the source # Require consistent-read on the source
# (We can only add this node once the job has started, or it # (We can only add this node once the job has started, or it
# will complain that it does not want to run on non-root nodes) # will complain that it does not want to run on non-root nodes)
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
driver='blkdebug', driver='blkdebug',
node_name='src-perm', node_name='src-perm',
image='src', image='src',
take_child_perms=['consistent-read']) take_child_perms=['consistent-read'])
self.assert_qmp(result, 'return', {})
# While completing, mirror will attempt to replace src by # While completing, mirror will attempt to replace src by
# dest, which must fail because src-perm requires # dest, which must fail because src-perm requires
@ -1277,26 +1219,23 @@ class TestReplaces(iotests.QMPTestCase):
""" """
Check that we can replace filter nodes. Check that we can replace filter nodes.
""" """
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', {
'driver': 'copy-on-read', 'driver': 'copy-on-read',
'node-name': 'filter0', 'node-name': 'filter0',
'file': { 'file': {
'driver': 'copy-on-read', 'driver': 'copy-on-read',
'node-name': 'filter1', 'node-name': 'filter1',
'file': { 'file': {
'driver': 'null-co' 'driver': 'null-co'
} }
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='target', driver='null-co') node_name='target', driver='null-co')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-mirror', job_id='mirror', device='filter0', self.vm.cmd('blockdev-mirror', job_id='mirror', device='filter0',
target='target', sync='full', replaces='filter1') target='target', sync='full', replaces='filter1')
self.assert_qmp(result, 'return', {})
self.complete_and_wait('mirror') self.complete_and_wait('mirror')
@ -1318,16 +1257,15 @@ class TestFilters(iotests.QMPTestCase):
self.vm = iotests.VM().add_device('virtio-scsi,id=vio-scsi') self.vm = iotests.VM().add_device('virtio-scsi,id=vio-scsi')
self.vm.launch() self.vm.launch()
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', {
'node-name': 'target', 'node-name': 'target',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
'driver': 'file', 'driver': 'file',
'filename': target_img 'filename': target_img
}, },
'backing': None 'backing': None
}) })
self.assert_qmp(result, 'return', {})
self.filterless_chain = { self.filterless_chain = {
'node-name': 'source', 'node-name': 'source',
@ -1354,19 +1292,17 @@ class TestFilters(iotests.QMPTestCase):
os.remove(backing_img) os.remove(backing_img)
def test_cor(self): def test_cor(self):
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', {
'node-name': 'filter', 'node-name': 'filter',
'driver': 'copy-on-read', 'driver': 'copy-on-read',
'file': self.filterless_chain 'file': self.filterless_chain
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='filter', device='filter',
target='target', target='target',
sync='top') sync='top')
self.assert_qmp(result, 'return', {})
self.complete_and_wait('mirror') self.complete_and_wait('mirror')
@ -1383,23 +1319,20 @@ class TestFilters(iotests.QMPTestCase):
assert target_map[1]['depth'] == 0 assert target_map[1]['depth'] == 0
def test_implicit_mirror_filter(self): def test_implicit_mirror_filter(self):
result = self.vm.qmp('blockdev-add', **self.filterless_chain) self.vm.cmd('blockdev-add', self.filterless_chain)
self.assert_qmp(result, 'return', {})
# We need this so we can query from above the mirror node # We need this so we can query from above the mirror node
result = self.vm.qmp('device_add', self.vm.cmd('device_add',
driver='scsi-hd', driver='scsi-hd',
id='virtio', id='virtio',
bus='vio-scsi.0', bus='vio-scsi.0',
drive='source') drive='source')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='source', device='source',
target='target', target='target',
sync='top') sync='top')
self.assert_qmp(result, 'return', {})
# The mirror filter is now an implicit node, so it should be # The mirror filter is now an implicit node, so it should be
# invisible when querying the backing chain # invisible when querying the backing chain
@ -1417,24 +1350,21 @@ class TestFilters(iotests.QMPTestCase):
def test_explicit_mirror_filter(self): def test_explicit_mirror_filter(self):
# Same test as above, but this time we give the mirror filter # Same test as above, but this time we give the mirror filter
# a node-name so it will not be invisible # a node-name so it will not be invisible
result = self.vm.qmp('blockdev-add', **self.filterless_chain) self.vm.cmd('blockdev-add', self.filterless_chain)
self.assert_qmp(result, 'return', {})
# We need this so we can query from above the mirror node # We need this so we can query from above the mirror node
result = self.vm.qmp('device_add', self.vm.cmd('device_add',
driver='scsi-hd', driver='scsi-hd',
id='virtio', id='virtio',
bus='vio-scsi.0', bus='vio-scsi.0',
drive='source') drive='source')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='source', device='source',
target='target', target='target',
sync='top', sync='top',
filter_node_name='mirror-filter') filter_node_name='mirror-filter')
self.assert_qmp(result, 'return', {})
# With a node-name given to it, the mirror filter should now # With a node-name given to it, the mirror filter should now
# be visible # be visible

View File

@ -77,8 +77,7 @@ class TestFdSets(iotests.QMPTestCase):
self.vm.shutdown() self.vm.shutdown()
def test_remove_fdset(self): def test_remove_fdset(self):
result = self.vm.qmp('remove-fd', fdset_id=2) self.vm.cmd('remove-fd', fdset_id=2)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-fdsets') result = self.vm.qmp('query-fdsets')
self.assert_qmp(result, 'return[0]/fdset-id', 1) self.assert_qmp(result, 'return[0]/fdset-id', 1)
self.assert_qmp(result, 'return[1]/fdset-id', 0) self.assert_qmp(result, 'return[1]/fdset-id', 0)
@ -90,8 +89,7 @@ class TestFdSets(iotests.QMPTestCase):
def test_remove_fd(self): def test_remove_fd(self):
result = self.vm.qmp('query-fdsets') result = self.vm.qmp('query-fdsets')
fd_image3 = result['return'][0]['fds'][0]['fd'] fd_image3 = result['return'][0]['fds'][0]['fd']
result = self.vm.qmp('remove-fd', fdset_id=2, fd=fd_image3) self.vm.cmd('remove-fd', fdset_id=2, fd=fd_image3)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-fdsets') result = self.vm.qmp('query-fdsets')
self.assert_qmp(result, 'return[0]/fdset-id', 2) self.assert_qmp(result, 'return[0]/fdset-id', 2)
self.assert_qmp(result, 'return[1]/fdset-id', 1) self.assert_qmp(result, 'return[1]/fdset-id', 1)
@ -151,8 +149,7 @@ class TestSCMFd(iotests.QMPTestCase):
def test_getfd(self): def test_getfd(self):
self._send_fd_by_SCM() self._send_fd_by_SCM()
result = self.vm.qmp('getfd', fdname='image0:r') self.vm.cmd('getfd', fdname='image0:r')
self.assert_qmp(result, 'return', {})
def test_getfd_invalid_fdname(self): def test_getfd_invalid_fdname(self):
self._send_fd_by_SCM() self._send_fd_by_SCM()
@ -163,10 +160,8 @@ class TestSCMFd(iotests.QMPTestCase):
def test_closefd(self): def test_closefd(self):
self._send_fd_by_SCM() self._send_fd_by_SCM()
result = self.vm.qmp('getfd', fdname='image0:r') self.vm.cmd('getfd', fdname='image0:r')
self.assert_qmp(result, 'return', {}) self.vm.cmd('closefd', fdname='image0:r')
result = self.vm.qmp('closefd', fdname='image0:r')
self.assert_qmp(result, 'return', {})
def test_closefd_fd_not_found(self): def test_closefd_fd_not_found(self):
fdname = 'image0:r' fdname = 'image0:r'

View File

@ -69,8 +69,7 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp(cmd, device='drive0', target=target, sync='full') self.vm.cmd(cmd, device='drive0', target=target, sync='full')
self.assert_qmp(result, 'return', {})
event = self.cancel_and_wait(resume=True) event = self.cancel_and_wait(resume=True)
self.assert_qmp(event, 'data/type', 'backup') self.assert_qmp(event, 'data/type', 'backup')
@ -85,9 +84,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp(cmd, device='drive0', self.vm.cmd(cmd, device='drive0',
target=target, sync='full') target=target, sync='full')
self.assert_qmp(result, 'return', {})
self.pause_job('drive0', wait=False) self.pause_job('drive0', wait=False)
self.vm.resume_drive('drive0') self.vm.resume_drive('drive0')
@ -100,8 +98,7 @@ class TestSingleDrive(iotests.QMPTestCase):
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/offset', offset) self.assert_qmp(result, 'return[0]/offset', offset)
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -123,10 +120,9 @@ class TestSingleDrive(iotests.QMPTestCase):
result = self.vm.qmp('block_resize', node_name=node, size=65536) result = self.vm.qmp('block_resize', node_name=node, size=65536)
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0', self.vm.cmd('blockdev-backup', job_id='job0', device='drive0',
target='drive1', sync='full', auto_finalize=False, target='drive1', sync='full', auto_finalize=False,
auto_dismiss=False) auto_dismiss=False)
self.assert_qmp(result, 'return', {})
self.vm.run_job('job0', auto_finalize=False, pre_finalize=pre_finalize) self.vm.run_job('job0', auto_finalize=False, pre_finalize=pre_finalize)
@ -137,8 +133,7 @@ class TestSingleDrive(iotests.QMPTestCase):
self.do_test_resize_blockdev_backup('drive1', 'target') self.do_test_resize_blockdev_backup('drive1', 'target')
def do_test_target_size(self, size): def do_test_target_size(self, size):
result = self.vm.qmp('block_resize', device='drive1', size=size) self.vm.cmd('block_resize', device='drive1', size=size)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0', result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0',
target='drive1', sync='full') target='drive1', sync='full')
@ -219,16 +214,14 @@ class TestSetSpeed(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp(cmd, device='drive0', target=target, sync='full') self.vm.cmd(cmd, device='drive0', target=target, sync='full')
self.assert_qmp(result, 'return', {})
# Default speed is 0 # Default speed is 0
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/device', 'drive0')
self.assert_qmp(result, 'return[0]/speed', 0) self.assert_qmp(result, 'return[0]/speed', 0)
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) self.vm.cmd('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
self.assert_qmp(result, 'return', {})
# Ensure the speed we set was accepted # Ensure the speed we set was accepted
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
@ -240,9 +233,8 @@ class TestSetSpeed(iotests.QMPTestCase):
# Check setting speed option works # Check setting speed option works
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp(cmd, device='drive0', self.vm.cmd(cmd, device='drive0',
target=target, sync='full', speed=4*1024*1024) target=target, sync='full', speed=4*1024*1024)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/device', 'drive0')
@ -267,9 +259,8 @@ class TestSetSpeed(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp(cmd, device='drive0', self.vm.cmd(cmd, device='drive0',
target=target, sync='full') target=target, sync='full')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1) result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
@ -306,7 +297,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
def do_test_cancel(self, cmd, target): def do_test_cancel(self, cmd, target):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('transaction', actions=[{ self.vm.cmd('transaction', actions=[{
'type': cmd, 'type': cmd,
'data': { 'device': 'drive0', 'data': { 'device': 'drive0',
'target': target, 'target': target,
@ -315,8 +306,6 @@ class TestSingleTransaction(iotests.QMPTestCase):
} }
]) ])
self.assert_qmp(result, 'return', {})
event = self.cancel_and_wait() event = self.cancel_and_wait()
self.assert_qmp(event, 'data/type', 'backup') self.assert_qmp(event, 'data/type', 'backup')
@ -329,7 +318,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
def do_test_pause(self, cmd, target, image): def do_test_pause(self, cmd, target, image):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('transaction', actions=[{ self.vm.cmd('transaction', actions=[{
'type': cmd, 'type': cmd,
'data': { 'device': 'drive0', 'data': { 'device': 'drive0',
'target': target, 'target': target,
@ -337,12 +326,10 @@ class TestSingleTransaction(iotests.QMPTestCase):
'speed': 64 * 1024 }, 'speed': 64 * 1024 },
} }
]) ])
self.assert_qmp(result, 'return', {})
self.pause_job('drive0', wait=False) self.pause_job('drive0', wait=False)
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) self.vm.cmd('block-job-set-speed', device='drive0', speed=0)
self.assert_qmp(result, 'return', {})
self.pause_wait('drive0') self.pause_wait('drive0')
@ -353,8 +340,7 @@ class TestSingleTransaction(iotests.QMPTestCase):
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/offset', offset) self.assert_qmp(result, 'return[0]/offset', offset)
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -519,8 +505,7 @@ class TestCompressedToQcow2(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args) self.vm.cmd(cmd, device='drive0', sync='full', compress=True, **args)
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()
@ -545,8 +530,7 @@ class TestCompressedToQcow2(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args) self.vm.cmd(cmd, device='drive0', sync='full', compress=True, **args)
self.assert_qmp(result, 'return', {})
event = self.cancel_and_wait(resume=True) event = self.cancel_and_wait(resume=True)
self.assert_qmp(event, 'data/type', 'backup') self.assert_qmp(event, 'data/type', 'backup')
@ -568,8 +552,7 @@ class TestCompressedToQcow2(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.pause_drive('drive0') self.vm.pause_drive('drive0')
result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args) self.vm.cmd(cmd, device='drive0', sync='full', compress=True, **args)
self.assert_qmp(result, 'return', {})
self.pause_job('drive0', wait=False) self.pause_job('drive0', wait=False)
self.vm.resume_drive('drive0') self.vm.resume_drive('drive0')
@ -582,8 +565,7 @@ class TestCompressedToQcow2(iotests.QMPTestCase):
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/offset', offset) self.assert_qmp(result, 'return[0]/offset', offset)
result = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed() self.wait_until_completed()

View File

@ -75,9 +75,8 @@ class TestSyncModesNoneAndTop(iotests.QMPTestCase):
def test_complete_top(self): def test_complete_top(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-backup', device='drive0', sync='top', self.vm.cmd('drive-backup', device='drive0', sync='top',
format=iotests.imgfmt, target=target_img) format=iotests.imgfmt, target=target_img)
self.assert_qmp(result, 'return', {})
self.wait_until_completed(check_offset=False) self.wait_until_completed(check_offset=False)
@ -89,9 +88,8 @@ class TestSyncModesNoneAndTop(iotests.QMPTestCase):
def test_cancel_sync_none(self): def test_cancel_sync_none(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
result = self.vm.qmp('drive-backup', device='drive0', self.vm.cmd('drive-backup', device='drive0',
sync='none', target=target_img) sync='none', target=target_img)
self.assert_qmp(result, 'return', {})
time.sleep(1) time.sleep(1)
self.vm.hmp_qemu_io('drive0', 'write -P0x5e 0 512') self.vm.hmp_qemu_io('drive0', 'write -P0x5e 0 512')
self.vm.hmp_qemu_io('drive0', 'aio_flush') self.vm.hmp_qemu_io('drive0', 'aio_flush')
@ -115,18 +113,15 @@ class TestBeforeWriteNotifier(iotests.QMPTestCase):
def test_before_write_notifier(self): def test_before_write_notifier(self):
self.vm.pause_drive("drive0") self.vm.pause_drive("drive0")
result = self.vm.qmp('drive-backup', device='drive0', self.vm.cmd('drive-backup', device='drive0',
sync='full', target=target_img, sync='full', target=target_img,
format="file", speed=1) format="file", speed=1)
self.assert_qmp(result, 'return', {}) self.vm.cmd('block-job-pause', device="drive0")
result = self.vm.qmp('block-job-pause', device="drive0")
self.assert_qmp(result, 'return', {})
# Speed is low enough that this must be an uncopied range, which will # Speed is low enough that this must be an uncopied range, which will
# trigger the before write notifier # trigger the before write notifier
self.vm.hmp_qemu_io('drive0', 'aio_write -P 1 512512 512') self.vm.hmp_qemu_io('drive0', 'aio_write -P 1 512512 512')
self.vm.resume_drive("drive0") self.vm.resume_drive("drive0")
result = self.vm.qmp('block-job-resume', device="drive0") self.vm.cmd('block-job-resume', device="drive0")
self.assert_qmp(result, 'return', {})
event = self.cancel_and_wait() event = self.cancel_and_wait()
self.assert_qmp(event, 'data/type', 'backup') self.assert_qmp(event, 'data/type', 'backup')
@ -191,8 +186,7 @@ class BackupTest(iotests.QMPTestCase):
self.qmp_backup_and_wait(device='drive0', format=iotests.imgfmt, self.qmp_backup_and_wait(device='drive0', format=iotests.imgfmt,
sync='full', target=self.ref_img, sync='full', target=self.ref_img,
auto_dismiss=False) auto_dismiss=False)
res = self.vm.qmp('block-job-dismiss', id='drive0') self.vm.cmd('block-job-dismiss', id='drive0')
self.assert_qmp(res, 'return', {})
# Now to the test backup: We simulate the following guest # Now to the test backup: We simulate the following guest
# writes: # writes:
@ -211,11 +205,9 @@ class BackupTest(iotests.QMPTestCase):
('66', '1M', '1M')]) ('66', '1M', '1M')])
# Let the job complete # Let the job complete
res = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) self.vm.cmd('block-job-set-speed', device='drive0', speed=0)
self.assert_qmp(res, 'return', {})
self.qmp_backup_wait('drive0') self.qmp_backup_wait('drive0')
res = self.vm.qmp('block-job-dismiss', id='drive0') self.vm.cmd('block-job-dismiss', id='drive0')
self.assert_qmp(res, 'return', {})
self.assertTrue(iotests.compare_images(self.ref_img, self.dest_img), self.assertTrue(iotests.compare_images(self.ref_img, self.dest_img),
'target image does not match reference image') 'target image does not match reference image')
@ -237,8 +229,7 @@ class BackupTest(iotests.QMPTestCase):
auto_dismiss=False) auto_dismiss=False)
res = self.vm.qmp('query-block-jobs') res = self.vm.qmp('query-block-jobs')
self.assert_qmp(res, 'return[0]/status', 'concluded') self.assert_qmp(res, 'return[0]/status', 'concluded')
res = self.vm.qmp('block-job-dismiss', id='drive0') self.vm.cmd('block-job-dismiss', id='drive0')
self.assert_qmp(res, 'return', {})
res = self.vm.qmp('query-block-jobs') res = self.vm.qmp('query-block-jobs')
self.assert_qmp(res, 'return', []) self.assert_qmp(res, 'return', [])
@ -263,8 +254,7 @@ class BackupTest(iotests.QMPTestCase):
auto_dismiss=False) auto_dismiss=False)
self.assertEqual(res, False) self.assertEqual(res, False)
# OK, dismiss the zombie. # OK, dismiss the zombie.
res = self.vm.qmp('block-job-dismiss', id='drive0') self.vm.cmd('block-job-dismiss', id='drive0')
self.assert_qmp(res, 'return', {})
res = self.vm.qmp('query-block-jobs') res = self.vm.qmp('query-block-jobs')
self.assert_qmp(res, 'return', []) self.assert_qmp(res, 'return', [])
# Ensure it's really gone. # Ensure it's really gone.
@ -281,23 +271,22 @@ class BackupTest(iotests.QMPTestCase):
('0x55', '8M', '352k'), ('0x55', '8M', '352k'),
('0x78', '15872k', '1M'))) ('0x78', '15872k', '1M')))
# Add destination node via blkdebug # Add destination node via blkdebug
res = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='target0', node_name='target0',
driver=iotests.imgfmt, driver=iotests.imgfmt,
file={ file={
'driver': 'blkdebug', 'driver': 'blkdebug',
'image': { 'image': {
'driver': 'file', 'driver': 'file',
'filename': self.dest_img 'filename': self.dest_img
}, },
'inject-error': [{ 'inject-error': [{
'event': 'write_aio', 'event': 'write_aio',
'errno': 5, 'errno': 5,
'immediately': False, 'immediately': False,
'once': True 'once': True
}], }],
}) })
self.assert_qmp(res, 'return', {})
res = self.qmp_backup(cmd='blockdev-backup', res = self.qmp_backup(cmd='blockdev-backup',
device='drive0', target='target0', device='drive0', target='target0',
@ -323,8 +312,7 @@ class BackupTest(iotests.QMPTestCase):
res = self.vm.qmp('query-block-jobs') res = self.vm.qmp('query-block-jobs')
self.assert_qmp(res, 'return[0]/status', 'paused') self.assert_qmp(res, 'return[0]/status', 'paused')
# OK, unstick job and move forward. # OK, unstick job and move forward.
res = self.vm.qmp('block-job-resume', device='drive0') self.vm.cmd('block-job-resume', device='drive0')
self.assert_qmp(res, 'return', {})
# And now we need to wait for it to conclude; # And now we need to wait for it to conclude;
res = self.qmp_backup_wait(device='drive0') res = self.qmp_backup_wait(device='drive0')
self.assertTrue(res) self.assertTrue(res)
@ -332,8 +320,7 @@ class BackupTest(iotests.QMPTestCase):
# Job should now be languishing: # Job should now be languishing:
res = self.vm.qmp('query-block-jobs') res = self.vm.qmp('query-block-jobs')
self.assert_qmp(res, 'return[0]/status', 'concluded') self.assert_qmp(res, 'return[0]/status', 'concluded')
res = self.vm.qmp('block-job-dismiss', id='drive0') self.vm.cmd('block-job-dismiss', id='drive0')
self.assert_qmp(res, 'return', {})
res = self.vm.qmp('query-block-jobs') res = self.vm.qmp('query-block-jobs')
self.assert_qmp(res, 'return', []) self.assert_qmp(res, 'return', [])

View File

@ -55,8 +55,7 @@ class ThrottleTestCase(iotests.QMPTestCase):
# Set the I/O throttling parameters to all drives # Set the I/O throttling parameters to all drives
for i in range(0, ndrives): for i in range(0, ndrives):
params['device'] = 'drive%d' % i params['device'] = 'drive%d' % i
result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params) self.vm.cmd("block_set_io_throttle", conv_keys=False, **params)
self.assert_qmp(result, 'return', {})
def do_test_throttle(self, ndrives, seconds, params, first_drive = 0): def do_test_throttle(self, ndrives, seconds, params, first_drive = 0):
def check_limit(limit, num): def check_limit(limit, num):
@ -253,8 +252,7 @@ class ThrottleTestCase(iotests.QMPTestCase):
# drive1 remains in the group with a throttled request. # drive1 remains in the group with a throttled request.
params['bps_rd'] = 0 params['bps_rd'] = 0
params['device'] = 'drive0' params['device'] = 'drive0'
result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params) self.vm.cmd("block_set_io_throttle", conv_keys=False, **params)
self.assert_qmp(result, 'return', {})
# Removing the I/O limits from drive0 drains its two pending requests. # Removing the I/O limits from drive0 drains its two pending requests.
# The read request in drive1 is still throttled. # The read request in drive1 is still throttled.
@ -286,8 +284,7 @@ class ThrottleTestGroupNames(iotests.QMPTestCase):
def set_io_throttle(self, device, params): def set_io_throttle(self, device, params):
params["device"] = device params["device"] = device
result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params) self.vm.cmd("block_set_io_throttle", conv_keys=False, **params)
self.assert_qmp(result, 'return', {})
def verify_name(self, device, name): def verify_name(self, device, name):
result = self.vm.qmp("query-block") result = self.vm.qmp("query-block")
@ -379,23 +376,19 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
def test_removable_media(self): def test_removable_media(self):
# Add a couple of dummy nodes named cd0 and cd1 # Add a couple of dummy nodes named cd0 and cd1
result = self.vm.qmp("blockdev-add", driver="null-co", self.vm.cmd("blockdev-add", driver="null-co",
read_zeroes=True, node_name="cd0") read_zeroes=True, node_name="cd0")
self.assert_qmp(result, 'return', {}) self.vm.cmd("blockdev-add", driver="null-co",
result = self.vm.qmp("blockdev-add", driver="null-co", read_zeroes=True, node_name="cd1")
read_zeroes=True, node_name="cd1")
self.assert_qmp(result, 'return', {})
# Attach a CD drive with cd0 inserted # Attach a CD drive with cd0 inserted
result = self.vm.qmp("device_add", driver="scsi-cd", self.vm.cmd("device_add", driver="scsi-cd",
id="dev0", drive="cd0") id="dev0", drive="cd0")
self.assert_qmp(result, 'return', {})
# Set I/O limits # Set I/O limits
args = { "id": "dev0", "iops": 100, "iops_rd": 0, "iops_wr": 0, args = { "id": "dev0", "iops": 100, "iops_rd": 0, "iops_wr": 0,
"bps": 50, "bps_rd": 0, "bps_wr": 0 } "bps": 50, "bps_rd": 0, "bps_wr": 0 }
result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args) self.vm.cmd("block_set_io_throttle", conv_keys=False, **args)
self.assert_qmp(result, 'return', {})
# Check that the I/O limits have been set # Check that the I/O limits have been set
result = self.vm.qmp("query-block") result = self.vm.qmp("query-block")
@ -403,12 +396,9 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
self.assert_qmp(result, 'return[0]/inserted/bps', 50) self.assert_qmp(result, 'return[0]/inserted/bps', 50)
# Now eject cd0 and insert cd1 # Now eject cd0 and insert cd1
result = self.vm.qmp("blockdev-open-tray", id='dev0') self.vm.cmd("blockdev-open-tray", id='dev0')
self.assert_qmp(result, 'return', {}) self.vm.cmd("blockdev-remove-medium", id='dev0')
result = self.vm.qmp("blockdev-remove-medium", id='dev0') self.vm.cmd("blockdev-insert-medium", id='dev0', node_name='cd1')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp("blockdev-insert-medium", id='dev0', node_name='cd1')
self.assert_qmp(result, 'return', {})
# Check that the I/O limits are still the same # Check that the I/O limits are still the same
result = self.vm.qmp("query-block") result = self.vm.qmp("query-block")
@ -416,16 +406,14 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
self.assert_qmp(result, 'return[0]/inserted/bps', 50) self.assert_qmp(result, 'return[0]/inserted/bps', 50)
# Eject cd1 # Eject cd1
result = self.vm.qmp("blockdev-remove-medium", id='dev0') self.vm.cmd("blockdev-remove-medium", id='dev0')
self.assert_qmp(result, 'return', {})
# Check that we can't set limits if the device has no medium # Check that we can't set limits if the device has no medium
result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args) result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **args)
self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/class', 'GenericError')
# Remove the CD drive # Remove the CD drive
result = self.vm.qmp("device_del", id='dev0') self.vm.cmd("device_del", id='dev0')
self.assert_qmp(result, 'return', {})
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -74,11 +74,9 @@ class ChangeBaseClass(iotests.QMPTestCase):
class GeneralChangeTestsBaseClass(ChangeBaseClass): class GeneralChangeTestsBaseClass(ChangeBaseClass):
def test_blockdev_change_medium(self): def test_blockdev_change_medium(self):
result = self.vm.qmp('blockdev-change-medium', self.vm.cmd('blockdev-change-medium',
id=self.device_name, filename=new_img, id=self.device_name, filename=new_img,
format=iotests.imgfmt) format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
self.wait_for_close() self.wait_for_close()
@ -89,8 +87,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
def test_eject(self): def test_eject(self):
result = self.vm.qmp('eject', id=self.device_name, force=True) self.vm.cmd('eject', id=self.device_name, force=True)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
@ -100,8 +97,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp_absent(result, 'return[0]/inserted') self.assert_qmp_absent(result, 'return[0]/inserted')
def test_tray_eject_change(self): def test_tray_eject_change(self):
result = self.vm.qmp('eject', id=self.device_name, force=True) self.vm.cmd('eject', id=self.device_name, force=True)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
@ -110,9 +106,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp(result, 'return[0]/tray_open', True)
self.assert_qmp_absent(result, 'return[0]/inserted') self.assert_qmp_absent(result, 'return[0]/inserted')
result = self.vm.qmp('blockdev-change-medium', id=self.device_name, self.vm.cmd('blockdev-change-medium', id=self.device_name,
filename=new_img, format=iotests.imgfmt) filename=new_img, format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.wait_for_close() self.wait_for_close()
@ -122,9 +117,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
def test_tray_open_close(self): def test_tray_open_close(self):
result = self.vm.qmp('blockdev-open-tray', self.vm.cmd('blockdev-open-tray',
id=self.device_name, force=True) id=self.device_name, force=True)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
@ -136,8 +130,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
else: else:
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-close-tray', id=self.device_name) self.vm.cmd('blockdev-close-tray', id=self.device_name)
self.assert_qmp(result, 'return', {})
if self.has_real_tray or not self.was_empty: if self.has_real_tray or not self.was_empty:
self.wait_for_close() self.wait_for_close()
@ -151,8 +144,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
def test_tray_eject_close(self): def test_tray_eject_close(self):
result = self.vm.qmp('eject', id=self.device_name, force=True) self.vm.cmd('eject', id=self.device_name, force=True)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
@ -161,8 +153,7 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp(result, 'return[0]/tray_open', True)
self.assert_qmp_absent(result, 'return[0]/inserted') self.assert_qmp_absent(result, 'return[0]/inserted')
result = self.vm.qmp('blockdev-close-tray', id=self.device_name) self.vm.cmd('blockdev-close-tray', id=self.device_name)
self.assert_qmp(result, 'return', {})
self.wait_for_close() self.wait_for_close()
@ -172,9 +163,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp_absent(result, 'return[0]/inserted') self.assert_qmp_absent(result, 'return[0]/inserted')
def test_tray_open_change(self): def test_tray_open_change(self):
result = self.vm.qmp('blockdev-open-tray', id=self.device_name, self.vm.cmd('blockdev-open-tray', id=self.device_name,
force=True) force=True)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
@ -186,10 +176,9 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
else: else:
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-change-medium', id=self.device_name, self.vm.cmd('blockdev-change-medium', id=self.device_name,
filename=new_img, filename=new_img,
format=iotests.imgfmt) format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
self.wait_for_close() self.wait_for_close()
@ -199,17 +188,15 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
def test_cycle(self, read_only_node=False): def test_cycle(self, read_only_node=False):
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='new', node_name='new',
driver=iotests.imgfmt, driver=iotests.imgfmt,
read_only=read_only_node, read_only=read_only_node,
file={'filename': new_img, file={'filename': new_img,
'driver': 'file'}) 'driver': 'file'})
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-open-tray', self.vm.cmd('blockdev-open-tray',
id=self.device_name, force=True) id=self.device_name, force=True)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
@ -221,26 +208,23 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
else: else:
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-remove-medium', self.vm.cmd('blockdev-remove-medium',
id=self.device_name) id=self.device_name)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
if self.has_real_tray: if self.has_real_tray:
self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp(result, 'return[0]/tray_open', True)
self.assert_qmp_absent(result, 'return[0]/inserted') self.assert_qmp_absent(result, 'return[0]/inserted')
result = self.vm.qmp('blockdev-insert-medium', self.vm.cmd('blockdev-insert-medium',
id=self.device_name, node_name='new') id=self.device_name, node_name='new')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
if self.has_real_tray: if self.has_real_tray:
self.assert_qmp(result, 'return[0]/tray_open', True) self.assert_qmp(result, 'return[0]/tray_open', True)
self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
result = self.vm.qmp('blockdev-close-tray', id=self.device_name) self.vm.cmd('blockdev-close-tray', id=self.device_name)
self.assert_qmp(result, 'return', {})
self.wait_for_close() self.wait_for_close()
@ -253,9 +237,8 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
self.test_cycle(True) self.test_cycle(True)
def test_close_on_closed(self): def test_close_on_closed(self):
result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
# Should be a no-op # Should be a no-op
self.assert_qmp(result, 'return', {}) self.vm.cmd('blockdev-close-tray', id=self.device_name)
self.assertEqual(self.vm.get_qmp_events(wait=False), []) self.assertEqual(self.vm.get_qmp_events(wait=False), [])
def test_remove_on_closed(self): def test_remove_on_closed(self):
@ -269,12 +252,11 @@ class GeneralChangeTestsBaseClass(ChangeBaseClass):
if not self.has_real_tray: if not self.has_real_tray:
return return
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='new', node_name='new',
driver=iotests.imgfmt, driver=iotests.imgfmt,
file={'filename': new_img, file={'filename': new_img,
'driver': 'file'}) 'driver': 'file'})
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
node_name='new') node_name='new')
@ -307,15 +289,13 @@ class TestInitiallyFilled(GeneralChangeTestsBaseClass):
os.remove(new_img) os.remove(new_img)
def test_insert_on_filled(self): def test_insert_on_filled(self):
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='new', node_name='new',
driver=iotests.imgfmt, driver=iotests.imgfmt,
file={'filename': new_img, file={'filename': new_img,
'driver': 'file'}) 'driver': 'file'})
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-open-tray', id=self.device_name) self.vm.cmd('blockdev-open-tray', id=self.device_name)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
@ -344,14 +324,12 @@ class TestInitiallyEmpty(GeneralChangeTestsBaseClass):
os.remove(new_img) os.remove(new_img)
def test_remove_on_empty(self): def test_remove_on_empty(self):
result = self.vm.qmp('blockdev-open-tray', id=self.device_name) self.vm.cmd('blockdev-open-tray', id=self.device_name)
self.assert_qmp(result, 'return', {})
self.wait_for_open() self.wait_for_open()
result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
# Should be a no-op # Should be a no-op
self.assert_qmp(result, 'return', {}) self.vm.cmd('blockdev-remove-medium', id=self.device_name)
# Do this in a function to avoid leaking variables like case into the global # Do this in a function to avoid leaking variables like case into the global
# name space (otherwise tests would be run for the abstract base classes) # name space (otherwise tests would be run for the abstract base classes)
@ -399,11 +377,10 @@ class TestChangeReadOnly(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-change-medium', id=self.device_name, self.vm.cmd('blockdev-change-medium', id=self.device_name,
filename=new_img, filename=new_img,
format=iotests.imgfmt, format=iotests.imgfmt,
read_only_mode='retain') read_only_mode='retain')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
@ -419,11 +396,10 @@ class TestChangeReadOnly(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-change-medium', id=self.device_name, self.vm.cmd('blockdev-change-medium', id=self.device_name,
filename=new_img, filename=new_img,
format=iotests.imgfmt, format=iotests.imgfmt,
read_only_mode='retain') read_only_mode='retain')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
@ -462,12 +438,11 @@ class TestChangeReadOnly(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-change-medium', self.vm.cmd('blockdev-change-medium',
id=self.device_name, id=self.device_name,
filename=new_img, filename=new_img,
format=iotests.imgfmt, format=iotests.imgfmt,
read_only_mode='read-write') read_only_mode='read-write')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/ro', False)
@ -483,12 +458,11 @@ class TestChangeReadOnly(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/ro', False)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-change-medium', self.vm.cmd('blockdev-change-medium',
id=self.device_name, id=self.device_name,
filename=new_img, filename=new_img,
format=iotests.imgfmt, format=iotests.imgfmt,
read_only_mode='read-only') read_only_mode='read-only')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
@ -503,12 +477,11 @@ class TestChangeReadOnly(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/ro', False)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-change-medium', self.vm.cmd('blockdev-change-medium',
id=self.device_name, id=self.device_name,
filename=new_img, filename=new_img,
format=iotests.imgfmt, format=iotests.imgfmt,
read_only_mode='read-only') read_only_mode='read-only')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
@ -546,11 +519,10 @@ class TestChangeReadOnly(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-change-medium', id=self.device_name, self.vm.cmd('blockdev-change-medium', id=self.device_name,
filename=new_img, filename=new_img,
format=iotests.imgfmt, format=iotests.imgfmt,
read_only_mode='retain') read_only_mode='retain')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
@ -587,27 +559,24 @@ class TestChangeReadOnly(ChangeBaseClass):
self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/ro', False)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='new', node_name='new',
driver=iotests.imgfmt, driver=iotests.imgfmt,
read_only=True, read_only=True,
file={'filename': new_img, file={'filename': new_img,
'driver': 'file'}) 'driver': 'file'})
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', False) self.assert_qmp(result, 'return[0]/inserted/ro', False)
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) self.vm.cmd('blockdev-remove-medium', id=self.device_name)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp_absent(result, 'return[0]/inserted') self.assert_qmp_absent(result, 'return[0]/inserted')
result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, self.vm.cmd('blockdev-insert-medium', id=self.device_name,
node_name='new') node_name='new')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/ro', True) self.assert_qmp(result, 'return[0]/inserted/ro', True)
@ -638,22 +607,19 @@ class TestBlockJobsAfterCycle(ChangeBaseClass):
# For device-less BBs, calling blockdev-open-tray or blockdev-close-tray # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
# is not necessary # is not necessary
result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) self.vm.cmd('blockdev-remove-medium', id=self.device_name)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp_absent(result, 'return[0]/inserted') self.assert_qmp_absent(result, 'return[0]/inserted')
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name='node0', node_name='node0',
driver=iotests.imgfmt, driver=iotests.imgfmt,
file={'filename': old_img, file={'filename': old_img,
'driver': 'file'}) 'driver': 'file'})
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, self.vm.cmd('blockdev-insert-medium', id=self.device_name,
node_name='node0') node_name='node0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
@ -670,10 +636,9 @@ class TestBlockJobsAfterCycle(ChangeBaseClass):
@iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw', @iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw',
'vhdx')) 'vhdx'))
def test_snapshot_and_commit(self): def test_snapshot_and_commit(self):
result = self.vm.qmp('blockdev-snapshot-sync', device='drive0', self.vm.cmd('blockdev-snapshot-sync', device='drive0',
snapshot_file=new_img, snapshot_file=new_img,
format=iotests.imgfmt) format=iotests.imgfmt)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('query-block') result = self.vm.qmp('query-block')
self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
@ -681,16 +646,14 @@ class TestBlockJobsAfterCycle(ChangeBaseClass):
'return[0]/inserted/image/backing-image/filename', 'return[0]/inserted/image/backing-image/filename',
old_img) old_img)
result = self.vm.qmp('block-commit', device='drive0') self.vm.cmd('block-commit', device='drive0')
self.assert_qmp(result, 'return', {})
self.vm.event_wait(name='BLOCK_JOB_READY') self.vm.event_wait(name='BLOCK_JOB_READY')
result = self.vm.qmp('query-block-jobs') result = self.vm.qmp('query-block-jobs')
self.assert_qmp(result, 'return[0]/device', 'drive0') self.assert_qmp(result, 'return[0]/device', 'drive0')
result = self.vm.qmp('block-job-complete', device='drive0') self.vm.cmd('block-job-complete', device='drive0')
self.assert_qmp(result, 'return', {})
self.vm.event_wait(name='BLOCK_JOB_COMPLETED') self.vm.event_wait(name='BLOCK_JOB_COMPLETED')

View File

@ -24,6 +24,7 @@
import os import os
import iotests import iotests
from iotests import try_remove from iotests import try_remove
from qemu.qmp.qmp_client import ExecuteError
def io_write_patterns(img, patterns): def io_write_patterns(img, patterns):
@ -141,8 +142,7 @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
def do_qmp_backup(self, error='Input/output error', **kwargs): def do_qmp_backup(self, error='Input/output error', **kwargs):
res = self.vm.qmp('drive-backup', **kwargs) self.vm.cmd('drive-backup', **kwargs)
self.assert_qmp(res, 'return', {})
return self.wait_qmp_backup(kwargs['device'], error) return self.wait_qmp_backup(kwargs['device'], error)
@ -201,9 +201,8 @@ class TestIncrementalBackupBase(iotests.QMPTestCase):
def add_bitmap(self, name, drive, **kwargs): def add_bitmap(self, name, drive, **kwargs):
bitmap = Bitmap(name, drive) bitmap = Bitmap(name, drive)
self.bitmaps.append(bitmap) self.bitmaps.append(bitmap)
result = self.vm.qmp('block-dirty-bitmap-add', node=drive['id'], self.vm.cmd('block-dirty-bitmap-add', node=drive['id'],
name=bitmap.name, **kwargs) name=bitmap.name, **kwargs)
self.assert_qmp(result, 'return', {})
return bitmap return bitmap
@ -388,13 +387,12 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
('0x64', '32736k', '64k'))) ('0x64', '32736k', '64k')))
bitmap1 = self.add_bitmap('bitmap1', drive0) bitmap1 = self.add_bitmap('bitmap1', drive0)
result = self.vm.qmp('transaction', actions=[ self.vm.cmd('transaction', actions=[
transaction_bitmap_clear(bitmap0.drive['id'], bitmap0.name), transaction_bitmap_clear(bitmap0.drive['id'], bitmap0.name),
transaction_bitmap_clear(bitmap1.drive['id'], bitmap1.name), transaction_bitmap_clear(bitmap1.drive['id'], bitmap1.name),
transaction_drive_backup(drive0['id'], drive0['backup'], transaction_drive_backup(drive0['id'], drive0['backup'],
sync='full', format=drive0['fmt']) sync='full', format=drive0['fmt'])
]) ])
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive0['id']) self.wait_until_completed(drive0['id'])
self.files.append(drive0['backup']) self.files.append(drive0['backup'])
@ -417,7 +415,7 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
('0xcd', '32M', '124k'))) ('0xcd', '32M', '124k')))
# Create a blkdebug interface to this img as 'drive1' # Create a blkdebug interface to this img as 'drive1'
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name=drive1['id'], node_name=drive1['id'],
driver=drive1['fmt'], driver=drive1['fmt'],
file={ file={
@ -440,7 +438,6 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
}], }],
} }
) )
self.assert_qmp(result, 'return', {})
# Create bitmaps and full backups for both drives # Create bitmaps and full backups for both drives
drive0 = self.drives[0] drive0 = self.drives[0]
@ -475,9 +472,8 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
format=drive1['fmt'], mode='existing', format=drive1['fmt'], mode='existing',
bitmap=dr1bm0.name) bitmap=dr1bm0.name)
] ]
result = self.vm.qmp('transaction', actions=transaction, self.vm.cmd('transaction', actions=transaction,
properties={'completion-mode': 'grouped'} ) properties={'completion-mode': 'grouped'} )
self.assert_qmp(result, 'return', {})
# Observe that drive0's backup is cancelled and drive1 completes with # Observe that drive0's backup is cancelled and drive1 completes with
# an error. # an error.
@ -504,9 +500,8 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
target1 = self.prepare_backup(dr1bm0) target1 = self.prepare_backup(dr1bm0)
# Re-run the exact same transaction. # Re-run the exact same transaction.
result = self.vm.qmp('transaction', actions=transaction, self.vm.cmd('transaction', actions=transaction,
properties={'completion-mode':'grouped'}) properties={'completion-mode':'grouped'})
self.assert_qmp(result, 'return', {})
# Both should complete successfully this time. # Both should complete successfully this time.
self.assertTrue(self.wait_qmp_backup(drive0['id'])) self.assertTrue(self.wait_qmp_backup(drive0['id']))
@ -567,7 +562,7 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
The granularity must always be a power of 2. The granularity must always be a power of 2.
''' '''
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.assertRaises(AssertionError, self.add_bitmap, self.assertRaises(ExecuteError, self.add_bitmap,
'bitmap0', self.drives[0], 'bitmap0', self.drives[0],
granularity=64000) granularity=64000)
@ -585,9 +580,8 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
self.add_bitmap('bitmap0', self.drives[0]) self.add_bitmap('bitmap0', self.drives[0])
res = self.vm.qmp('block_resize', device=self.drives[0]['id'], self.vm.cmd('block_resize', device=self.drives[0]['id'],
size=(65 * 1048576)) size=(65 * 1048576))
self.assert_qmp(res, 'return', {})
# Dirty the image past the old end # Dirty the image past the old end
self.vm.hmp_qemu_io(self.drives[0]['id'], 'write 64M 64k') self.vm.hmp_qemu_io(self.drives[0]['id'], 'write 64M 64k')
@ -617,7 +611,7 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
''' '''
drive0 = self.drives[0] drive0 = self.drives[0]
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name=drive0['id'], node_name=drive0['id'],
driver=drive0['fmt'], driver=drive0['fmt'],
file={ file={
@ -640,7 +634,6 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
}], }],
} }
) )
self.assert_qmp(result, 'return', {})
self.create_anchor_backup(drive0) self.create_anchor_backup(drive0)
self.add_bitmap('bitmap0', drive0) self.add_bitmap('bitmap0', drive0)
@ -668,29 +661,28 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
drive0 = self.drives[0] drive0 = self.drives[0]
# NB: The blkdebug script here looks for a "flush, read" pattern. # NB: The blkdebug script here looks for a "flush, read" pattern.
# The flush occurs in hmp_io_writes, and the read during the block job. # The flush occurs in hmp_io_writes, and the read during the block job.
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
node_name=drive0['id'], node_name=drive0['id'],
driver=drive0['fmt'], driver=drive0['fmt'],
file={ file={
'driver': 'blkdebug', 'driver': 'blkdebug',
'image': { 'image': {
'driver': 'file', 'driver': 'file',
'filename': drive0['file'] 'filename': drive0['file']
}, },
'set-state': [{ 'set-state': [{
'event': 'flush_to_disk', 'event': 'flush_to_disk',
'state': 1, 'state': 1,
'new_state': 2 'new_state': 2
}], }],
'inject-error': [{ 'inject-error': [{
'event': 'read_aio', 'event': 'read_aio',
'errno': 5, 'errno': 5,
'state': 2, 'state': 2,
'immediately': False, 'immediately': False,
'once': True 'once': True
}], }],
}) })
self.assert_qmp(result, 'return', {})
self.create_anchor_backup(drive0) self.create_anchor_backup(drive0)
bitmap = self.add_bitmap('bitmap0', drive0) bitmap = self.add_bitmap('bitmap0', drive0)
@ -711,16 +703,15 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
# Start backup # Start backup
parent, _ = bitmap.last_target() parent, _ = bitmap.last_target()
target = self.prepare_backup(bitmap, parent) target = self.prepare_backup(bitmap, parent)
res = self.vm.qmp('drive-backup', self.vm.cmd('drive-backup',
job_id=bitmap.drive['id'], job_id=bitmap.drive['id'],
device=bitmap.drive['id'], device=bitmap.drive['id'],
sync='incremental', sync='incremental',
bitmap=bitmap.name, bitmap=bitmap.name,
format=bitmap.drive['fmt'], format=bitmap.drive['fmt'],
target=target, target=target,
mode='existing', mode='existing',
on_source_error='stop') on_source_error='stop')
self.assert_qmp(res, 'return', {})
# Wait for the error # Wait for the error
event = self.vm.event_wait(name="BLOCK_JOB_ERROR", event = self.vm.event_wait(name="BLOCK_JOB_ERROR",
@ -739,8 +730,7 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
})) }))
# Resume and check incremental backup for consistency # Resume and check incremental backup for consistency
res = self.vm.qmp('block-job-resume', device=bitmap.drive['id']) self.vm.cmd('block-job-resume', device=bitmap.drive['id'])
self.assert_qmp(res, 'return', {})
self.wait_qmp_backup(bitmap.drive['id']) self.wait_qmp_backup(bitmap.drive['id'])
# Bitmap Status Check # Bitmap Status Check

View File

@ -55,11 +55,9 @@ class TestStopWithBlockJob(iotests.QMPTestCase):
def do_test_stop(self, cmd, **args): def do_test_stop(self, cmd, **args):
"""Test 'stop' while block job is running on a throttled drive. """Test 'stop' while block job is running on a throttled drive.
The 'stop' command shouldn't drain the job""" The 'stop' command shouldn't drain the job"""
result = self.vm.qmp(cmd, **args) self.vm.cmd(cmd, **args)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp("stop") self.vm.cmd("stop")
self.assert_qmp(result, 'return', {})
result = self.vm.qmp("query-block-jobs") result = self.vm.qmp("query-block-jobs")
self.assert_qmp(result, 'return[0]/status', 'running') self.assert_qmp(result, 'return[0]/status', 'running')
@ -87,7 +85,7 @@ class TestStopWithBlockJob(iotests.QMPTestCase):
iotests.qemu_img('create', '-f', iotests.imgfmt, self.overlay_img, iotests.qemu_img('create', '-f', iotests.imgfmt, self.overlay_img,
'1G') '1G')
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', {
'node-name': 'overlay', 'node-name': 'overlay',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
@ -95,11 +93,9 @@ class TestStopWithBlockJob(iotests.QMPTestCase):
'filename': self.overlay_img 'filename': self.overlay_img
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-snapshot', self.vm.cmd('blockdev-snapshot',
node='source', overlay='overlay') node='source', overlay='overlay')
self.assert_qmp(result, 'return', {})
self.do_test_stop('block-commit', device='drive0', top_node='source') self.do_test_stop('block-commit', device='drive0', top_node='source')

View File

@ -47,9 +47,8 @@ class TestSingleDrive(iotests.QMPTestCase):
pass pass
def test_mirror_discard(self): def test_mirror_discard(self):
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
target=target_img) target=target_img)
self.assert_qmp(result, 'return', {})
self.vm.hmp_qemu_io('drive0', 'discard 0 64k') self.vm.hmp_qemu_io('drive0', 'discard 0 64k')
self.complete_and_wait('drive0') self.complete_and_wait('drive0')
self.vm.shutdown() self.vm.shutdown()

View File

@ -58,8 +58,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
'file': {'driver': 'file', 'file': {'driver': 'file',
'node-name': file_node, 'node-name': file_node,
'filename': base_img}} 'filename': base_img}}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
self.checkBlockDriverState(file_node) self.checkBlockDriverState(file_node)
@ -73,8 +72,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
'backing': None, 'backing': None,
'file': {'driver': 'file', 'file': {'driver': 'file',
'filename': new_img}} 'filename': new_img}}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
# Delete a BlockDriverState # Delete a BlockDriverState
@ -89,17 +87,14 @@ class TestBlockdevDel(iotests.QMPTestCase):
# Add a device model # Add a device model
def addDeviceModel(self, device, backend, driver = 'virtio-blk'): def addDeviceModel(self, device, backend, driver = 'virtio-blk'):
result = self.vm.qmp('device_add', id = device, self.vm.cmd('device_add', id = device,
driver = driver, drive = backend) driver = driver, drive = backend)
self.assert_qmp(result, 'return', {})
# Delete a device model # Delete a device model
def delDeviceModel(self, device, is_virtio_blk = True): def delDeviceModel(self, device, is_virtio_blk = True):
result = self.vm.qmp('device_del', id = device) self.vm.cmd('device_del', id = device)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('system_reset') self.vm.cmd('system_reset')
self.assert_qmp(result, 'return', {})
if is_virtio_blk: if is_virtio_blk:
device_path = '/machine/peripheral/%s/virtio-backend' % device device_path = '/machine/peripheral/%s/virtio-backend' % device
@ -126,9 +121,8 @@ class TestBlockdevDel(iotests.QMPTestCase):
# Insert a BlockDriverState # Insert a BlockDriverState
def insertDrive(self, device, node): def insertDrive(self, device, node):
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
result = self.vm.qmp('blockdev-insert-medium', self.vm.cmd('blockdev-insert-medium',
id = device, node_name = node) id = device, node_name = node)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
# Create a snapshot using 'blockdev-snapshot-sync' # Create a snapshot using 'blockdev-snapshot-sync'
@ -139,8 +133,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
'snapshot-file': new_img, 'snapshot-file': new_img,
'snapshot-node-name': overlay, 'snapshot-node-name': overlay,
'format': iotests.imgfmt} 'format': iotests.imgfmt}
result = self.vm.qmp('blockdev-snapshot-sync', conv_keys=False, **opts) self.vm.cmd('blockdev-snapshot-sync', conv_keys=False, **opts)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
self.checkBlockDriverState(overlay) self.checkBlockDriverState(overlay)
@ -148,9 +141,8 @@ class TestBlockdevDel(iotests.QMPTestCase):
def createSnapshot(self, node, overlay): def createSnapshot(self, node, overlay):
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
self.checkBlockDriverState(overlay) self.checkBlockDriverState(overlay)
result = self.vm.qmp('blockdev-snapshot', self.vm.cmd('blockdev-snapshot',
node = node, overlay = overlay) node = node, overlay = overlay)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
self.checkBlockDriverState(overlay) self.checkBlockDriverState(overlay)
@ -163,14 +155,12 @@ class TestBlockdevDel(iotests.QMPTestCase):
'node-name': new_node, 'node-name': new_node,
'sync': 'top', 'sync': 'top',
'format': iotests.imgfmt} 'format': iotests.imgfmt}
result = self.vm.qmp('drive-mirror', conv_keys=False, **opts) self.vm.cmd('drive-mirror', conv_keys=False, **opts)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(new_node) self.checkBlockDriverState(new_node)
# Complete an existing block job # Complete an existing block job
def completeBlockJob(self, id, node_before, node_after): def completeBlockJob(self, id, node_before, node_after):
result = self.vm.qmp('block-job-complete', device=id) self.vm.cmd('block-job-complete', device=id)
self.assert_qmp(result, 'return', {})
self.wait_until_completed(id) self.wait_until_completed(id)
# Add a BlkDebug node # Add a BlkDebug node
@ -186,8 +176,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
opts = {'driver': 'blkdebug', opts = {'driver': 'blkdebug',
'node-name': debug, 'node-name': debug,
'image': image} 'image': image}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(node) self.checkBlockDriverState(node)
self.checkBlockDriverState(debug) self.checkBlockDriverState(debug)
@ -211,8 +200,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
'node-name': blkverify, 'node-name': blkverify,
'test': node_0, 'test': node_0,
'raw': node_1} 'raw': node_1}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(test) self.checkBlockDriverState(test)
self.checkBlockDriverState(raw) self.checkBlockDriverState(raw)
self.checkBlockDriverState(blkverify) self.checkBlockDriverState(blkverify)
@ -235,8 +223,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
'node-name': quorum, 'node-name': quorum,
'vote-threshold': 1, 'vote-threshold': 1,
'children': [ child_0, child_1 ]} 'children': [ child_0, child_1 ]}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(child0) self.checkBlockDriverState(child0)
self.checkBlockDriverState(child1) self.checkBlockDriverState(child1)
self.checkBlockDriverState(quorum) self.checkBlockDriverState(quorum)

View File

@ -58,8 +58,7 @@ class NBDBlockdevAddBase(iotests.QMPTestCase):
def client_test(self, filename, address, export=None, def client_test(self, filename, address, export=None,
node_name='nbd-blockdev', delete=True): node_name='nbd-blockdev', delete=True):
bao = self.blockdev_add_options(address, export, node_name) bao = self.blockdev_add_options(address, export, node_name)
result = self.vm.qmp('blockdev-add', **bao) self.vm.cmd('blockdev-add', bao)
self.assert_qmp(result, 'return', {})
found = False found = False
result = self.vm.qmp('query-named-block-nodes') result = self.vm.qmp('query-named-block-nodes')
@ -75,8 +74,7 @@ class NBDBlockdevAddBase(iotests.QMPTestCase):
self.assertTrue(found) self.assertTrue(found)
if delete: if delete:
result = self.vm.qmp('blockdev-del', node_name=node_name) self.vm.cmd('blockdev-del', node_name=node_name)
self.assert_qmp(result, 'return', {})
class QemuNBD(NBDBlockdevAddBase): class QemuNBD(NBDBlockdevAddBase):
@ -158,16 +156,14 @@ class BuiltinNBD(NBDBlockdevAddBase):
self.assert_qmp(result, 'return', {}) self.assert_qmp(result, 'return', {})
if export_name is None: if export_name is None:
result = self.server.qmp('nbd-server-add', device='nbd-export') self.server.cmd('nbd-server-add', device='nbd-export')
else: else:
result = self.server.qmp('nbd-server-add', device='nbd-export', self.server.cmd('nbd-server-add', device='nbd-export',
name=export_name) name=export_name)
self.assert_qmp(result, 'return', {})
if export_name2 is not None: if export_name2 is not None:
result = self.server.qmp('nbd-server-add', device='nbd-export', self.server.cmd('nbd-server-add', device='nbd-export',
name=export_name2) name=export_name2)
self.assert_qmp(result, 'return', {})
return True return True
@ -175,8 +171,7 @@ class BuiltinNBD(NBDBlockdevAddBase):
self.assertTrue(self._try_server_up(address, export_name, export_name2)) self.assertTrue(self._try_server_up(address, export_name, export_name2))
def _server_down(self): def _server_down(self):
result = self.server.qmp('nbd-server-stop') self.server.cmd('nbd-server-stop')
self.assert_qmp(result, 'return', {})
def do_test_inet(self, export_name=None): def do_test_inet(self, export_name=None):
while True: while True:
@ -218,10 +213,8 @@ class BuiltinNBD(NBDBlockdevAddBase):
flatten_sock_addr(address), 'exp1', 'node1', False) flatten_sock_addr(address), 'exp1', 'node1', False)
self.client_test('nbd://localhost:%i/%s' % (nbd_port, 'exp2'), self.client_test('nbd://localhost:%i/%s' % (nbd_port, 'exp2'),
flatten_sock_addr(address), 'exp2', 'node2', False) flatten_sock_addr(address), 'exp2', 'node2', False)
result = self.vm.qmp('blockdev-del', node_name='node1') self.vm.cmd('blockdev-del', node_name='node1')
self.assert_qmp(result, 'return', {}) self.vm.cmd('blockdev-del', node_name='node2')
result = self.vm.qmp('blockdev-del', node_name='node2')
self.assert_qmp(result, 'return', {})
self._server_down() self._server_down()
def test_inet6(self): def test_inet6(self):
@ -272,8 +265,7 @@ class BuiltinNBD(NBDBlockdevAddBase):
result = self.vm.send_fd_scm(fd=sockfd.fileno()) result = self.vm.send_fd_scm(fd=sockfd.fileno())
self.assertEqual(result, 0, 'Failed to send socket FD') self.assertEqual(result, 0, 'Failed to send socket FD')
result = self.vm.qmp('getfd', fdname='nbd-fifo') self.vm.cmd('getfd', fdname='nbd-fifo')
self.assert_qmp(result, 'return', {})
address = { 'type': 'fd', address = { 'type': 'fd',
'data': { 'str': 'nbd-fifo' } } 'data': { 'str': 'nbd-fifo' } }

View File

@ -79,14 +79,13 @@ class TestActiveMirror(iotests.QMPTestCase):
self.vm.hmp_qemu_io('source', 'aio_write -z %i 1M' % offset) self.vm.hmp_qemu_io('source', 'aio_write -z %i 1M' % offset)
# Start the block job # Start the block job
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
filter_node_name='mirror-node', filter_node_name='mirror-node',
device='source-node', device='source-node',
target='target-node', target='target-node',
sync='full', sync='full',
copy_mode='write-blocking') copy_mode='write-blocking')
self.assert_qmp(result, 'return', {})
# Start some more requests # Start some more requests
for offset in range(3 * self.image_len // 8, 5 * self.image_len // 8, 1024 * 1024): for offset in range(3 * self.image_len // 8, 5 * self.image_len // 8, 1024 * 1024):
@ -125,23 +124,21 @@ class TestActiveMirror(iotests.QMPTestCase):
result = self.vm.hmp_qemu_io('source', 'write -P 1 0 2M') result = self.vm.hmp_qemu_io('source', 'write -P 1 0 2M')
# Start the block job (very slowly) # Start the block job (very slowly)
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
filter_node_name='mirror-node', filter_node_name='mirror-node',
device='source-node', device='source-node',
target='target-node', target='target-node',
sync='full', sync='full',
copy_mode='write-blocking', copy_mode='write-blocking',
buf_size=(1048576 // 4), buf_size=(1048576 // 4),
speed=1) speed=1)
self.assert_qmp(result, 'return', {})
# Start an unaligned request to a dirty area # Start an unaligned request to a dirty area
result = self.vm.hmp_qemu_io('source', 'write -P 2 %i 1' % (1048576 + 42)) result = self.vm.hmp_qemu_io('source', 'write -P 2 %i 1' % (1048576 + 42))
# Let the job finish # Let the job finish
result = self.vm.qmp('block-job-set-speed', device='mirror', speed=0) self.vm.cmd('block-job-set-speed', device='mirror', speed=0)
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive='mirror') self.complete_and_wait(drive='mirror')
self.potential_writes_in_flight = False self.potential_writes_in_flight = False
@ -151,14 +148,14 @@ class TestActiveMirror(iotests.QMPTestCase):
result = self.vm.hmp_qemu_io('source', 'write -P 1 0 2M') result = self.vm.hmp_qemu_io('source', 'write -P 1 0 2M')
# Start the block job (very slowly) # Start the block job (very slowly)
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
filter_node_name='mirror-node', filter_node_name='mirror-node',
device='source-node', device='source-node',
target='target-node', target='target-node',
sync='full', sync='full',
copy_mode='write-blocking', copy_mode='write-blocking',
speed=1) speed=1)
self.vm.hmp_qemu_io('source', 'break write_aio A') self.vm.hmp_qemu_io('source', 'break write_aio A')
self.vm.hmp_qemu_io('source', 'aio_write 0 1M') # 1 self.vm.hmp_qemu_io('source', 'aio_write 0 1M') # 1
@ -189,8 +186,7 @@ class TestActiveMirror(iotests.QMPTestCase):
# After resuming 4, one of 2 and 3 goes first and set in_flight_bitmap, # After resuming 4, one of 2 and 3 goes first and set in_flight_bitmap,
# so the other will wait for it. # so the other will wait for it.
result = self.vm.qmp('block-job-set-speed', device='mirror', speed=0) self.vm.cmd('block-job-set-speed', device='mirror', speed=0)
self.assert_qmp(result, 'return', {})
self.complete_and_wait(drive='mirror') self.complete_and_wait(drive='mirror')
self.potential_writes_in_flight = False self.potential_writes_in_flight = False
@ -211,7 +207,7 @@ class TestThrottledWithNbdExportBase(iotests.QMPTestCase):
self.vm = iotests.VM() self.vm = iotests.VM()
self.vm.launch() self.vm.launch()
result = self.vm.qmp('object-add', **{ self.vm.cmd('object-add', **{
'qom-type': 'throttle-group', 'qom-type': 'throttle-group',
'id': 'thrgr', 'id': 'thrgr',
'limits': { 'limits': {
@ -219,9 +215,8 @@ class TestThrottledWithNbdExportBase(iotests.QMPTestCase):
'iops-total-max': self.iops 'iops-total-max': self.iops
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', **{
'node-name': 'source-node', 'node-name': 'source-node',
'driver': 'throttle', 'driver': 'throttle',
'throttle-group': 'thrgr', 'throttle-group': 'thrgr',
@ -233,9 +228,8 @@ class TestThrottledWithNbdExportBase(iotests.QMPTestCase):
} }
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', **{ self.vm.cmd('blockdev-add', **{
'node-name': 'target-node', 'node-name': 'target-node',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
@ -243,23 +237,20 @@ class TestThrottledWithNbdExportBase(iotests.QMPTestCase):
'filename': target_img 'filename': target_img
} }
}) })
self.assert_qmp(result, 'return', {})
self.nbd_sock = iotests.file_path('nbd.sock', self.nbd_sock = iotests.file_path('nbd.sock',
base_dir=iotests.sock_dir) base_dir=iotests.sock_dir)
self.nbd_url = f'nbd+unix:///source-node?socket={self.nbd_sock}' self.nbd_url = f'nbd+unix:///source-node?socket={self.nbd_sock}'
result = self.vm.qmp('nbd-server-start', addr={ self.vm.cmd('nbd-server-start', addr={
'type': 'unix', 'type': 'unix',
'data': { 'data': {
'path': self.nbd_sock 'path': self.nbd_sock
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-export-add', id='exp0', type='nbd', self.vm.cmd('block-export-add', id='exp0', type='nbd',
node_name='source-node', writable=True) node_name='source-node', writable=True)
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
# Wait for background requests to settle # Wait for background requests to settle
@ -312,15 +303,14 @@ class TestLowThrottledWithNbdExport(TestThrottledWithNbdExportBase):
# Launch the mirror job # Launch the mirror job
mirror_buf_size = 65536 mirror_buf_size = 65536
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
filter_node_name='mirror-node', filter_node_name='mirror-node',
device='source-node', device='source-node',
target='target-node', target='target-node',
sync='full', sync='full',
copy_mode='write-blocking', copy_mode='write-blocking',
buf_size=mirror_buf_size) buf_size=mirror_buf_size)
self.assert_qmp(result, 'return', {})
# We create the external requests via qemu-io processes on the NBD # We create the external requests via qemu-io processes on the NBD
# server. Have their offset start in the middle of the image so they # server. Have their offset start in the middle of the image so they
@ -408,13 +398,12 @@ class TestHighThrottledWithNbdExport(TestThrottledWithNbdExportBase):
# start blockdev-mirror # start blockdev-mirror
self.vm.qtest(f'clock_step {1 * 1000 * 1000 * 1000}') self.vm.qtest(f'clock_step {1 * 1000 * 1000 * 1000}')
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='source-node', device='source-node',
target='target-node', target='target-node',
sync='full', sync='full',
copy_mode='write-blocking') copy_mode='write-blocking')
self.assert_qmp(result, 'return', {})
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -41,16 +41,16 @@ class TestUnaligned(iotests.QMPTestCase):
pass pass
def test_unaligned(self): def test_unaligned(self):
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
granularity=65536, target=target_img) granularity=65536, target=target_img)
self.complete_and_wait() self.complete_and_wait()
self.vm.shutdown() self.vm.shutdown()
self.assertEqual(iotests.image_size(test_img), iotests.image_size(target_img), self.assertEqual(iotests.image_size(test_img), iotests.image_size(target_img),
"Target size doesn't match source when granularity when unaligend") "Target size doesn't match source when granularity when unaligend")
def test_unaligned_with_update(self): def test_unaligned_with_update(self):
result = self.vm.qmp('drive-mirror', device='drive0', sync='full', self.vm.cmd('drive-mirror', device='drive0', sync='full',
granularity=65536, target=target_img) granularity=65536, target=target_img)
self.wait_ready() self.wait_ready()
self.vm.hmp_qemu_io('drive0', 'write 0 512') self.vm.hmp_qemu_io('drive0', 'write 0 512')
self.complete_and_wait(wait_ready=False) self.complete_and_wait(wait_ready=False)

View File

@ -110,8 +110,7 @@ class BaseClass(iotests.QMPTestCase):
elif self.target_blockdev_backing: elif self.target_blockdev_backing:
options['backing'] = self.target_blockdev_backing options['backing'] = self.target_blockdev_backing
result = self.vm.qmp('blockdev-add', **options) self.vm.cmd('blockdev-add', options)
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
self.vm.shutdown() self.vm.shutdown()
@ -178,20 +177,18 @@ class MirrorBaseClass(BaseClass):
def runMirror(self, sync): def runMirror(self, sync):
if self.cmd == 'blockdev-mirror': if self.cmd == 'blockdev-mirror':
result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source', self.vm.cmd(self.cmd, job_id='mirror-job', device='source',
sync=sync, target='target', sync=sync, target='target',
auto_finalize=False) auto_finalize=False)
else: else:
if self.existing: if self.existing:
mode = 'existing' mode = 'existing'
else: else:
mode = 'absolute-paths' mode = 'absolute-paths'
result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source', self.vm.cmd(self.cmd, job_id='mirror-job', device='source',
sync=sync, target=target_img, sync=sync, target=target_img,
format=iotests.imgfmt, mode=mode, format=iotests.imgfmt, mode=mode,
node_name='target', auto_finalize=False) node_name='target', auto_finalize=False)
self.assert_qmp(result, 'return', {})
self.vm.run_job('mirror-job', auto_finalize=False, self.vm.run_job('mirror-job', auto_finalize=False,
pre_finalize=self.openBacking, auto_dismiss=True) pre_finalize=self.openBacking, auto_dismiss=True)
@ -258,16 +255,14 @@ class TestBlockdevMirrorReopen(MirrorBaseClass):
def openBacking(self): def openBacking(self):
if not self.target_open_with_backing: if not self.target_open_with_backing:
result = self.vm.qmp('blockdev-add', node_name="backing", self.vm.cmd('blockdev-add', node_name="backing",
driver="null-co") driver="null-co")
self.assert_qmp(result, 'return', {}) self.vm.cmd('blockdev-reopen', options=[{
result = self.vm.qmp('blockdev-reopen', options=[{ 'node-name': "target",
'node-name': "target", 'driver': iotests.imgfmt,
'driver': iotests.imgfmt, 'file': "target-file",
'file': "target-file", 'backing': "backing"
'backing': "backing" }])
}])
self.assert_qmp(result, 'return', {})
class TestBlockdevMirrorReopenIothread(TestBlockdevMirrorReopen): class TestBlockdevMirrorReopenIothread(TestBlockdevMirrorReopen):
use_iothread = True use_iothread = True
@ -281,12 +276,10 @@ class TestBlockdevMirrorSnapshot(MirrorBaseClass):
def openBacking(self): def openBacking(self):
if not self.target_open_with_backing: if not self.target_open_with_backing:
result = self.vm.qmp('blockdev-add', node_name="backing", self.vm.cmd('blockdev-add', node_name="backing",
driver="null-co") driver="null-co")
self.assert_qmp(result, 'return', {}) self.vm.cmd('blockdev-snapshot', node="backing",
result = self.vm.qmp('blockdev-snapshot', node="backing", overlay="target")
overlay="target")
self.assert_qmp(result, 'return', {})
class TestBlockdevMirrorSnapshotIothread(TestBlockdevMirrorSnapshot): class TestBlockdevMirrorSnapshotIothread(TestBlockdevMirrorSnapshot):
use_iothread = True use_iothread = True
@ -295,14 +288,12 @@ class TestCommit(BaseClass):
existing = False existing = False
def testCommit(self): def testCommit(self):
result = self.vm.qmp('block-commit', job_id='commit-job', self.vm.cmd('block-commit', job_id='commit-job',
device='source', base=back1_img) device='source', base=back1_img)
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_READY') self.vm.event_wait('BLOCK_JOB_READY')
result = self.vm.qmp('block-job-complete', device='commit-job') self.vm.cmd('block-job-complete', device='commit-job')
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_COMPLETED') self.vm.event_wait('BLOCK_JOB_COMPLETED')

View File

@ -116,9 +116,8 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
sha256_2 = self.getSha256() sha256_2 = self.getSha256()
assert sha256_1 != sha256_2 # Otherwise, it's not very interesting. assert sha256_1 != sha256_2 # Otherwise, it's not very interesting.
result = self.vm.qmp('block-dirty-bitmap-clear', node='drive0', self.vm.cmd('block-dirty-bitmap-clear', node='drive0',
name='bitmap0') name='bitmap0')
self.assert_qmp(result, 'return', {})
# Start with regions1 # Start with regions1
@ -137,7 +136,7 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
assert sha256_1 == self.getSha256() assert sha256_1 == self.getSha256()
# Reopen to RW # Reopen to RW
result = self.vm.qmp('blockdev-reopen', options=[{ self.vm.cmd('blockdev-reopen', options=[{
'node-name': 'node0', 'node-name': 'node0',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
@ -146,7 +145,6 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
}, },
'read-only': False 'read-only': False
}]) }])
self.assert_qmp(result, 'return', {})
# Check that bitmap is reopened to RW and we can write to it. # Check that bitmap is reopened to RW and we can write to it.
self.writeRegions(regions2) self.writeRegions(regions2)

View File

@ -45,8 +45,7 @@ class TestInvalidateAutoclear(iotests.QMPTestCase):
self.vm_b.add_incoming("exec: cat '" + migfile + "'") self.vm_b.add_incoming("exec: cat '" + migfile + "'")
def test_migration(self): def test_migration(self):
result = self.vm_a.qmp('migrate', uri='exec:cat>' + migfile) self.vm_a.cmd('migrate', uri='exec:cat>' + migfile)
self.assert_qmp(result, 'return', {});
self.assertNotEqual(self.vm_a.event_wait("STOP"), None) self.assertNotEqual(self.vm_a.event_wait("STOP"), None)
with open(disk, 'r+b') as f: with open(disk, 'r+b') as f:

View File

@ -44,10 +44,8 @@ class TestNbdServerRemove(iotests.QMPTestCase):
} }
} }
result = self.vm.qmp('nbd-server-start', addr=address) self.vm.cmd('nbd-server-start', addr=address)
self.assert_qmp(result, 'return', {}) self.vm.cmd('nbd-server-add', device='drive0', name='exp')
result = self.vm.qmp('nbd-server-add', device='drive0', name='exp')
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
self.vm.shutdown() self.vm.shutdown()

View File

@ -41,34 +41,30 @@ iotests.script_initialize(supported_fmts=['qcow2', 'raw'])
def start_mirror(vm, speed=None, buf_size=None): def start_mirror(vm, speed=None, buf_size=None):
vm.launch() vm.launch()
ret = vm.qmp('blockdev-add', vm.cmd('blockdev-add',
node_name='source', node_name='source',
driver='null-co', driver='null-co',
size=1048576) size=1048576)
assert ret['return'] == {}
ret = vm.qmp('blockdev-add', vm.cmd('blockdev-add',
node_name='target', node_name='target',
driver='null-co', driver='null-co',
size=1048576) size=1048576)
assert ret['return'] == {}
if speed is not None: if speed is not None:
ret = vm.qmp('blockdev-mirror', vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='source', device='source',
target='target', target='target',
sync='full', sync='full',
speed=speed, speed=speed,
buf_size=buf_size) buf_size=buf_size)
else: else:
ret = vm.qmp('blockdev-mirror', vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='source', device='source',
target='target', target='target',
sync='full') sync='full')
assert ret['return'] == {}
log('') log('')
@ -150,38 +146,33 @@ with iotests.VM() as vm, \
vm.launch() vm.launch()
ret = vm.qmp('object-add', qom_type='throttle-group', id='tg', vm.cmd('object-add', qom_type='throttle-group', id='tg',
limits={'bps-read': 4096}) limits={'bps-read': 4096})
assert ret['return'] == {}
ret = vm.qmp('blockdev-add', vm.cmd('blockdev-add',
node_name='source', node_name='source',
driver=iotests.imgfmt, driver=iotests.imgfmt,
file={ file={
'driver': 'file', 'driver': 'file',
'filename': src_img_path 'filename': src_img_path
}) })
assert ret['return'] == {}
ret = vm.qmp('blockdev-add', vm.cmd('blockdev-add',
node_name='throttled-source', node_name='throttled-source',
driver='throttle', driver='throttle',
throttle_group='tg', throttle_group='tg',
file='source') file='source')
assert ret['return'] == {}
ret = vm.qmp('blockdev-add', vm.cmd('blockdev-add',
node_name='target', node_name='target',
driver='null-co', driver='null-co',
size=(64 * 1048576)) size=(64 * 1048576))
assert ret['return'] == {}
ret = vm.qmp('blockdev-mirror', vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='throttled-source', device='throttled-source',
target='target', target='target',
sync='full') sync='full')
assert ret['return'] == {}
log(vm.qmp('quit')) log(vm.qmp('quit'))

View File

@ -136,8 +136,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
def test_incorrect_parameters_single_file(self): def test_incorrect_parameters_single_file(self):
# Open 'hd0' only (no backing files) # Open 'hd0' only (no backing files)
opts = hd_opts(0) opts = hd_opts(0)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
original_graph = self.vm.qmp('query-named-block-nodes') original_graph = self.vm.qmp('query-named-block-nodes')
# We can reopen the image passing the same options # We can reopen the image passing the same options
@ -171,8 +170,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.check_node_graph(original_graph) self.check_node_graph(original_graph)
# Remove the node # Remove the node
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
# This test opens an image with a backing file and tries to reopen # This test opens an image with a backing file and tries to reopen
# it with illegal / incorrect parameters. # it with illegal / incorrect parameters.
@ -180,8 +178,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# Open hd1 omitting the backing options (hd0 will be opened # Open hd1 omitting the backing options (hd0 will be opened
# with the default options) # with the default options)
opts = hd_opts(1) opts = hd_opts(1)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
original_graph = self.vm.qmp('query-named-block-nodes') original_graph = self.vm.qmp('query-named-block-nodes')
# We can't reopen the image passing the same options, 'backing' is mandatory # We can't reopen the image passing the same options, 'backing' is mandatory
@ -213,8 +210,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.check_node_graph(original_graph) self.check_node_graph(original_graph)
# Remove the node # Remove the node
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd1') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd1')
self.assert_qmp(result, 'return', {})
# Reopen an image several times changing some of its options # Reopen an image several times changing some of its options
def test_reopen(self): def test_reopen(self):
@ -230,8 +226,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# Open the hd1 image passing all backing options # Open the hd1 image passing all backing options
opts = hd_opts(1) opts = hd_opts(1)
opts['backing'] = hd_opts(0) opts['backing'] = hd_opts(0)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
original_graph = self.vm.qmp('query-named-block-nodes') original_graph = self.vm.qmp('query-named-block-nodes')
# We can reopen the image passing the same options # We can reopen the image passing the same options
@ -306,8 +301,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.assert_qmp_absent(self.get_node('hd1'), 'image/backing-image') self.assert_qmp_absent(self.get_node('hd1'), 'image/backing-image')
# Open the 'hd0' image # Open the 'hd0' image
result = self.vm.qmp('blockdev-add', conv_keys = False, **hd_opts(0)) self.vm.cmd('blockdev-add', conv_keys = False, **hd_opts(0))
self.assert_qmp(result, 'return', {})
# Reopen the hd1 image setting 'hd0' as its backing image # Reopen the hd1 image setting 'hd0' as its backing image
self.reopen(opts, {'backing': 'hd0'}) self.reopen(opts, {'backing': 'hd0'})
@ -326,10 +320,8 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.assert_qmp(result, 'error/desc', "Node 'hd0' is busy: node is used as backing hd of 'hd1'") self.assert_qmp(result, 'error/desc', "Node 'hd0' is busy: node is used as backing hd of 'hd1'")
# But we can remove both nodes if done in the proper order # But we can remove both nodes if done in the proper order
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd1') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd1')
self.assert_qmp(result, 'return', {}) self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
# Reopen a raw image and see the effect of changing the 'offset' option # Reopen a raw image and see the effect of changing the 'offset' option
def test_reopen_raw(self): def test_reopen_raw(self):
@ -345,8 +337,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
qemu_io('-f', 'raw', '-c', 'write -P 0xa1 1M 1M', hd_path[0]) qemu_io('-f', 'raw', '-c', 'write -P 0xa1 1M 1M', hd_path[0])
# Open the raw file with QEMU # Open the raw file with QEMU
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Read 1MB from offset 0 # Read 1MB from offset 0
self.run_qemu_io("hd0", "read -P 0xa0 0 1M") self.run_qemu_io("hd0", "read -P 0xa0 0 1M")
@ -362,8 +353,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.run_qemu_io("hd0", "read -P 0xa0 0 1M") self.run_qemu_io("hd0", "read -P 0xa0 0 1M")
# Remove the block device # Remove the block device
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
# Omitting an option should reset it to the default value, but if # Omitting an option should reset it to the default value, but if
# an option cannot be changed it shouldn't be possible to reset it # an option cannot be changed it shouldn't be possible to reset it
@ -377,8 +367,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
'node-name': 'hd0-file' } } 'node-name': 'hd0-file' } }
# Open the file with QEMU # Open the file with QEMU
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# file.x-check-cache-dropped can be changed... # file.x-check-cache-dropped can be changed...
self.reopen(opts, { 'file.x-check-cache-dropped': False }) self.reopen(opts, { 'file.x-check-cache-dropped': False })
@ -394,8 +383,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.reopen(opts, { 'file.locking': 'off' }) self.reopen(opts, { 'file.locking': 'off' })
# Remove the block device # Remove the block device
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
# This test modifies the node graph a few times by changing the # This test modifies the node graph a few times by changing the
# 'backing' option on reopen and verifies that the guest data that # 'backing' option on reopen and verifies that the guest data that
@ -407,8 +395,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
for i in range(3): for i in range(3):
opts.append(hd_opts(i)) opts.append(hd_opts(i))
opts[i]['backing'] = None opts[i]['backing'] = None
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts[i]) self.vm.cmd('blockdev-add', conv_keys = False, **opts[i])
self.assert_qmp(result, 'return', {})
# hd0 # hd0
self.run_qemu_io("hd0", "read -P 0xa0 0 1M") self.run_qemu_io("hd0", "read -P 0xa0 0 1M")
@ -499,8 +486,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
for i in range(3): for i in range(3):
opts.append(hd_opts(i)) opts.append(hd_opts(i))
opts[i]['backing'] = None opts[i]['backing'] = None
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts[i]) self.vm.cmd('blockdev-add', conv_keys = False, **opts[i])
self.assert_qmp(result, 'return', {})
# hd1 <- hd0, hd1 <- hd2 # hd1 <- hd0, hd1 <- hd2
self.reopen(opts[0], {'backing': 'hd1'}) self.reopen(opts[0], {'backing': 'hd1'})
@ -532,8 +518,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
'node-name': 'bv', 'node-name': 'bv',
'test': 'hd0', 'test': 'hd0',
'raw': 'hd1'} 'raw': 'hd1'}
result = self.vm.qmp('blockdev-add', conv_keys = False, **bvopts) self.vm.cmd('blockdev-add', conv_keys = False, **bvopts)
self.assert_qmp(result, 'return', {})
# blkverify doesn't currently allow reopening. TODO: implement this # blkverify doesn't currently allow reopening. TODO: implement this
self.reopen(bvopts, {}, "Block format 'blkverify' used by node 'bv'" + self.reopen(bvopts, {}, "Block format 'blkverify' used by node 'bv'" +
@ -544,8 +529,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
"Making 'bv' a backing child of 'hd0' would create a cycle") "Making 'bv' a backing child of 'hd0' would create a cycle")
# Delete the blkverify node # Delete the blkverify node
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'bv') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'bv')
self.assert_qmp(result, 'return', {})
# Replace the protocol layer ('file' parameter) of a disk image # Replace the protocol layer ('file' parameter) of a disk image
def test_replace_file(self): def test_replace_file(self):
@ -556,16 +540,13 @@ class TestBlockdevReopen(iotests.QMPTestCase):
hd0_opts = {'driver': 'file', 'node-name': 'hd0-file', 'filename': hd_path[0] } hd0_opts = {'driver': 'file', 'node-name': 'hd0-file', 'filename': hd_path[0] }
hd1_opts = {'driver': 'file', 'node-name': 'hd1-file', 'filename': hd_path[1] } hd1_opts = {'driver': 'file', 'node-name': 'hd1-file', 'filename': hd_path[1] }
result = self.vm.qmp('blockdev-add', conv_keys = False, **hd0_opts) self.vm.cmd('blockdev-add', conv_keys = False, **hd0_opts)
self.assert_qmp(result, 'return', {}) self.vm.cmd('blockdev-add', conv_keys = False, **hd1_opts)
result = self.vm.qmp('blockdev-add', conv_keys = False, **hd1_opts)
self.assert_qmp(result, 'return', {})
# Add a raw format layer that uses hd0-file as its protocol layer # Add a raw format layer that uses hd0-file as its protocol layer
opts = {'driver': 'raw', 'node-name': 'hd', 'file': 'hd0-file'} opts = {'driver': 'raw', 'node-name': 'hd', 'file': 'hd0-file'}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Fill the image with data # Fill the image with data
self.run_qemu_io("hd", "read -P 0 0 10k") self.run_qemu_io("hd", "read -P 0 0 10k")
@ -588,21 +569,18 @@ class TestBlockdevReopen(iotests.QMPTestCase):
def test_insert_throttle_filter(self): def test_insert_throttle_filter(self):
# Add an image to the VM # Add an image to the VM
hd0_opts = hd_opts(0) hd0_opts = hd_opts(0)
result = self.vm.qmp('blockdev-add', conv_keys = False, **hd0_opts) self.vm.cmd('blockdev-add', conv_keys = False, **hd0_opts)
self.assert_qmp(result, 'return', {})
# Create a throttle-group object # Create a throttle-group object
opts = { 'qom-type': 'throttle-group', 'id': 'group0', opts = { 'qom-type': 'throttle-group', 'id': 'group0',
'limits': { 'iops-total': 1000 } } 'limits': { 'iops-total': 1000 } }
result = self.vm.qmp('object-add', conv_keys = False, **opts) self.vm.cmd('object-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Add a throttle filter with the group that we just created. # Add a throttle filter with the group that we just created.
# The filter is not used by anyone yet # The filter is not used by anyone yet
opts = { 'driver': 'throttle', 'node-name': 'throttle0', opts = { 'driver': 'throttle', 'node-name': 'throttle0',
'throttle-group': 'group0', 'file': 'hd0-file' } 'throttle-group': 'group0', 'file': 'hd0-file' }
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Insert the throttle filter between hd0 and hd0-file # Insert the throttle filter between hd0 and hd0-file
self.reopen(hd0_opts, {'file': 'throttle0'}) self.reopen(hd0_opts, {'file': 'throttle0'})
@ -615,15 +593,13 @@ class TestBlockdevReopen(iotests.QMPTestCase):
def test_insert_compress_filter(self): def test_insert_compress_filter(self):
# Add an image to the VM: hd (raw) -> hd0 (qcow2) -> hd0-file (file) # Add an image to the VM: hd (raw) -> hd0 (qcow2) -> hd0-file (file)
opts = {'driver': 'raw', 'node-name': 'hd', 'file': hd_opts(0)} opts = {'driver': 'raw', 'node-name': 'hd', 'file': hd_opts(0)}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Add a 'compress' filter # Add a 'compress' filter
filter_opts = {'driver': 'compress', filter_opts = {'driver': 'compress',
'node-name': 'compress0', 'node-name': 'compress0',
'file': 'hd0'} 'file': 'hd0'}
result = self.vm.qmp('blockdev-add', conv_keys = False, **filter_opts) self.vm.cmd('blockdev-add', conv_keys = False, **filter_opts)
self.assert_qmp(result, 'return', {})
# Unmap the beginning of the image (we cannot write compressed # Unmap the beginning of the image (we cannot write compressed
# data to an allocated cluster) # data to an allocated cluster)
@ -659,12 +635,10 @@ class TestBlockdevReopen(iotests.QMPTestCase):
def test_swap_files(self): def test_swap_files(self):
# Add hd0 and hd2 (none of them with backing files) # Add hd0 and hd2 (none of them with backing files)
opts0 = hd_opts(0) opts0 = hd_opts(0)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts0) self.vm.cmd('blockdev-add', conv_keys = False, **opts0)
self.assert_qmp(result, 'return', {})
opts2 = hd_opts(2) opts2 = hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts2) self.vm.cmd('blockdev-add', conv_keys = False, **opts2)
self.assert_qmp(result, 'return', {})
# Write different data to both block devices # Write different data to both block devices
self.run_qemu_io("hd0", "write -P 0xa0 0 1k") self.run_qemu_io("hd0", "write -P 0xa0 0 1k")
@ -712,15 +686,13 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts = hd_opts(i) opts = hd_opts(i)
# Open all three images without backing file # Open all three images without backing file
opts['backing'] = None opts['backing'] = None
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
opts = {'driver': 'quorum', opts = {'driver': 'quorum',
'node-name': 'quorum0', 'node-name': 'quorum0',
'children': ['hd0', 'hd1', 'hd2'], 'children': ['hd0', 'hd1', 'hd2'],
'vote-threshold': 2} 'vote-threshold': 2}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Quorum doesn't currently allow reopening. TODO: implement this # Quorum doesn't currently allow reopening. TODO: implement this
self.reopen(opts, {}, "Block format 'quorum' used by node 'quorum0'" + self.reopen(opts, {}, "Block format 'quorum' used by node 'quorum0'" +
@ -732,14 +704,12 @@ class TestBlockdevReopen(iotests.QMPTestCase):
"Making 'quorum0' a backing child of 'hd0' would create a cycle") "Making 'quorum0' a backing child of 'hd0' would create a cycle")
# Delete quorum0 # Delete quorum0
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'quorum0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'quorum0')
self.assert_qmp(result, 'return', {})
# Delete hd0, hd1 and hd2 # Delete hd0, hd1 and hd2
for i in range(3): for i in range(3):
result = self.vm.qmp('blockdev-del', conv_keys = True, self.vm.cmd('blockdev-del', conv_keys = True,
node_name = 'hd%d' % i) node_name = 'hd%d' % i)
self.assert_qmp(result, 'return', {})
###################### ######################
###### blkdebug ###### ###### blkdebug ######
@ -748,8 +718,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
'node-name': 'bd', 'node-name': 'bd',
'config': '/dev/null', 'config': '/dev/null',
'image': hd_opts(0)} 'image': hd_opts(0)}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# blkdebug allows reopening if we keep the same options # blkdebug allows reopening if we keep the same options
self.reopen(opts) self.reopen(opts)
@ -762,16 +731,14 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.reopen(opts, {}, "Option 'config' cannot be reset to its default value") self.reopen(opts, {}, "Option 'config' cannot be reset to its default value")
# Delete the blkdebug node # Delete the blkdebug node
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'bd') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'bd')
self.assert_qmp(result, 'return', {})
################## ##################
###### null ###### ###### null ######
################## ##################
opts = {'driver': 'null-co', 'node-name': 'root', 'size': 1024} opts = {'driver': 'null-co', 'node-name': 'root', 'size': 1024}
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# 1 << 30 is the default value, but we cannot change it explicitly # 1 << 30 is the default value, but we cannot change it explicitly
self.reopen(opts, {'size': (1 << 30)}, "Cannot change the option 'size'") self.reopen(opts, {'size': (1 << 30)}, "Cannot change the option 'size'")
@ -780,16 +747,14 @@ class TestBlockdevReopen(iotests.QMPTestCase):
del opts['size'] del opts['size']
self.reopen(opts, {}, "Option 'size' cannot be reset to its default value") self.reopen(opts, {}, "Option 'size' cannot be reset to its default value")
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'root') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'root')
self.assert_qmp(result, 'return', {})
################## ##################
###### file ###### ###### file ######
################## ##################
opts = hd_opts(0) opts = hd_opts(0)
opts['file']['locking'] = 'on' opts['file']['locking'] = 'on'
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# 'locking' cannot be changed # 'locking' cannot be changed
del opts['file']['locking'] del opts['file']['locking']
@ -803,27 +768,23 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.reopen(opts, {'locking': 'off'}, "Cannot change the option 'locking'") self.reopen(opts, {'locking': 'off'}, "Cannot change the option 'locking'")
self.reopen(opts, {}, "Option 'locking' cannot be reset to its default value") self.reopen(opts, {}, "Option 'locking' cannot be reset to its default value")
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
###################### ######################
###### throttle ###### ###### throttle ######
###################### ######################
opts = { 'qom-type': 'throttle-group', 'id': 'group0', opts = { 'qom-type': 'throttle-group', 'id': 'group0',
'limits': { 'iops-total': 1000 } } 'limits': { 'iops-total': 1000 } }
result = self.vm.qmp('object-add', conv_keys = False, **opts) self.vm.cmd('object-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
opts = { 'qom-type': 'throttle-group', 'id': 'group1', opts = { 'qom-type': 'throttle-group', 'id': 'group1',
'limits': { 'iops-total': 2000 } } 'limits': { 'iops-total': 2000 } }
result = self.vm.qmp('object-add', conv_keys = False, **opts) self.vm.cmd('object-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Add a throttle filter with group = group0 # Add a throttle filter with group = group0
opts = { 'driver': 'throttle', 'node-name': 'throttle0', opts = { 'driver': 'throttle', 'node-name': 'throttle0',
'throttle-group': 'group0', 'file': hd_opts(0) } 'throttle-group': 'group0', 'file': hd_opts(0) }
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# We can reopen it if we keep the same options # We can reopen it if we keep the same options
self.reopen(opts) self.reopen(opts)
@ -851,16 +812,13 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.assert_qmp(result, 'error/desc', "object 'group0' is in use, can not be deleted") self.assert_qmp(result, 'error/desc', "object 'group0' is in use, can not be deleted")
# But group1 is free this time, and it can be deleted # But group1 is free this time, and it can be deleted
result = self.vm.qmp('object-del', id = 'group1') self.vm.cmd('object-del', id = 'group1')
self.assert_qmp(result, 'return', {})
# Let's delete the filter node # Let's delete the filter node
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'throttle0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'throttle0')
self.assert_qmp(result, 'return', {})
# And we can finally get rid of group0 # And we can finally get rid of group0
result = self.vm.qmp('object-del', id = 'group0') self.vm.cmd('object-del', id = 'group0')
self.assert_qmp(result, 'return', {})
# If an image has a backing file then the 'backing' option must be # If an image has a backing file then the 'backing' option must be
# passed on reopen. We don't allow leaving the option out in this # passed on reopen. We don't allow leaving the option out in this
@ -868,13 +826,11 @@ class TestBlockdevReopen(iotests.QMPTestCase):
def test_missing_backing_options_1(self): def test_missing_backing_options_1(self):
# hd2 # hd2
opts = hd_opts(2) opts = hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# hd0 # hd0
opts = hd_opts(0) opts = hd_opts(0)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# hd0 has no backing file: we can omit the 'backing' option # hd0 has no backing file: we can omit the 'backing' option
self.reopen(opts) self.reopen(opts)
@ -897,11 +853,9 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.reopen(opts) self.reopen(opts)
# Remove both hd0 and hd2 # Remove both hd0 and hd2
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd2') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd2')
self.assert_qmp(result, 'return', {})
# If an image has default backing file (as part of its metadata) # If an image has default backing file (as part of its metadata)
# then the 'backing' option must be passed on reopen. We don't # then the 'backing' option must be passed on reopen. We don't
@ -911,8 +865,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# hd0 <- hd1 # hd0 <- hd1
# (hd0 is hd1's default backing file) # (hd0 is hd1's default backing file)
opts = hd_opts(1) opts = hd_opts(1)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# hd1 has a backing file: we can't omit the 'backing' option # hd1 has a backing file: we can't omit the 'backing' option
self.reopen(opts, {}, "backing is missing for 'hd1'") self.reopen(opts, {}, "backing is missing for 'hd1'")
@ -923,8 +876,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# No backing file attached to hd1 now, but we still can't omit the 'backing' option # No backing file attached to hd1 now, but we still can't omit the 'backing' option
self.reopen(opts, {}, "backing is missing for 'hd1'") self.reopen(opts, {}, "backing is missing for 'hd1'")
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd1') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd1')
self.assert_qmp(result, 'return', {})
# Test that making 'backing' a reference to an existing child # Test that making 'backing' a reference to an existing child
# keeps its current options # keeps its current options
@ -937,8 +889,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts['detect-zeroes'] = 'on' opts['detect-zeroes'] = 'on'
opts['backing']['detect-zeroes'] = 'on' opts['backing']['detect-zeroes'] = 'on'
opts['backing']['backing']['detect-zeroes'] = 'on' opts['backing']['backing']['detect-zeroes'] = 'on'
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Reopen the chain passing the minimum amount of required options. # Reopen the chain passing the minimum amount of required options.
# By making 'backing' a reference to hd1 (instead of a sub-dict) # By making 'backing' a reference to hd1 (instead of a sub-dict)
@ -961,12 +912,10 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts = hd_opts(0) opts = hd_opts(0)
opts['backing'] = hd_opts(1) opts['backing'] = hd_opts(1)
opts['backing']['backing'] = None opts['backing']['backing'] = None
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Stream hd1 into hd0 and wait until it's done # Stream hd1 into hd0 and wait until it's done
result = self.vm.qmp('block-stream', conv_keys = True, job_id = 'stream0', device = 'hd0') self.vm.cmd('block-stream', conv_keys = True, job_id = 'stream0', device = 'hd0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive = 'stream0') self.wait_until_completed(drive = 'stream0')
# Now we have only hd0 # Now we have only hd0
@ -982,8 +931,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# We can also reopen hd0 if we set 'backing' to null # We can also reopen hd0 if we set 'backing' to null
self.reopen(opts, {'backing': None}) self.reopen(opts, {'backing': None})
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
# Another block_stream test # Another block_stream test
def test_block_stream_2(self): def test_block_stream_2(self):
@ -991,13 +939,11 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts = hd_opts(0) opts = hd_opts(0)
opts['backing'] = hd_opts(1) opts['backing'] = hd_opts(1)
opts['backing']['backing'] = hd_opts(2) opts['backing']['backing'] = hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Stream hd1 into hd0 and wait until it's done # Stream hd1 into hd0 and wait until it's done
result = self.vm.qmp('block-stream', conv_keys = True, job_id = 'stream0', self.vm.cmd('block-stream', conv_keys = True, job_id = 'stream0',
device = 'hd0', base_node = 'hd2') device = 'hd0', base_node = 'hd2')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive = 'stream0') self.wait_until_completed(drive = 'stream0')
# The chain is hd2 <- hd0 now. hd1 is missing # The chain is hd2 <- hd0 now. hd1 is missing
@ -1019,8 +965,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.reopen(opts, {}, "backing is missing for 'hd0'") self.reopen(opts, {}, "backing is missing for 'hd0'")
# Now we can delete hd0 (and hd2) # Now we can delete hd0 (and hd2)
result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd0') self.vm.cmd('blockdev-del', conv_keys = True, node_name = 'hd0')
self.assert_qmp(result, 'return', {})
self.assertEqual(self.get_node('hd2'), None) self.assertEqual(self.get_node('hd2'), None)
# Reopen the chain during a block-stream job (from hd1 to hd0) # Reopen the chain during a block-stream job (from hd1 to hd0)
@ -1029,14 +974,12 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts = hd_opts(0) opts = hd_opts(0)
opts['backing'] = hd_opts(1) opts['backing'] = hd_opts(1)
opts['backing']['backing'] = hd_opts(2) opts['backing']['backing'] = hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# hd2 <- hd0 # hd2 <- hd0
result = self.vm.qmp('block-stream', conv_keys = True, job_id = 'stream0', self.vm.cmd('block-stream', conv_keys = True, job_id = 'stream0',
device = 'hd0', base_node = 'hd2', device = 'hd0', base_node = 'hd2',
auto_finalize = False) auto_finalize = False)
self.assert_qmp(result, 'return', {})
# We can remove hd2 while the stream job is ongoing # We can remove hd2 while the stream job is ongoing
opts['backing']['backing'] = None opts['backing']['backing'] = None
@ -1054,14 +997,12 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts = hd_opts(0) opts = hd_opts(0)
opts['backing'] = hd_opts(1) opts['backing'] = hd_opts(1)
opts['backing']['backing'] = hd_opts(2) opts['backing']['backing'] = hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# hd1 <- hd0 # hd1 <- hd0
result = self.vm.qmp('block-stream', conv_keys = True, job_id = 'stream0', self.vm.cmd('block-stream', conv_keys = True, job_id = 'stream0',
device = 'hd1', filter_node_name='cor', device = 'hd1', filter_node_name='cor',
auto_finalize = False) auto_finalize = False)
self.assert_qmp(result, 'return', {})
# We can't reopen with the original options because there is a filter # We can't reopen with the original options because there is a filter
# inserted by stream job above hd1. # inserted by stream job above hd1.
@ -1090,12 +1031,10 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts = hd_opts(0) opts = hd_opts(0)
opts['backing'] = hd_opts(1) opts['backing'] = hd_opts(1)
opts['backing']['backing'] = hd_opts(2) opts['backing']['backing'] = hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-commit', conv_keys = True, job_id = 'commit0', self.vm.cmd('block-commit', conv_keys = True, job_id = 'commit0',
device = 'hd0') device = 'hd0')
self.assert_qmp(result, 'return', {})
# We can't remove hd2 while the commit job is ongoing # We can't remove hd2 while the commit job is ongoing
opts['backing']['backing'] = None opts['backing']['backing'] = None
@ -1110,8 +1049,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.assert_qmp(event, 'data/type', 'commit') self.assert_qmp(event, 'data/type', 'commit')
self.assert_qmp_absent(event, 'data/error') self.assert_qmp_absent(event, 'data/error')
result = self.vm.qmp('block-job-complete', device='commit0') self.vm.cmd('block-job-complete', device='commit0')
self.assert_qmp(result, 'return', {})
self.wait_until_completed(drive = 'commit0') self.wait_until_completed(drive = 'commit0')
@ -1121,13 +1059,11 @@ class TestBlockdevReopen(iotests.QMPTestCase):
opts = hd_opts(0) opts = hd_opts(0)
opts['backing'] = hd_opts(1) opts['backing'] = hd_opts(1)
opts['backing']['backing'] = hd_opts(2) opts['backing']['backing'] = hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-commit', conv_keys = True, job_id = 'commit0', self.vm.cmd('block-commit', conv_keys = True, job_id = 'commit0',
device = 'hd0', top_node = 'hd1', device = 'hd0', top_node = 'hd1',
auto_finalize = False) auto_finalize = False)
self.assert_qmp(result, 'return', {})
# We can't remove hd2 while the commit job is ongoing # We can't remove hd2 while the commit job is ongoing
opts['backing']['backing'] = None opts['backing']['backing'] = None
@ -1147,36 +1083,28 @@ class TestBlockdevReopen(iotests.QMPTestCase):
def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None, def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None,
opts_a = None, opts_b = None): opts_a = None, opts_b = None):
opts = opts_a or hd_opts(0) opts = opts_a or hd_opts(0)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) self.vm.cmd('blockdev-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
opts2 = opts_b or hd_opts(2) opts2 = opts_b or hd_opts(2)
result = self.vm.qmp('blockdev-add', conv_keys = False, **opts2) self.vm.cmd('blockdev-add', conv_keys = False, **opts2)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('object-add', qom_type='iothread', id='iothread0') self.vm.cmd('object-add', qom_type='iothread', id='iothread0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('object-add', qom_type='iothread', id='iothread1') self.vm.cmd('object-add', qom_type='iothread', id='iothread1')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi0', self.vm.cmd('device_add', driver='virtio-scsi', id='scsi0',
iothread=iothread_a) iothread=iothread_a)
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('device_add', driver='virtio-scsi', id='scsi1', self.vm.cmd('device_add', driver='virtio-scsi', id='scsi1',
iothread=iothread_b) iothread=iothread_b)
self.assert_qmp(result, 'return', {})
if iothread_a: if iothread_a:
result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd0', self.vm.cmd('device_add', driver='scsi-hd', drive='hd0',
share_rw=True, bus="scsi0.0") share_rw=True, bus="scsi0.0")
self.assert_qmp(result, 'return', {})
if iothread_b: if iothread_b:
result = self.vm.qmp('device_add', driver='scsi-hd', drive='hd2', self.vm.cmd('device_add', driver='scsi-hd', drive='hd2',
share_rw=True, bus="scsi1.0") share_rw=True, bus="scsi1.0")
self.assert_qmp(result, 'return', {})
# Attaching the backing file may or may not work # Attaching the backing file may or may not work
self.reopen(opts, {'backing': 'hd2'}, errmsg) self.reopen(opts, {'backing': 'hd2'}, errmsg)
@ -1205,8 +1133,7 @@ class TestBlockdevReopen(iotests.QMPTestCase):
# Create a throttle-group object # Create a throttle-group object
opts = { 'qom-type': 'throttle-group', 'id': 'group0', opts = { 'qom-type': 'throttle-group', 'id': 'group0',
'limits': { 'iops-total': 1000 } } 'limits': { 'iops-total': 1000 } }
result = self.vm.qmp('object-add', conv_keys = False, **opts) self.vm.cmd('object-add', conv_keys = False, **opts)
self.assert_qmp(result, 'return', {})
# Options with a throttle filter between format and protocol # Options with a throttle filter between format and protocol
opts = [ opts = [

View File

@ -40,25 +40,25 @@ with iotests.FilePath('img0') as img0_path, \
def create_target(filepath, name, size): def create_target(filepath, name, size):
basename = os.path.basename(filepath) basename = os.path.basename(filepath)
nodename = "file_{}".format(basename) nodename = "file_{}".format(basename)
log(vm.command('blockdev-create', job_id='job1', log(vm.cmd('blockdev-create', job_id='job1',
options={ options={
'driver': 'file', 'driver': 'file',
'filename': filepath, 'filename': filepath,
'size': 0, 'size': 0,
})) }))
vm.run_job('job1') vm.run_job('job1')
log(vm.command('blockdev-add', driver='file', log(vm.cmd('blockdev-add', driver='file',
node_name=nodename, filename=filepath)) node_name=nodename, filename=filepath))
log(vm.command('blockdev-create', job_id='job2', log(vm.cmd('blockdev-create', job_id='job2',
options={ options={
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': nodename, 'file': nodename,
'size': size, 'size': size,
})) }))
vm.run_job('job2') vm.run_job('job2')
log(vm.command('blockdev-add', driver=iotests.imgfmt, log(vm.cmd('blockdev-add', driver=iotests.imgfmt,
node_name=name, node_name=name,
file=nodename)) file=nodename))
log('--- Preparing images & VM ---\n') log('--- Preparing images & VM ---\n')
vm.add_object('iothread,id=iothread0') vm.add_object('iothread,id=iothread0')

View File

@ -160,26 +160,26 @@ class Drive:
file_node_name = "file_{}".format(basename) file_node_name = "file_{}".format(basename)
vm = self.vm vm = self.vm
log(vm.command('blockdev-create', job_id='bdc-file-job', log(vm.cmd('blockdev-create', job_id='bdc-file-job',
options={ options={
'driver': 'file', 'driver': 'file',
'filename': self.path, 'filename': self.path,
'size': 0, 'size': 0,
})) }))
vm.run_job('bdc-file-job') vm.run_job('bdc-file-job')
log(vm.command('blockdev-add', driver='file', log(vm.cmd('blockdev-add', driver='file',
node_name=file_node_name, filename=self.path)) node_name=file_node_name, filename=self.path))
log(vm.command('blockdev-create', job_id='bdc-fmt-job', log(vm.cmd('blockdev-create', job_id='bdc-fmt-job',
options={ options={
'driver': fmt, 'driver': fmt,
'file': file_node_name, 'file': file_node_name,
'size': size, 'size': size,
})) }))
vm.run_job('bdc-fmt-job') vm.run_job('bdc-fmt-job')
log(vm.command('blockdev-add', driver=fmt, log(vm.cmd('blockdev-add', driver=fmt,
node_name=name, node_name=name,
file=file_node_name)) file=file_node_name))
self.fmt = fmt self.fmt = fmt
self.size = size self.size = size
self.node = name self.node = name

View File

@ -48,18 +48,16 @@ class TestNbdReconnect(iotests.QMPTestCase):
"""Stat job with nbd target and kill the server""" """Stat job with nbd target and kill the server"""
assert job in ('blockdev-backup', 'blockdev-mirror') assert job in ('blockdev-backup', 'blockdev-mirror')
with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b): with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b):
result = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
**{'node_name': 'backup0', {'node-name': 'backup0',
'driver': 'raw', 'driver': 'raw',
'file': {'driver': 'nbd', 'file': {'driver': 'nbd',
'server': {'type': 'unix', 'server': {'type': 'unix',
'path': nbd_sock}, 'path': nbd_sock},
'reconnect-delay': 10}}) 'reconnect-delay': 10}})
self.assert_qmp(result, 'return', {}) self.vm.cmd(job, device='drive0',
result = self.vm.qmp(job, device='drive0', sync='full', target='backup0',
sync='full', target='backup0', speed=(1 * 1024 * 1024))
speed=(1 * 1024 * 1024))
self.assert_qmp(result, 'return', {})
# Wait for some progress # Wait for some progress
t = 0.0 t = 0.0
@ -77,8 +75,7 @@ class TestNbdReconnect(iotests.QMPTestCase):
self.assertTrue(jobs) self.assertTrue(jobs)
self.assertTrue(jobs[0]['offset'] < jobs[0]['len']) self.assertTrue(jobs[0]['offset'] < jobs[0]['len'])
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) self.vm.cmd('block-job-set-speed', device='drive0', speed=0)
self.assert_qmp(result, 'return', {})
# Emulate server down time for 1 second # Emulate server down time for 1 second
time.sleep(1) time.sleep(1)
@ -91,12 +88,10 @@ class TestNbdReconnect(iotests.QMPTestCase):
with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b): with qemu_nbd_popen('-k', nbd_sock, '-f', iotests.imgfmt, disk_b):
e = self.vm.event_wait('BLOCK_JOB_COMPLETED') e = self.vm.event_wait('BLOCK_JOB_COMPLETED')
self.assertEqual(e['data']['offset'], size) self.assertEqual(e['data']['offset'], size)
result = self.vm.qmp('blockdev-del', node_name='backup0') self.vm.cmd('blockdev-del', node_name='backup0')
self.assert_qmp(result, 'return', {})
def cancel_job(self): def cancel_job(self):
result = self.vm.qmp('block-job-cancel', device='drive0', force=True) self.vm.cmd('block-job-cancel', device='drive0', force=True)
self.assert_qmp(result, 'return', {})
start_t = time.time() start_t = time.time()
self.vm.event_wait('BLOCK_JOB_CANCELLED') self.vm.event_wait('BLOCK_JOB_CANCELLED')

View File

@ -56,15 +56,13 @@ class TestDirtyBitmapIOThread(iotests.QMPTestCase):
os.remove(self.images[name]) os.remove(self.images[name])
def test_add_dirty_bitmap(self): def test_add_dirty_bitmap(self):
result = self.vm.qmp( self.vm.cmd(
'block-dirty-bitmap-add', 'block-dirty-bitmap-add',
node='drive0', node='drive0',
name='bitmap1', name='bitmap1',
persistent=True, persistent=True,
) )
self.assert_qmp(result, 'return', {})
# Test for RHBZ#1746217 & RHBZ#1773517 # Test for RHBZ#1746217 & RHBZ#1773517
class TestNBDMirrorIOThread(iotests.QMPTestCase): class TestNBDMirrorIOThread(iotests.QMPTestCase):
@ -105,23 +103,21 @@ class TestNBDMirrorIOThread(iotests.QMPTestCase):
os.remove(self.images[name]) os.remove(self.images[name])
def test_nbd_mirror(self): def test_nbd_mirror(self):
result = self.vm_tgt.qmp( self.vm_tgt.cmd(
'nbd-server-start', 'nbd-server-start',
addr={ addr={
'type': 'unix', 'type': 'unix',
'data': { 'path': self.nbd_sock } 'data': { 'path': self.nbd_sock }
} }
) )
self.assert_qmp(result, 'return', {})
result = self.vm_tgt.qmp( self.vm_tgt.cmd(
'nbd-server-add', 'nbd-server-add',
device='drive0', device='drive0',
writable=True writable=True
) )
self.assert_qmp(result, 'return', {})
result = self.vm_src.qmp( self.vm_src.cmd(
'drive-mirror', 'drive-mirror',
device='drive0', device='drive0',
target='nbd+unix:///drive0?socket=' + self.nbd_sock, target='nbd+unix:///drive0?socket=' + self.nbd_sock,
@ -130,7 +126,6 @@ class TestNBDMirrorIOThread(iotests.QMPTestCase):
speed=64*1024*1024, speed=64*1024*1024,
job_id='j1' job_id='j1'
) )
self.assert_qmp(result, 'return', {})
self.vm_src.event_wait(name="BLOCK_JOB_READY") self.vm_src.event_wait(name="BLOCK_JOB_READY")
@ -290,8 +285,7 @@ class TestYieldingAndTimers(iotests.QMPTestCase):
# they will remain active, fire later, and then access freed data. # they will remain active, fire later, and then access freed data.
# (Or, with "block/nbd: Assert there are no timers when closed" # (Or, with "block/nbd: Assert there are no timers when closed"
# applied, the assertions added in that patch will fail.) # applied, the assertions added in that patch will fail.)
result = self.vm.qmp('blockdev-del', node_name='nbd') self.vm.cmd('blockdev-del', node_name='nbd')
self.assert_qmp(result, 'return', {})
# Give the timers some time to fire (both have a timeout of 1 s). # Give the timers some time to fire (both have a timeout of 1 s).
# (Sleeping in an iotest may ring some alarm bells, but note that if # (Sleeping in an iotest may ring some alarm bells, but note that if
@ -303,9 +297,8 @@ class TestYieldingAndTimers(iotests.QMPTestCase):
def test_yield_in_iothread(self): def test_yield_in_iothread(self):
# Move the NBD node to the I/O thread; the NBD block driver should # Move the NBD node to the I/O thread; the NBD block driver should
# attach the connection's QIOChannel to that thread's AioContext, too # attach the connection's QIOChannel to that thread's AioContext, too
result = self.vm.qmp('x-blockdev-set-iothread', self.vm.cmd('x-blockdev-set-iothread',
node_name='nbd', iothread='iothr') node_name='nbd', iothread='iothr')
self.assert_qmp(result, 'return', {})
# Do some I/O that will be throttled by the QSD, so that the network # Do some I/O that will be throttled by the QSD, so that the network
# connection hopefully will yield here. When it is resumed, it must # connection hopefully will yield here. When it is resumed, it must

View File

@ -57,8 +57,7 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
# create the secrets and load 'em into the VM # create the secrets and load 'em into the VM
self.secrets = [ Secret(i) for i in range(0, 6) ] self.secrets = [ Secret(i) for i in range(0, 6) ]
for secret in self.secrets: for secret in self.secrets:
result = self.vm.qmp("object-add", **secret.to_qmp_object()) self.vm.cmd("object-add", **secret.to_qmp_object())
self.assert_qmp(result, 'return', {})
if iotests.imgfmt == "qcow2": if iotests.imgfmt == "qcow2":
self.pfx = "encrypt." self.pfx = "encrypt."
@ -102,8 +101,7 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
} }
} }
result = self.vm.qmp('blockdev-add', ** self.vm.cmd('blockdev-add', {
{
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'node-name': id, 'node-name': id,
'read-only': read_only, 'read-only': read_only,
@ -116,12 +114,10 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
} }
} }
) )
self.assert_qmp(result, 'return', {})
# close the encrypted block device # close the encrypted block device
def closeImageQmp(self, id): def closeImageQmp(self, id):
result = self.vm.qmp('blockdev-del', **{ 'node-name': id }) self.vm.cmd('blockdev-del', {'node-name': id})
self.assert_qmp(result, 'return', {})
########################################################################### ###########################################################################
# add a key to an encrypted block device # add a key to an encrypted block device
@ -160,8 +156,7 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
args['force'] = True args['force'] = True
#TODO: check what jobs return #TODO: check what jobs return
result = self.vm.qmp('x-blockdev-amend', **args) self.vm.cmd('x-blockdev-amend', **args)
assert result['return'] == {}
self.vm.run_job('job_add_key') self.vm.run_job('job_add_key')
# erase a key from an encrypted block device # erase a key from an encrypted block device
@ -194,8 +189,7 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
if force == True: if force == True:
args['force'] = True args['force'] = True
result = self.vm.qmp('x-blockdev-amend', **args) self.vm.cmd('x-blockdev-amend', **args)
assert result['return'] == {}
self.vm.run_job('job_erase_key') self.vm.run_job('job_erase_key')
########################################################################### ###########################################################################

View File

@ -42,7 +42,7 @@ class Secret:
return [ "secret,id=" + self._id + ",data=" + self._secret] return [ "secret,id=" + self._id + ",data=" + self._secret]
def to_qmp_object(self): def to_qmp_object(self):
return { "qom_type" : "secret", "id": self.id(), return { "qom-type" : "secret", "id": self.id(),
"data": self.secret() } "data": self.secret() }
################################################################################ ################################################################################
@ -61,10 +61,8 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
# create the secrets and load 'em into the VMs # create the secrets and load 'em into the VMs
self.secrets = [ Secret(i) for i in range(0, 4) ] self.secrets = [ Secret(i) for i in range(0, 4) ]
for secret in self.secrets: for secret in self.secrets:
result = self.vm1.qmp("object-add", **secret.to_qmp_object()) self.vm1.cmd("object-add", secret.to_qmp_object())
self.assert_qmp(result, 'return', {}) self.vm2.cmd("object-add", secret.to_qmp_object())
result = self.vm2.qmp("object-add", **secret.to_qmp_object())
self.assert_qmp(result, 'return', {})
# test case shutdown # test case shutdown
def tearDown(self): def tearDown(self):
@ -132,17 +130,15 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
} }
if reOpen: if reOpen:
result = vm.qmp(command, options=[opts]) vm.cmd(command, options=[opts])
else: else:
result = vm.qmp(command, **opts) vm.cmd(command, opts)
self.assert_qmp(result, 'return', {})
########################################################################### ###########################################################################
# add virtio-blk consumer for a block device # add virtio-blk consumer for a block device
def addImageUser(self, vm, id, disk_id, share_rw=False): def addImageUser(self, vm, id, disk_id, share_rw=False):
result = vm.qmp('device_add', ** result = vm.qmp('device_add', {
{
'driver': 'virtio-blk', 'driver': 'virtio-blk',
'id': id, 'id': id,
'drive': disk_id, 'drive': disk_id,
@ -154,8 +150,7 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
# close the encrypted block device # close the encrypted block device
def closeImageQmp(self, vm, id): def closeImageQmp(self, vm, id):
result = vm.qmp('blockdev-del', **{ 'node-name': id }) vm.cmd('blockdev-del', {'node-name': id})
self.assert_qmp(result, 'return', {})
########################################################################### ###########################################################################
@ -173,7 +168,7 @@ class EncryptionSetupTestCase(iotests.QMPTestCase):
}, },
} }
result = vm.qmp('x-blockdev-amend', **args) result = vm.qmp('x-blockdev-amend', args)
iotests.log(result) iotests.log(result)
# Run the job only if it was created # Run the job only if it was created
event = ('JOB_STATUS_CHANGE', event = ('JOB_STATUS_CHANGE',

View File

@ -80,25 +80,23 @@ class TestPreallocateFilter(TestPreallocateBase):
def test_external_snapshot(self): def test_external_snapshot(self):
self.test_prealloc() self.test_prealloc()
result = self.vm.qmp('blockdev-snapshot-sync', node_name='disk', self.vm.cmd('blockdev-snapshot-sync', node_name='disk',
snapshot_file=overlay, snapshot_file=overlay,
snapshot_node_name='overlay') snapshot_node_name='overlay')
self.assert_qmp(result, 'return', {})
# on reopen to r-o base preallocation should be dropped # on reopen to r-o base preallocation should be dropped
self.check_small() self.check_small()
self.vm.hmp_qemu_io('drive0', 'write 1M 1M') self.vm.hmp_qemu_io('drive0', 'write 1M 1M')
result = self.vm.qmp('block-commit', device='overlay') self.vm.cmd('block-commit', device='overlay')
self.assert_qmp(result, 'return', {})
self.complete_and_wait() self.complete_and_wait()
# commit of new megabyte should trigger preallocation # commit of new megabyte should trigger preallocation
self.check_big() self.check_big()
def test_reopen_opts(self): def test_reopen_opts(self):
result = self.vm.qmp('blockdev-reopen', options=[{ self.vm.cmd('blockdev-reopen', options=[{
'node-name': 'disk', 'node-name': 'disk',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
@ -113,7 +111,6 @@ class TestPreallocateFilter(TestPreallocateBase):
} }
} }
}]) }])
self.assert_qmp(result, 'return', {})
self.vm.hmp_qemu_io('drive0', 'write 0 1M') self.vm.hmp_qemu_io('drive0', 'write 0 1M')
self.assertTrue(os.path.getsize(disk) == 25 * MiB) self.assertTrue(os.path.getsize(disk) == 25 * MiB)

View File

@ -50,10 +50,9 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
self.vm_b.add_incoming(f'unix:{mig_sock}') self.vm_b.add_incoming(f'unix:{mig_sock}')
self.vm_b.launch() self.vm_b.launch()
result = self.vm_a.qmp('block-dirty-bitmap-add', self.vm_a.cmd('block-dirty-bitmap-add',
node=self.src_node_name, node=self.src_node_name,
name=self.src_bmap_name) name=self.src_bmap_name)
self.assert_qmp(result, 'return', {})
# Dirty some random megabytes # Dirty some random megabytes
for _ in range(9): for _ in range(9):
@ -69,8 +68,7 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
for name in ('dirty-bitmaps', 'events')] for name in ('dirty-bitmaps', 'events')]
for vm in (self.vm_a, self.vm_b): for vm in (self.vm_a, self.vm_b):
result = vm.qmp('migrate-set-capabilities', capabilities=caps) vm.cmd('migrate-set-capabilities', capabilities=caps)
self.assert_qmp(result, 'return', {})
def tearDown(self) -> None: def tearDown(self) -> None:
self.vm_a.shutdown() self.vm_a.shutdown()
@ -93,8 +91,7 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
def migrate(self, bitmap_name_valid: bool = True, def migrate(self, bitmap_name_valid: bool = True,
migration_success: bool = True) -> None: migration_success: bool = True) -> None:
result = self.vm_a.qmp('migrate', uri=f'unix:{mig_sock}') self.vm_a.cmd('migrate', uri=f'unix:{mig_sock}')
self.assert_qmp(result, 'return', {})
with iotests.Timeout(5, 'Timeout waiting for migration to complete'): with iotests.Timeout(5, 'Timeout waiting for migration to complete'):
self.assertEqual(self.vm_a.wait_migration('postmigrate'), self.assertEqual(self.vm_a.wait_migration('postmigrate'),
@ -442,10 +439,9 @@ class TestBlockBitmapMappingErrors(TestDirtyBitmapMigration):
def test_bitmap_name_too_long(self) -> None: def test_bitmap_name_too_long(self) -> None:
name = 'a' * 256 name = 'a' * 256
result = self.vm_a.qmp('block-dirty-bitmap-add', self.vm_a.cmd('block-dirty-bitmap-add',
node=self.src_node_name, node=self.src_node_name,
name=name) name=name)
self.assert_qmp(result, 'return', {})
self.migrate(False, False) self.migrate(False, False)
@ -517,22 +513,19 @@ class TestCrossAliasMigration(TestDirtyBitmapMigration):
TestDirtyBitmapMigration.setUp(self) TestDirtyBitmapMigration.setUp(self)
# Now create another block device and let both have two bitmaps each # Now create another block device and let both have two bitmaps each
result = self.vm_a.qmp('blockdev-add', self.vm_a.cmd('blockdev-add',
node_name='node-b', driver='null-co') node_name='node-b', driver='null-co')
self.assert_qmp(result, 'return', {})
result = self.vm_b.qmp('blockdev-add', self.vm_b.cmd('blockdev-add',
node_name='node-a', driver='null-co') node_name='node-a', driver='null-co')
self.assert_qmp(result, 'return', {})
bmaps_to_add = (('node-a', 'bmap-b'), bmaps_to_add = (('node-a', 'bmap-b'),
('node-b', 'bmap-a'), ('node-b', 'bmap-a'),
('node-b', 'bmap-b')) ('node-b', 'bmap-b'))
for (node, bmap) in bmaps_to_add: for (node, bmap) in bmaps_to_add:
result = self.vm_a.qmp('block-dirty-bitmap-add', self.vm_a.cmd('block-dirty-bitmap-add',
node=node, name=bmap) node=node, name=bmap)
self.assert_qmp(result, 'return', {})
@staticmethod @staticmethod
def cross_mapping() -> BlockBitmapMapping: def cross_mapping() -> BlockBitmapMapping:
@ -611,24 +604,21 @@ class TestAliasTransformMigration(TestDirtyBitmapMigration):
TestDirtyBitmapMigration.setUp(self) TestDirtyBitmapMigration.setUp(self)
# Now create another block device and let both have two bitmaps each # Now create another block device and let both have two bitmaps each
result = self.vm_a.qmp('blockdev-add', self.vm_a.cmd('blockdev-add',
node_name='node-b', driver='null-co', node_name='node-b', driver='null-co',
read_zeroes=False) read_zeroes=False)
self.assert_qmp(result, 'return', {})
result = self.vm_b.qmp('blockdev-add', self.vm_b.cmd('blockdev-add',
node_name='node-a', driver='null-co', node_name='node-a', driver='null-co',
read_zeroes=False) read_zeroes=False)
self.assert_qmp(result, 'return', {})
bmaps_to_add = (('node-a', 'bmap-b'), bmaps_to_add = (('node-a', 'bmap-b'),
('node-b', 'bmap-a'), ('node-b', 'bmap-a'),
('node-b', 'bmap-b')) ('node-b', 'bmap-b'))
for (node, bmap) in bmaps_to_add: for (node, bmap) in bmaps_to_add:
result = self.vm_a.qmp('block-dirty-bitmap-add', self.vm_a.cmd('block-dirty-bitmap-add',
node=node, name=bmap) node=node, name=bmap)
self.assert_qmp(result, 'return', {})
@staticmethod @staticmethod
def transform_mapping() -> BlockBitmapMapping: def transform_mapping() -> BlockBitmapMapping:

View File

@ -38,7 +38,7 @@ import unittest
from contextlib import contextmanager from contextlib import contextmanager
from qemu.machine import qtest from qemu.machine import qtest
from qemu.qmp.legacy import QMPMessage, QEMUMonitorProtocol from qemu.qmp.legacy import QMPMessage, QMPReturnValue, QEMUMonitorProtocol
from qemu.utils import VerboseProcessError from qemu.utils import VerboseProcessError
# Use this logger for logging messages directly from the iotests module # Use this logger for logging messages directly from the iotests module
@ -460,12 +460,17 @@ class QemuStorageDaemon:
def qmp(self, cmd: str, args: Optional[Dict[str, object]] = None) \ def qmp(self, cmd: str, args: Optional[Dict[str, object]] = None) \
-> QMPMessage: -> QMPMessage:
assert self._qmp is not None assert self._qmp is not None
return self._qmp.cmd(cmd, args) return self._qmp.cmd_raw(cmd, args)
def get_qmp(self) -> QEMUMonitorProtocol: def get_qmp(self) -> QEMUMonitorProtocol:
assert self._qmp is not None assert self._qmp is not None
return self._qmp return self._qmp
def cmd(self, cmd: str, args: Optional[Dict[str, object]] = None) \
-> QMPReturnValue:
assert self._qmp is not None
return self._qmp.cmd(cmd, **(args or {}))
def stop(self, kill_signal=15): def stop(self, kill_signal=15):
self._p.send_signal(kill_signal) self._p.send_signal(kill_signal)
self._p.wait() self._p.wait()
@ -823,7 +828,7 @@ class VM(qtest.QEMUQtestMachine):
super().__init__(qemu_prog, qemu_opts, wrapper=wrapper, super().__init__(qemu_prog, qemu_opts, wrapper=wrapper,
name=name, name=name,
base_temp_dir=test_dir, base_temp_dir=test_dir,
sock_dir=sock_dir, qmp_timer=timer) qmp_timer=timer)
self._num_drives = 0 self._num_drives = 0
def _post_shutdown(self) -> None: def _post_shutdown(self) -> None:
@ -1247,8 +1252,7 @@ class QMPTestCase(unittest.TestCase):
def cancel_and_wait(self, drive='drive0', force=False, def cancel_and_wait(self, drive='drive0', force=False,
resume=False, wait=60.0): resume=False, wait=60.0):
'''Cancel a block job and wait for it to finish, returning the event''' '''Cancel a block job and wait for it to finish, returning the event'''
result = self.vm.qmp('block-job-cancel', device=drive, force=force) self.vm.cmd('block-job-cancel', device=drive, force=force)
self.assert_qmp(result, 'return', {})
if resume: if resume:
self.vm.resume_drive(drive) self.vm.resume_drive(drive)
@ -1310,8 +1314,7 @@ class QMPTestCase(unittest.TestCase):
if wait_ready: if wait_ready:
self.wait_ready(drive=drive) self.wait_ready(drive=drive)
result = self.vm.qmp('block-job-complete', device=drive) self.vm.cmd('block-job-complete', device=drive)
self.assert_qmp(result, 'return', {})
event = self.wait_until_completed(drive=drive, error=completion_error) event = self.wait_until_completed(drive=drive, error=completion_error)
self.assertTrue(event['data']['type'] in ['mirror', 'commit']) self.assertTrue(event['data']['type'] in ['mirror', 'commit'])
@ -1330,11 +1333,9 @@ class QMPTestCase(unittest.TestCase):
assert found assert found
def pause_job(self, job_id='job0', wait=True): def pause_job(self, job_id='job0', wait=True):
result = self.vm.qmp('block-job-pause', device=job_id) self.vm.cmd('block-job-pause', device=job_id)
self.assert_qmp(result, 'return', {})
if wait: if wait:
return self.pause_wait(job_id) self.pause_wait(job_id)
return result
def case_skip(self, reason): def case_skip(self, reason):
'''Skip this test case''' '''Skip this test case'''

View File

@ -129,12 +129,11 @@ class TestPostMigrateFilename(iotests.QMPTestCase):
# For good measure, try creating an overlay and check its backing # For good measure, try creating an overlay and check its backing
# chain below. This is how the issue was originally found. # chain below. This is how the issue was originally found.
result = self.vm_d.qmp('blockdev-snapshot-sync', self.vm_d.cmd('blockdev-snapshot-sync',
format=iotests.imgfmt, format=iotests.imgfmt,
snapshot_file=imgs[3], snapshot_file=imgs[3],
node_name='node0', node_name='node0',
snapshot_node_name='node0-overlay') snapshot_node_name='node0-overlay')
self.assert_qmp(result, 'return', {})
self.vm_d.shutdown() self.vm_d.shutdown()
self.vm_d = None self.vm_d = None

View File

@ -44,12 +44,11 @@ class TestCbwError(iotests.QMPTestCase):
opts = ['-nodefaults', '-display', 'none', '-machine', 'none'] opts = ['-nodefaults', '-display', 'none', '-machine', 'none']
self.vm = QEMUMachine(iotests.qemu_prog, opts, self.vm = QEMUMachine(iotests.qemu_prog, opts,
base_temp_dir=iotests.test_dir, base_temp_dir=iotests.test_dir)
sock_dir=iotests.sock_dir)
self.vm.launch() self.vm.launch()
def do_cbw_error(self, on_cbw_error): def do_cbw_error(self, on_cbw_error):
result = self.vm.qmp('blockdev-add', { self.vm.cmd('blockdev-add', {
'node-name': 'cbw', 'node-name': 'cbw',
'driver': 'copy-before-write', 'driver': 'copy-before-write',
'on-cbw-error': on_cbw_error, 'on-cbw-error': on_cbw_error,
@ -79,14 +78,12 @@ class TestCbwError(iotests.QMPTestCase):
} }
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', { self.vm.cmd('blockdev-add', {
'node-name': 'access', 'node-name': 'access',
'driver': 'snapshot-access', 'driver': 'snapshot-access',
'file': 'cbw' 'file': 'cbw'
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('human-monitor-command', result = self.vm.qmp('human-monitor-command',
command_line='qemu-io cbw "write 0 1M"') command_line='qemu-io cbw "write 0 1M"')
@ -130,14 +127,13 @@ read 1048576/1048576 bytes at offset 0
""") """)
def do_cbw_timeout(self, on_cbw_error): def do_cbw_timeout(self, on_cbw_error):
result = self.vm.qmp('object-add', { self.vm.cmd('object-add', {
'qom-type': 'throttle-group', 'qom-type': 'throttle-group',
'id': 'group0', 'id': 'group0',
'limits': {'bps-write': 300 * 1024} 'limits': {'bps-write': 300 * 1024}
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', { self.vm.cmd('blockdev-add', {
'node-name': 'cbw', 'node-name': 'cbw',
'driver': 'copy-before-write', 'driver': 'copy-before-write',
'on-cbw-error': on_cbw_error, 'on-cbw-error': on_cbw_error,
@ -161,14 +157,12 @@ read 1048576/1048576 bytes at offset 0
} }
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('blockdev-add', { self.vm.cmd('blockdev-add', {
'node-name': 'access', 'node-name': 'access',
'driver': 'snapshot-access', 'driver': 'snapshot-access',
'file': 'cbw' 'file': 'cbw'
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('human-monitor-command', result = self.vm.qmp('human-monitor-command',
command_line='qemu-io cbw "write 0 512K"') command_line='qemu-io cbw "write 0 512K"')

View File

@ -55,7 +55,7 @@ class TestExportIncomingIothread(iotests.QMPTestCase):
os.remove(test_img) os.remove(test_img)
def test_export_add(self): def test_export_add(self):
result = self.vm.qmp('nbd-server-start', { self.vm.cmd('nbd-server-start', {
'addr': { 'addr': {
'type': 'unix', 'type': 'unix',
'data': { 'data': {
@ -63,16 +63,14 @@ class TestExportIncomingIothread(iotests.QMPTestCase):
} }
} }
}) })
self.assert_qmp(result, 'return', {})
# Regression test for issue 945: This should not fail an assertion # Regression test for issue 945: This should not fail an assertion
result = self.vm.qmp('block-export-add', { self.vm.cmd('block-export-add', {
'type': 'nbd', 'type': 'nbd',
'id': 'exp0', 'id': 'exp0',
'node-name': node_name, 'node-name': node_name,
'iothread': iothread_id 'iothread': iothread_id
}) })
self.assert_qmp(result, 'return', {})
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -66,7 +66,7 @@ class TestGraphChangesWhileIO(QMPTestCase):
# While qemu-img bench is running, repeatedly add and remove an # While qemu-img bench is running, repeatedly add and remove an
# overlay to/from node0 # overlay to/from node0
while bench_thr.is_alive(): while bench_thr.is_alive():
result = self.qsd.qmp('blockdev-add', { self.qsd.cmd('blockdev-add', {
'driver': imgfmt, 'driver': imgfmt,
'node-name': 'overlay', 'node-name': 'overlay',
'backing': 'node0', 'backing': 'node0',
@ -75,12 +75,10 @@ class TestGraphChangesWhileIO(QMPTestCase):
'filename': top 'filename': top
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.qsd.qmp('blockdev-del', { self.qsd.cmd('blockdev-del', {
'node-name': 'overlay' 'node-name': 'overlay'
}) })
self.assert_qmp(result, 'return', {})
bench_thr.join() bench_thr.join()
@ -92,7 +90,7 @@ class TestGraphChangesWhileIO(QMPTestCase):
qemu_io('-c', 'write 0 64k', top) qemu_io('-c', 'write 0 64k', top)
qemu_io('-c', 'write 128k 64k', top) qemu_io('-c', 'write 128k 64k', top)
result = self.qsd.qmp('blockdev-add', { self.qsd.cmd('blockdev-add', {
'driver': imgfmt, 'driver': imgfmt,
'node-name': 'overlay', 'node-name': 'overlay',
'backing': None, 'backing': None,
@ -101,26 +99,22 @@ class TestGraphChangesWhileIO(QMPTestCase):
'filename': top 'filename': top
} }
}) })
self.assert_qmp(result, 'return', {})
result = self.qsd.qmp('blockdev-snapshot', { self.qsd.cmd('blockdev-snapshot', {
'node': 'node0', 'node': 'node0',
'overlay': 'overlay', 'overlay': 'overlay',
}) })
self.assert_qmp(result, 'return', {})
# While qemu-img bench is running, repeatedly commit overlay to node0 # While qemu-img bench is running, repeatedly commit overlay to node0
while bench_thr.is_alive(): while bench_thr.is_alive():
result = self.qsd.qmp('block-commit', { self.qsd.cmd('block-commit', {
'job-id': 'job0', 'job-id': 'job0',
'device': 'overlay', 'device': 'overlay',
}) })
self.assert_qmp(result, 'return', {})
result = self.qsd.qmp('block-job-cancel', { self.qsd.cmd('block-job-cancel', {
'device': 'job0', 'device': 'job0',
}) })
self.assert_qmp(result, 'return', {})
cancelled = False cancelled = False
while not cancelled: while not cancelled:

View File

@ -213,8 +213,7 @@ def do_test(vm, use_cbw, use_snapshot_access_filter, base_img_path,
result = vm.qmp('query-block-jobs') result = vm.qmp('query-block-jobs')
assert len(result['return']) == 1 assert len(result['return']) == 1
result = vm.qmp('block-job-set-speed', device='push-backup', speed=0) vm.cmd('block-job-set-speed', device='push-backup', speed=0)
assert result == {'return': {}}
log(vm.event_wait(name='BLOCK_JOB_COMPLETED', log(vm.event_wait(name='BLOCK_JOB_COMPLETED',
match={'data': {'device': 'push-backup'}}), match={'data': {'device': 'push-backup'}}),

View File

@ -118,11 +118,10 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
def start_postcopy(self): def start_postcopy(self):
""" Run migration until RESUME event on target. Return this event. """ """ Run migration until RESUME event on target. Return this event. """
for i in range(nb_bitmaps): for i in range(nb_bitmaps):
result = self.vm_a.qmp('block-dirty-bitmap-add', node='drive0', self.vm_a.cmd('block-dirty-bitmap-add', node='drive0',
name='bitmap{}'.format(i), name='bitmap{}'.format(i),
granularity=granularity, granularity=granularity,
persistent=True) persistent=True)
self.assert_qmp(result, 'return', {})
result = self.vm_a.qmp('x-debug-block-dirty-bitmap-sha256', result = self.vm_a.qmp('x-debug-block-dirty-bitmap-sha256',
node='drive0', name='bitmap0') node='drive0', name='bitmap0')
@ -140,9 +139,8 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
# We want to calculate resulting sha256. Do it in bitmap0, so, disable # We want to calculate resulting sha256. Do it in bitmap0, so, disable
# other bitmaps # other bitmaps
for i in range(1, nb_bitmaps): for i in range(1, nb_bitmaps):
result = self.vm_a.qmp('block-dirty-bitmap-disable', node='drive0', self.vm_a.cmd('block-dirty-bitmap-disable', node='drive0',
name='bitmap{}'.format(i)) name='bitmap{}'.format(i))
self.assert_qmp(result, 'return', {})
apply_discards(self.vm_a, discards2) apply_discards(self.vm_a, discards2)
@ -152,24 +150,19 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
# Now, enable some bitmaps, to be updated during migration # Now, enable some bitmaps, to be updated during migration
for i in range(2, nb_bitmaps, 2): for i in range(2, nb_bitmaps, 2):
result = self.vm_a.qmp('block-dirty-bitmap-enable', node='drive0', self.vm_a.cmd('block-dirty-bitmap-enable', node='drive0',
name='bitmap{}'.format(i)) name='bitmap{}'.format(i))
self.assert_qmp(result, 'return', {})
caps = [{'capability': 'dirty-bitmaps', 'state': True}, caps = [{'capability': 'dirty-bitmaps', 'state': True},
{'capability': 'events', 'state': True}] {'capability': 'events', 'state': True}]
result = self.vm_a.qmp('migrate-set-capabilities', capabilities=caps) self.vm_a.cmd('migrate-set-capabilities', capabilities=caps)
self.assert_qmp(result, 'return', {})
result = self.vm_b.qmp('migrate-set-capabilities', capabilities=caps) self.vm_b.cmd('migrate-set-capabilities', capabilities=caps)
self.assert_qmp(result, 'return', {})
result = self.vm_a.qmp('migrate', uri='exec:cat>' + fifo) self.vm_a.cmd('migrate', uri='exec:cat>' + fifo)
self.assert_qmp(result, 'return', {})
result = self.vm_a.qmp('migrate-start-postcopy') self.vm_a.cmd('migrate-start-postcopy')
self.assert_qmp(result, 'return', {})
event_resume = self.vm_b.event_wait('RESUME') event_resume = self.vm_b.event_wait('RESUME')
self.vm_b_events.append(event_resume) self.vm_b_events.append(event_resume)

View File

@ -67,8 +67,7 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
if persistent: if persistent:
params['persistent'] = True params['persistent'] = True
result = vm.qmp('block-dirty-bitmap-add', **params) vm.cmd('block-dirty-bitmap-add', params)
self.assert_qmp(result, 'return', {})
def check_bitmap(self, vm, sha256): def check_bitmap(self, vm, sha256):
result = vm.qmp('x-debug-block-dirty-bitmap-sha256', result = vm.qmp('x-debug-block-dirty-bitmap-sha256',
@ -91,16 +90,15 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
if migrate_bitmaps: if migrate_bitmaps:
mig_caps.append({'capability': 'dirty-bitmaps', 'state': True}) mig_caps.append({'capability': 'dirty-bitmaps', 'state': True})
result = self.vm_a.qmp('migrate-set-capabilities', self.vm_a.cmd('migrate-set-capabilities',
capabilities=mig_caps) capabilities=mig_caps)
self.assert_qmp(result, 'return', {})
self.add_bitmap(self.vm_a, granularity, persistent) self.add_bitmap(self.vm_a, granularity, persistent)
for r in regions: for r in regions:
self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % r) self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % r)
sha256 = get_bitmap_hash(self.vm_a) sha256 = get_bitmap_hash(self.vm_a)
result = self.vm_a.qmp('migrate', uri=mig_cmd) self.vm_a.cmd('migrate', uri=mig_cmd)
while True: while True:
event = self.vm_a.event_wait('MIGRATION') event = self.vm_a.event_wait('MIGRATION')
if event['data']['status'] == 'completed': if event['data']['status'] == 'completed':
@ -114,8 +112,7 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
removed = (not migrate_bitmaps) and persistent removed = (not migrate_bitmaps) and persistent
self.check_bitmap(self.vm_a, False if removed else sha256) self.check_bitmap(self.vm_a, False if removed else sha256)
result = self.vm_a.qmp('cont') self.vm_a.cmd('cont')
self.assert_qmp(result, 'return', {})
# test that bitmap is still here after invalidation # test that bitmap is still here after invalidation
self.check_bitmap(self.vm_a, sha256) self.check_bitmap(self.vm_a, sha256)
@ -158,9 +155,8 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
if online: if online:
os.mkfifo(mig_file) os.mkfifo(mig_file)
self.vm_b.launch() self.vm_b.launch()
result = self.vm_b.qmp('migrate-set-capabilities', self.vm_b.cmd('migrate-set-capabilities',
capabilities=mig_caps) capabilities=mig_caps)
self.assert_qmp(result, 'return', {})
self.add_bitmap(self.vm_a, granularity, persistent) self.add_bitmap(self.vm_a, granularity, persistent)
for r in regions: for r in regions:
@ -171,11 +167,10 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
self.vm_a.shutdown() self.vm_a.shutdown()
self.vm_a.launch() self.vm_a.launch()
result = self.vm_a.qmp('migrate-set-capabilities', self.vm_a.cmd('migrate-set-capabilities',
capabilities=mig_caps) capabilities=mig_caps)
self.assert_qmp(result, 'return', {})
result = self.vm_a.qmp('migrate', uri=mig_cmd) self.vm_a.cmd('migrate', uri=mig_cmd)
while True: while True:
event = self.vm_a.event_wait('MIGRATION') event = self.vm_a.event_wait('MIGRATION')
if event['data']['status'] == 'completed': if event['data']['status'] == 'completed':
@ -184,11 +179,9 @@ class TestDirtyBitmapMigration(iotests.QMPTestCase):
if not online: if not online:
self.vm_a.shutdown() self.vm_a.shutdown()
self.vm_b.launch() self.vm_b.launch()
result = self.vm_b.qmp('migrate-set-capabilities', self.vm_b.cmd('migrate-set-capabilities',
capabilities=mig_caps) capabilities=mig_caps)
self.assert_qmp(result, 'return', {}) self.vm_b.cmd('migrate-incoming', uri=incoming_cmd)
result = self.vm_b.qmp('migrate-incoming', uri=incoming_cmd)
self.assert_qmp(result, 'return', {})
while True: while True:
event = self.vm_b.event_wait('MIGRATION') event = self.vm_b.event_wait('MIGRATION')
@ -254,8 +247,7 @@ class TestDirtyBitmapBackingMigration(iotests.QMPTestCase):
self.vm = iotests.VM() self.vm = iotests.VM()
self.vm.launch() self.vm.launch()
result = self.vm.qmp('blockdev-add', **blockdev) self.vm.cmd('blockdev-add', blockdev)
self.assert_qmp(result, 'return', {})
# Check that the bitmaps are there # Check that the bitmaps are there
nodes = self.vm.qmp('query-named-block-nodes', flat=True)['return'] nodes = self.vm.qmp('query-named-block-nodes', flat=True)['return']
@ -264,8 +256,7 @@ class TestDirtyBitmapBackingMigration(iotests.QMPTestCase):
self.assert_qmp(node, 'dirty-bitmaps[0]/name', 'bmap0') self.assert_qmp(node, 'dirty-bitmaps[0]/name', 'bmap0')
caps = [{'capability': 'events', 'state': True}] caps = [{'capability': 'events', 'state': True}]
result = self.vm.qmp('migrate-set-capabilities', capabilities=caps) self.vm.cmd('migrate-set-capabilities', capabilities=caps)
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
self.vm.shutdown() self.vm.shutdown()
@ -276,14 +267,12 @@ class TestDirtyBitmapBackingMigration(iotests.QMPTestCase):
""" """
Continue the source after migration. Continue the source after migration.
""" """
result = self.vm.qmp('migrate', uri='exec: cat > /dev/null') self.vm.cmd('migrate', uri='exec: cat > /dev/null')
self.assert_qmp(result, 'return', {})
with Timeout(10, 'Migration timeout'): with Timeout(10, 'Migration timeout'):
self.vm.wait_migration('postmigrate') self.vm.wait_migration('postmigrate')
result = self.vm.qmp('cont') self.vm.cmd('cont')
self.assert_qmp(result, 'return', {})
def main() -> None: def main() -> None:

View File

@ -43,7 +43,7 @@ class TestMigrateDuringBackup(iotests.QMPTestCase):
self.vm = iotests.VM().add_drive(disk_a) self.vm = iotests.VM().add_drive(disk_a)
self.vm.launch() self.vm.launch()
result = self.vm.qmp('blockdev-add', { self.vm.cmd('blockdev-add', {
'node-name': 'target', 'node-name': 'target',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
@ -51,26 +51,21 @@ class TestMigrateDuringBackup(iotests.QMPTestCase):
'filename': disk_b 'filename': disk_b
} }
}) })
self.assert_qmp(result, 'return', {})
def test_migrate(self): def test_migrate(self):
result = self.vm.qmp('blockdev-backup', device='drive0', self.vm.cmd('blockdev-backup', device='drive0',
target='target', sync='full', target='target', sync='full',
speed=1, x_perf={ speed=1, x_perf={
'max-workers': 1, 'max-workers': 1,
'max-chunk': 64 * 1024 'max-chunk': 64 * 1024
}) })
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('job-pause', id='drive0') self.vm.cmd('job-pause', id='drive0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('migrate-set-capabilities', self.vm.cmd('migrate-set-capabilities',
capabilities=[{'capability': 'events', capabilities=[{'capability': 'events',
'state': True}]) 'state': True}])
self.assert_qmp(result, 'return', {}) self.vm.cmd('migrate', uri=mig_cmd)
result = self.vm.qmp('migrate', uri=mig_cmd)
self.assert_qmp(result, 'return', {})
e = self.vm.events_wait((('MIGRATION', e = self.vm.events_wait((('MIGRATION',
{'data': {'status': 'completed'}}), {'data': {'status': 'completed'}}),
@ -80,11 +75,9 @@ class TestMigrateDuringBackup(iotests.QMPTestCase):
# Don't assert that e is 'failed' now: this way we'll miss # Don't assert that e is 'failed' now: this way we'll miss
# possible crash when backup continues :) # possible crash when backup continues :)
result = self.vm.qmp('block-job-set-speed', device='drive0', self.vm.cmd('block-job-set-speed', device='drive0',
speed=0) speed=0)
self.assert_qmp(result, 'return', {}) self.vm.cmd('job-resume', id='drive0')
result = self.vm.qmp('job-resume', id='drive0')
self.assert_qmp(result, 'return', {})
# For future: if something changes so that both migration # For future: if something changes so that both migration
# and backup pass, let's not miss that moment, as it may # and backup pass, let's not miss that moment, as it may

View File

@ -47,11 +47,10 @@ class TestMigrationPermissions(iotests.QMPTestCase):
vms[i].launch() vms[i].launch()
result = vms[i].qmp('migrate-set-capabilities', vms[i].cmd('migrate-set-capabilities',
capabilities=[ capabilities=[
{'capability': 'events', 'state': True} {'capability': 'events', 'state': True}
]) ])
self.assert_qmp(result, 'return', {})
self.vm_s = vms[0] self.vm_s = vms[0]
self.vm_d = vms[1] self.vm_d = vms[1]

View File

@ -48,51 +48,48 @@ class TestMirrorReadyCancelError(iotests.QMPTestCase):
os.remove(target) os.remove(target)
def add_blockdevs(self, once: bool) -> None: def add_blockdevs(self, once: bool) -> None:
res = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
**{'node-name': 'source', {'node-name': 'source',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
'driver': 'file', 'driver': 'file',
'filename': source 'filename': source
}}) }})
self.assert_qmp(res, 'return', {})
# blkdebug notes: # blkdebug notes:
# Enter state 2 on the first flush, which happens before the # Enter state 2 on the first flush, which happens before the
# job enters the READY state. The second flush will happen # job enters the READY state. The second flush will happen
# when the job is about to complete, and we want that one to # when the job is about to complete, and we want that one to
# fail. # fail.
res = self.vm.qmp('blockdev-add', self.vm.cmd('blockdev-add',
**{'node-name': 'target', {'node-name': 'target',
'driver': iotests.imgfmt, 'driver': iotests.imgfmt,
'file': { 'file': {
'driver': 'blkdebug', 'driver': 'blkdebug',
'image': { 'image': {
'driver': 'file', 'driver': 'file',
'filename': target 'filename': target
}, },
'set-state': [{ 'set-state': [{
'event': 'flush_to_disk', 'event': 'flush_to_disk',
'state': 1, 'state': 1,
'new_state': 2 'new_state': 2
}], }],
'inject-error': [{ 'inject-error': [{
'event': 'flush_to_disk', 'event': 'flush_to_disk',
'once': once, 'once': once,
'immediately': True, 'immediately': True,
'state': 2 'state': 2
}]}}) }]}})
self.assert_qmp(res, 'return', {})
def start_mirror(self) -> None: def start_mirror(self) -> None:
res = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='source', device='source',
target='target', target='target',
filter_node_name='mirror-top', filter_node_name='mirror-top',
sync='full', sync='full',
on_target_error='stop') on_target_error='stop')
self.assert_qmp(res, 'return', {})
def cancel_mirror_with_error(self) -> None: def cancel_mirror_with_error(self) -> None:
self.vm.event_wait('BLOCK_JOB_READY') self.vm.event_wait('BLOCK_JOB_READY')
@ -107,8 +104,7 @@ class TestMirrorReadyCancelError(iotests.QMPTestCase):
while self.vm.event_wait('JOB_STATUS_CHANGE', timeout=0.0) is not None: while self.vm.event_wait('JOB_STATUS_CHANGE', timeout=0.0) is not None:
pass pass
res = self.vm.qmp('block-job-cancel', device='mirror') self.vm.cmd('block-job-cancel', device='mirror')
self.assert_qmp(res, 'return', {})
self.vm.event_wait('BLOCK_JOB_ERROR') self.vm.event_wait('BLOCK_JOB_ERROR')

View File

@ -78,12 +78,11 @@ class TestMirrorTopPerms(iotests.QMPTestCase):
difficult to let some other qemu process open the image.) difficult to let some other qemu process open the image.)
""" """
result = self.vm.qmp('blockdev-mirror', self.vm.cmd('blockdev-mirror',
job_id='mirror', job_id='mirror',
device='drive0', device='drive0',
target='null', target='null',
sync='full') sync='full')
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_READY') self.vm.event_wait('BLOCK_JOB_READY')
@ -105,9 +104,8 @@ class TestMirrorTopPerms(iotests.QMPTestCase):
except machine.VMLaunchFailure as exc: except machine.VMLaunchFailure as exc:
assert 'Is another process using the image' in exc.output assert 'Is another process using the image' in exc.output
result = self.vm.qmp('block-job-cancel', self.vm.cmd('block-job-cancel',
device='mirror') device='mirror')
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_COMPLETED') self.vm.event_wait('BLOCK_JOB_COMPLETED')

View File

@ -20,6 +20,8 @@
import os import os
from contextlib import contextmanager from contextlib import contextmanager
from types import ModuleType
import iotests import iotests
from iotests import qemu_img_create, qemu_io from iotests import qemu_img_create, qemu_io
@ -28,7 +30,7 @@ disk = os.path.join(iotests.test_dir, 'disk')
size = '4M' size = '4M'
nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock') nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock')
nbd_uri = 'nbd+unix:///{}?socket=' + nbd_sock nbd_uri = 'nbd+unix:///{}?socket=' + nbd_sock
nbd: ModuleType
@contextmanager @contextmanager
def open_nbd(export_name): def open_nbd(export_name):
@ -46,12 +48,11 @@ class TestNbdMulticonn(iotests.QMPTestCase):
self.vm = iotests.VM() self.vm = iotests.VM()
self.vm.launch() self.vm.launch()
result = self.vm.qmp('blockdev-add', { self.vm.cmd('blockdev-add', {
'driver': 'qcow2', 'driver': 'qcow2',
'node-name': 'n', 'node-name': 'n',
'file': {'driver': 'file', 'filename': disk} 'file': {'driver': 'file', 'filename': disk}
}) })
self.assert_qmp(result, 'return', {})
def tearDown(self): def tearDown(self):
self.vm.shutdown() self.vm.shutdown()
@ -72,12 +73,10 @@ class TestNbdMulticonn(iotests.QMPTestCase):
if max_connections is not None: if max_connections is not None:
args['max-connections'] = max_connections args['max-connections'] = max_connections
result = self.vm.qmp('nbd-server-start', args) self.vm.cmd('nbd-server-start', args)
self.assert_qmp(result, 'return', {})
yield yield
result = self.vm.qmp('nbd-server-stop') self.vm.cmd('nbd-server-stop')
self.assert_qmp(result, 'return', {})
def add_export(self, name, writable=None): def add_export(self, name, writable=None):
args = { args = {
@ -89,8 +88,7 @@ class TestNbdMulticonn(iotests.QMPTestCase):
if writable is not None: if writable is not None:
args['writable'] = writable args['writable'] = writable
result = self.vm.qmp('block-export-add', args) self.vm.cmd('block-export-add', args)
self.assert_qmp(result, 'return', {})
def test_default_settings(self): def test_default_settings(self):
with self.run_server(): with self.run_server():

View File

@ -64,12 +64,11 @@ class TestReopenFile(QMPTestCase):
self.fail('qemu-io pattern verification failed') self.fail('qemu-io pattern verification failed')
def test_reopen_file(self) -> None: def test_reopen_file(self) -> None:
result = self.vm.qmp('blockdev-reopen', options=[{ self.vm.cmd('blockdev-reopen', options=[{
'driver': imgfmt, 'driver': imgfmt,
'node-name': 'format', 'node-name': 'format',
'file': 'raw' 'file': 'raw'
}]) }])
self.assert_qmp(result, 'return', {})
# Do some I/O to the image to see whether it still works # Do some I/O to the image to see whether it still works
# (Pattern verification will be checked by tearDown()) # (Pattern verification will be checked by tearDown())

View File

@ -115,8 +115,7 @@ class TestStreamErrorOnReset(QMPTestCase):
# Launch a stream job, which will take at least a second to # Launch a stream job, which will take at least a second to
# complete, because the base image is throttled (so we can # complete, because the base image is throttled (so we can
# get in between it having started and it having completed) # get in between it having started and it having completed)
res = self.vm.qmp('block-stream', job_id='stream', device='top') self.vm.cmd('block-stream', job_id='stream', device='top')
self.assert_qmp(res, 'return', {})
while True: while True:
ev = self.vm.event_wait('JOB_STATUS_CHANGE') ev = self.vm.event_wait('JOB_STATUS_CHANGE')
@ -125,8 +124,7 @@ class TestStreamErrorOnReset(QMPTestCase):
# forces the virtio-scsi device to be reset, thus draining # forces the virtio-scsi device to be reset, thus draining
# the stream job, and making it complete. Completing # the stream job, and making it complete. Completing
# inside of that drain should not result in a segfault. # inside of that drain should not result in a segfault.
res = self.vm.qmp('system_reset') self.vm.cmd('system_reset')
self.assert_qmp(res, 'return', {})
elif ev['data']['status'] == 'null': elif ev['data']['status'] == 'null':
# The test is done once the job is gone # The test is done once the job is gone
break break

View File

@ -102,10 +102,9 @@ class TestStreamWithThrottle(iotests.QMPTestCase):
Do a simple stream beneath the two throttle nodes. Should complete Do a simple stream beneath the two throttle nodes. Should complete
with no problems. with no problems.
''' '''
result = self.vm.qmp('block-stream', self.vm.cmd('block-stream',
job_id='stream', job_id='stream',
device='unthrottled-node') device='unthrottled-node')
self.assert_qmp(result, 'return', {})
# Should succeed and not time out # Should succeed and not time out
try: try:

View File

@ -312,8 +312,8 @@ class BaseVM(object):
self._guest = guest self._guest = guest
# Init console so we can start consuming the chars. # Init console so we can start consuming the chars.
self.console_init() self.console_init()
usernet_info = guest.qmp("human-monitor-command", usernet_info = guest.cmd("human-monitor-command",
command_line="info usernet").get("return") command_line="info usernet")
self.ssh_port = get_info_usernet_hostfwd_port(usernet_info) self.ssh_port = get_info_usernet_hostfwd_port(usernet_info)
if not self.ssh_port: if not self.ssh_port:
raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \ raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \