# Common utilities and Python wrappers for qemu-iotests
#
# Copyright (C) 2012 IBM Corp.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import argparse
import atexit
import bz2
from collections import OrderedDict
import faulthandler
import json
import logging
import os
import re
import shutil
import signal
import struct
import subprocess
import sys
import time
from typing import (Any, Callable, Dict, Iterable, Iterator,
                    List, Optional, Sequence, TextIO, Tuple, Type, TypeVar)
import unittest

from contextlib import contextmanager

from qemu.machine import qtest
from qemu.qmp.legacy import QMPMessage, QMPReturnValue, QEMUMonitorProtocol
from qemu.utils import VerboseProcessError

# Use this logger for logging messages directly from the iotests module
logger = logging.getLogger('qemu.iotests')
logger.addHandler(logging.NullHandler())

# Use this logger for messages that ought to be used for diff output.
test_logger = logging.getLogger('qemu.iotests.diff_io')


faulthandler.enable()

# This will not work if arguments contain spaces but is necessary if we
# want to support the override options that ./check supports.
qemu_img_args = [os.environ.get('QEMU_IMG_PROG', 'qemu-img')]
if os.environ.get('QEMU_IMG_OPTIONS'):
    qemu_img_args += os.environ['QEMU_IMG_OPTIONS'].strip().split(' ')

qemu_io_args = [os.environ.get('QEMU_IO_PROG', 'qemu-io')]
if os.environ.get('QEMU_IO_OPTIONS'):
    qemu_io_args += os.environ['QEMU_IO_OPTIONS'].strip().split(' ')

qemu_io_args_no_fmt = [os.environ.get('QEMU_IO_PROG', 'qemu-io')]
if os.environ.get('QEMU_IO_OPTIONS_NO_FMT'):
    qemu_io_args_no_fmt += \
        os.environ['QEMU_IO_OPTIONS_NO_FMT'].strip().split(' ')

qemu_nbd_prog = os.environ.get('QEMU_NBD_PROG', 'qemu-nbd')
qemu_nbd_args = [qemu_nbd_prog]
if os.environ.get('QEMU_NBD_OPTIONS'):
    qemu_nbd_args += os.environ['QEMU_NBD_OPTIONS'].strip().split(' ')

qemu_prog = os.environ.get('QEMU_PROG', 'qemu')
qemu_opts = os.environ.get('QEMU_OPTIONS', '').strip().split(' ')

qsd_prog = os.environ.get('QSD_PROG', 'qemu-storage-daemon')

gdb_qemu_env = os.environ.get('GDB_OPTIONS')
qemu_gdb = []
if gdb_qemu_env:
    qemu_gdb = ['gdbserver'] + gdb_qemu_env.strip().split(' ')

qemu_print = os.environ.get('PRINT_QEMU', False)

imgfmt = os.environ.get('IMGFMT', 'raw')
imgproto = os.environ.get('IMGPROTO', 'file')

try:
    test_dir = os.environ['TEST_DIR']
    sock_dir = os.environ['SOCK_DIR']
    cachemode = os.environ['CACHEMODE']
    aiomode = os.environ['AIOMODE']
    qemu_default_machine = os.environ['QEMU_DEFAULT_MACHINE']
except KeyError:
    # We are using these variables as proxies to indicate that we're
    # not being run via "check". There may be other things set up by
    # "check" that individual test cases rely on.
    sys.stderr.write('Please run this test via the "check" script\n')
    sys.exit(os.EX_USAGE)

qemu_valgrind = []
if os.environ.get('VALGRIND_QEMU') == "y" and \
    os.environ.get('NO_VALGRIND') != "y":
    valgrind_logfile = "--log-file=" + test_dir
    # %p allows to put the valgrind process PID, since
    # we don't know it a priori (subprocess.Popen is
    # not yet invoked)
    valgrind_logfile += "/%p.valgrind"

    qemu_valgrind = ['valgrind', valgrind_logfile, '--error-exitcode=99']

luks_default_secret_object = 'secret,id=keysec0,data=' + \
                             os.environ.get('IMGKEYSECRET', '')
luks_default_key_secret_opt = 'key-secret=keysec0'

sample_img_dir = os.environ['SAMPLE_IMG_DIR']


@contextmanager
def change_log_level(
        logger_name: str, level: int = logging.CRITICAL) -> Iterator[None]:
    """
    Utility function for temporarily changing the log level of a logger.

    This can be used to silence errors that are expected or uninteresting.
    """
    _logger = logging.getLogger(logger_name)
    current_level = _logger.level
    _logger.setLevel(level)

    try:
        yield
    finally:
        _logger.setLevel(current_level)


def unarchive_sample_image(sample, fname):
    sample_fname = os.path.join(sample_img_dir, sample + '.bz2')
    with bz2.open(sample_fname) as f_in, open(fname, 'wb') as f_out:
        shutil.copyfileobj(f_in, f_out)


def qemu_tool_popen(args: Sequence[str],
                    connect_stderr: bool = True) -> 'subprocess.Popen[str]':
    stderr = subprocess.STDOUT if connect_stderr else None
    # pylint: disable=consider-using-with
    return subprocess.Popen(args,
                            stdout=subprocess.PIPE,
                            stderr=stderr,
                            universal_newlines=True)


def qemu_tool_pipe_and_status(tool: str, args: Sequence[str],
                              connect_stderr: bool = True,
                              drop_successful_output: bool = False) \
        -> Tuple[str, int]:
    """
    Run a tool and return both its output and its exit code
    """
    with qemu_tool_popen(args, connect_stderr) as subp:
        output = subp.communicate()[0]
        if subp.returncode < 0:
            cmd = ' '.join(args)
            sys.stderr.write(f'{tool} received signal \
                               {-subp.returncode}: {cmd}\n')
        if drop_successful_output and subp.returncode == 0:
            output = ''
        return (output, subp.returncode)

def qemu_img_create_prepare_args(args: List[str]) -> List[str]:
    if not args or args[0] != 'create':
        return list(args)
    args = args[1:]

    p = argparse.ArgumentParser(allow_abbrev=False)
    # -o option may be specified several times
    p.add_argument('-o', action='append', default=[])
    p.add_argument('-f')
    parsed, remaining = p.parse_known_args(args)

    opts_list = parsed.o

    result = ['create']
    if parsed.f is not None:
        result += ['-f', parsed.f]

    # IMGOPTS most probably contain options specific for the selected format,
    # like extended_l2 or compression_type for qcow2. Test may want to create
    # additional images in other formats that doesn't support these options.
    # So, use IMGOPTS only for images created in imgfmt format.
    imgopts = os.environ.get('IMGOPTS')
    if imgopts and parsed.f == imgfmt:
        opts_list.insert(0, imgopts)

    # default luks support
    if parsed.f == 'luks' and \
            all('key-secret' not in opts for opts in opts_list):
        result += ['--object', luks_default_secret_object]
        opts_list.append(luks_default_key_secret_opt)

    for opts in opts_list:
        result += ['-o', opts]

    result += remaining

    return result


def qemu_tool(*args: str, check: bool = True, combine_stdio: bool = True
              ) -> 'subprocess.CompletedProcess[str]':
    """
    Run a qemu tool and return its status code and console output.

    :param args: full command line to run.
    :param check: Enforce a return code of zero.
    :param combine_stdio: set to False to keep stdout/stderr separated.

    :raise VerboseProcessError:
        When the return code is negative, or on any non-zero exit code
        when 'check=True' was provided (the default). This exception has
        'stdout', 'stderr', and 'returncode' properties that may be
        inspected to show greater detail. If this exception is not
        handled, the command-line, return code, and all console output
        will be included at the bottom of the stack trace.

    :return:
        a CompletedProcess. This object has args, returncode, and stdout
        properties. If streams are not combined, it will also have a
        stderr property.
    """
    subp = subprocess.run(
        args,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT if combine_stdio else subprocess.PIPE,
        universal_newlines=True,
        check=False
    )

    if check and subp.returncode or (subp.returncode < 0):
        raise VerboseProcessError(
            subp.returncode, args,
            output=subp.stdout,
            stderr=subp.stderr,
        )

    return subp


def qemu_img(*args: str, check: bool = True, combine_stdio: bool = True
             ) -> 'subprocess.CompletedProcess[str]':
    """
    Run QEMU_IMG_PROG and return its status code and console output.

    This function always prepends QEMU_IMG_OPTIONS and may further alter
    the args for 'create' commands.

    See `qemu_tool()` for greater detail.
    """
    full_args = qemu_img_args + qemu_img_create_prepare_args(list(args))
    return qemu_tool(*full_args, check=check, combine_stdio=combine_stdio)


def ordered_qmp(qmsg, conv_keys=True):
    # Dictionaries are not ordered prior to 3.6, therefore:
    if isinstance(qmsg, list):
        return [ordered_qmp(atom) for atom in qmsg]
    if isinstance(qmsg, dict):
        od = OrderedDict()
        for k, v in sorted(qmsg.items()):
            if conv_keys:
                k = k.replace('_', '-')
            od[k] = ordered_qmp(v, conv_keys=False)
        return od
    return qmsg

def qemu_img_create(*args: str) -> 'subprocess.CompletedProcess[str]':
    return qemu_img('create', *args)

def qemu_img_json(*args: str) -> Any:
    """
    Run qemu-img and return its output as deserialized JSON.

    :raise CalledProcessError:
        When qemu-img crashes, or returns a non-zero exit code without
        producing a valid JSON document to stdout.
    :raise JSONDecoderError:
        When qemu-img returns 0, but failed to produce a valid JSON document.

    :return: A deserialized JSON object; probably a dict[str, Any].
    """
    try:
        res = qemu_img(*args, combine_stdio=False)
    except subprocess.CalledProcessError as exc:
        # Terminated due to signal. Don't bother.
        if exc.returncode < 0:
            raise

        # Commands like 'check' can return failure (exit codes 2 and 3)
        # to indicate command completion, but with errors found. For
        # multi-command flexibility, ignore the exact error codes and
        # *try* to load JSON.
        try:
            return json.loads(exc.stdout)
        except json.JSONDecodeError:
            # Nope. This thing is toast. Raise the /process/ error.
            pass
        raise

    return json.loads(res.stdout)

def qemu_img_measure(*args: str) -> Any:
    return qemu_img_json("measure", "--output", "json", *args)

def qemu_img_check(*args: str) -> Any:
    return qemu_img_json("check", "--output", "json", *args)

def qemu_img_info(*args: str) -> Any:
    return qemu_img_json('info', "--output", "json", *args)

def qemu_img_map(*args: str) -> Any:
    return qemu_img_json('map', "--output", "json", *args)

def qemu_img_log(*args: str, check: bool = True
                 ) -> 'subprocess.CompletedProcess[str]':
    result = qemu_img(*args, check=check)
    log(result.stdout, filters=[filter_testfiles])
    return result

def img_info_log(filename: str, filter_path: Optional[str] = None,
                 use_image_opts: bool = False, extra_args: Sequence[str] = (),
                 check: bool = True, drop_child_info: bool = True,
                 ) -> None:
    args = ['info']
    if use_image_opts:
        args.append('--image-opts')
    else:
        args += ['-f', imgfmt]
    args += extra_args
    args.append(filename)

    output = qemu_img(*args, check=check).stdout
    if not filter_path:
        filter_path = filename
    log(filter_img_info(output, filter_path, drop_child_info))

def qemu_io_wrap_args(args: Sequence[str]) -> List[str]:
    if '-f' in args or '--image-opts' in args:
        return qemu_io_args_no_fmt + list(args)
    else:
        return qemu_io_args + list(args)

def qemu_io_popen(*args):
    return qemu_tool_popen(qemu_io_wrap_args(args))

def qemu_io(*args: str, check: bool = True, combine_stdio: bool = True
            ) -> 'subprocess.CompletedProcess[str]':
    """
    Run QEMU_IO_PROG and return the status code and console output.

    This function always prepends either QEMU_IO_OPTIONS or
    QEMU_IO_OPTIONS_NO_FMT.
    """
    return qemu_tool(*qemu_io_wrap_args(args),
                     check=check, combine_stdio=combine_stdio)

def qemu_io_log(*args: str, check: bool = True
                ) -> 'subprocess.CompletedProcess[str]':
    result = qemu_io(*args, check=check)
    log(result.stdout, filters=[filter_testfiles, filter_qemu_io])
    return result

class QemuIoInteractive:
    def __init__(self, *args):
        self.args = qemu_io_wrap_args(args)
        # We need to keep the Popen objext around, and not
        # close it immediately. Therefore, disable the pylint check:
        # pylint: disable=consider-using-with
        self._p = subprocess.Popen(self.args, stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT,
                                   universal_newlines=True)
        out = self._p.stdout.read(9)
        if out != 'qemu-io> ':
            # Most probably qemu-io just failed to start.
            # Let's collect the whole output and exit.
            out += self._p.stdout.read()
            self._p.wait(timeout=1)
            raise ValueError(out)

    def close(self):
        self._p.communicate('q\n')

    def _read_output(self):
        pattern = 'qemu-io> '
        n = len(pattern)
        pos = 0
        s = []
        while pos != n:
            c = self._p.stdout.read(1)
            # check unexpected EOF
            assert c != ''
            s.append(c)
            if c == pattern[pos]:
                pos += 1
            else:
                pos = 0

        return ''.join(s[:-n])

    def cmd(self, cmd):
        # quit command is in close(), '\n' is added automatically
        assert '\n' not in cmd
        cmd = cmd.strip()
        assert cmd not in ('q', 'quit')
        self._p.stdin.write(cmd + '\n')
        self._p.stdin.flush()
        return self._read_output()


class QemuStorageDaemon:
    _qmp: Optional[QEMUMonitorProtocol] = None
    _qmpsock: Optional[str] = None
    # Python < 3.8 would complain if this type were not a string literal
    # (importing `annotations` from `__future__` would work; but not on <= 3.6)
    _p: 'Optional[subprocess.Popen[bytes]]' = None

    def __init__(self, *args: str, instance_id: str = 'a', qmp: bool = False):
        assert '--pidfile' not in args
        self.pidfile = os.path.join(test_dir, f'qsd-{instance_id}-pid')
        all_args = [qsd_prog] + list(args) + ['--pidfile', self.pidfile]

        if qmp:
            self._qmpsock = os.path.join(sock_dir, f'qsd-{instance_id}.sock')
            all_args += ['--chardev',
                         f'socket,id=qmp-sock,path={self._qmpsock}',
                         '--monitor', 'qmp-sock']

            self._qmp = QEMUMonitorProtocol(self._qmpsock, server=True)

        # Cannot use with here, we want the subprocess to stay around
        # pylint: disable=consider-using-with
        self._p = subprocess.Popen(all_args)
        if self._qmp is not None:
            self._qmp.accept()
        while not os.path.exists(self.pidfile):
            if self._p.poll() is not None:
                cmd = ' '.join(all_args)
                raise RuntimeError(
                    'qemu-storage-daemon terminated with exit code ' +
                    f'{self._p.returncode}: {cmd}')

            time.sleep(0.01)

        with open(self.pidfile, encoding='utf-8') as f:
            self._pid = int(f.read().strip())

        assert self._pid == self._p.pid

    def qmp(self, cmd: str, args: Optional[Dict[str, object]] = None) \
            -> QMPMessage:
        assert self._qmp is not None
        return self._qmp.cmd_raw(cmd, args)

    def get_qmp(self) -> QEMUMonitorProtocol:
        assert self._qmp is not None
        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):
        self._p.send_signal(kill_signal)
        self._p.wait()
        self._p = None

        if self._qmp:
            self._qmp.close()

        if self._qmpsock is not None:
            try:
                os.remove(self._qmpsock)
            except OSError:
                pass
        try:
            os.remove(self.pidfile)
        except OSError:
            pass

    def __del__(self):
        if self._p is not None:
            self.stop(kill_signal=9)


def qemu_nbd(*args):
    '''Run qemu-nbd in daemon mode and return the parent's exit code'''
    return subprocess.call(qemu_nbd_args + ['--fork'] + list(args))

def qemu_nbd_early_pipe(*args: str) -> Tuple[int, str]:
    '''Run qemu-nbd in daemon mode and return both the parent's exit code
       and its output in case of an error'''
    full_args = qemu_nbd_args + ['--fork'] + list(args)
    output, returncode = qemu_tool_pipe_and_status('qemu-nbd', full_args,
                                                   connect_stderr=False)
    return returncode, output if returncode else ''

def qemu_nbd_list_log(*args: str) -> str:
    '''Run qemu-nbd to list remote exports'''
    full_args = [qemu_nbd_prog, '-L'] + list(args)
    output, _ = qemu_tool_pipe_and_status('qemu-nbd', full_args)
    log(output, filters=[filter_testfiles, filter_nbd_exports])
    return output

@contextmanager
def qemu_nbd_popen(*args):
    '''Context manager running qemu-nbd within the context'''
    pid_file = file_path("qemu_nbd_popen-nbd-pid-file")

    assert not os.path.exists(pid_file)

    cmd = list(qemu_nbd_args)
    cmd.extend(('--persistent', '--pid-file', pid_file))
    cmd.extend(args)

    log('Start NBD server')
    with subprocess.Popen(cmd) as p:
        try:
            while not os.path.exists(pid_file):
                if p.poll() is not None:
                    raise RuntimeError(
                        "qemu-nbd terminated with exit code {}: {}"
                        .format(p.returncode, ' '.join(cmd)))

                time.sleep(0.01)
            yield
        finally:
            if os.path.exists(pid_file):
                os.remove(pid_file)
            log('Kill NBD server')
            p.kill()
            p.wait()

def compare_images(img1: str, img2: str,
                   fmt1: str = imgfmt, fmt2: str = imgfmt) -> bool:
    """
    Compare two images with QEMU_IMG; return True if they are identical.

    :raise CalledProcessError:
        when qemu-img crashes or returns a status code of anything other
        than 0 (identical) or 1 (different).
    """
    try:
        qemu_img('compare', '-f', fmt1, '-F', fmt2, img1, img2)
        return True
    except subprocess.CalledProcessError as exc:
        if exc.returncode == 1:
            return False
        raise

def create_image(name, size):
    '''Create a fully-allocated raw image with sector markers'''
    with open(name, 'wb') as file:
        i = 0
        while i < size:
            sector = struct.pack('>l504xl', i // 512, i // 512)
            file.write(sector)
            i = i + 512

def image_size(img: str) -> int:
    """Return image's virtual size"""
    value = qemu_img_info('-f', imgfmt, img)['virtual-size']
    if not isinstance(value, int):
        type_name = type(value).__name__
        raise TypeError("Expected 'int' for 'virtual-size', "
                        f"got '{value}' of type '{type_name}'")
    return value

def is_str(val):
    return isinstance(val, str)

test_dir_re = re.compile(r"%s" % test_dir)
def filter_test_dir(msg):
    return test_dir_re.sub("TEST_DIR", msg)

win32_re = re.compile(r"\r")
def filter_win32(msg):
    return win32_re.sub("", msg)

qemu_io_re = re.compile(r"[0-9]* ops; [0-9\/:. sec]* "
                        r"\([0-9\/.inf]* [EPTGMKiBbytes]*\/sec "
                        r"and [0-9\/.inf]* ops\/sec\)")
def filter_qemu_io(msg):
    msg = filter_win32(msg)
    return qemu_io_re.sub("X ops; XX:XX:XX.X "
                          "(XXX YYY/sec and XXX ops/sec)", msg)

chown_re = re.compile(r"chown [0-9]+:[0-9]+")
def filter_chown(msg):
    return chown_re.sub("chown UID:GID", msg)

def filter_qmp_event(event):
    '''Filter a QMP event dict'''
    event = dict(event)
    if 'timestamp' in event:
        event['timestamp']['seconds'] = 'SECS'
        event['timestamp']['microseconds'] = 'USECS'
    return event

def filter_qmp(qmsg, filter_fn):
    '''Given a string filter, filter a QMP object's values.
    filter_fn takes a (key, value) pair.'''
    # Iterate through either lists or dicts;
    if isinstance(qmsg, list):
        items = enumerate(qmsg)
    elif isinstance(qmsg, dict):
        items = qmsg.items()
    else:
        return filter_fn(None, qmsg)

    for k, v in items:
        if isinstance(v, (dict, list)):
            qmsg[k] = filter_qmp(v, filter_fn)
        else:
            qmsg[k] = filter_fn(k, v)
    return qmsg

def filter_testfiles(msg):
    pref1 = os.path.join(test_dir, "%s-" % (os.getpid()))
    pref2 = os.path.join(sock_dir, "%s-" % (os.getpid()))
    return msg.replace(pref1, 'TEST_DIR/PID-').replace(pref2, 'SOCK_DIR/PID-')

def filter_qmp_testfiles(qmsg):
    def _filter(_key, value):
        if is_str(value):
            return filter_testfiles(value)
        return value
    return filter_qmp(qmsg, _filter)

def filter_virtio_scsi(output: str) -> str:
    return re.sub(r'(virtio-scsi)-(ccw|pci)', r'\1', output)

def filter_qmp_virtio_scsi(qmsg):
    def _filter(_key, value):
        if is_str(value):
            return filter_virtio_scsi(value)
        return value
    return filter_qmp(qmsg, _filter)

def filter_generated_node_ids(msg):
    return re.sub("#block[0-9]+", "NODE_NAME", msg)

def filter_qmp_generated_node_ids(qmsg):
    def _filter(_key, value):
        if is_str(value):
            return filter_generated_node_ids(value)
        return value
    return filter_qmp(qmsg, _filter)

def filter_img_info(output: str, filename: str,
                    drop_child_info: bool = True) -> str:
    lines = []
    drop_indented = False
    for line in output.split('\n'):
        if 'disk size' in line or 'actual-size' in line:
            continue

        # Drop child node info
        if drop_indented:
            if line.startswith(' '):
                continue
            drop_indented = False
        if drop_child_info and "Child node '/" in line:
            drop_indented = True
            continue

        line = line.replace(filename, 'TEST_IMG')
        line = filter_testfiles(line)
        line = line.replace(imgfmt, 'IMGFMT')
        line = re.sub('iters: [0-9]+', 'iters: XXX', line)
        line = re.sub('uuid: [-a-f0-9]+',
                      'uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
                      line)
        line = re.sub('cid: [0-9]+', 'cid: XXXXXXXXXX', line)
        line = re.sub('(compression type: )(zlib|zstd)', r'\1COMPRESSION_TYPE',
                      line)
        lines.append(line)
    return '\n'.join(lines)

def filter_imgfmt(msg):
    return msg.replace(imgfmt, 'IMGFMT')

def filter_qmp_imgfmt(qmsg):
    def _filter(_key, value):
        if is_str(value):
            return filter_imgfmt(value)
        return value
    return filter_qmp(qmsg, _filter)

def filter_nbd_exports(output: str) -> str:
    return re.sub(r'((min|opt|max) block): [0-9]+', r'\1: XXX', output)


Msg = TypeVar('Msg', Dict[str, Any], List[Any], str)

def log(msg: Msg,
        filters: Iterable[Callable[[Msg], Msg]] = (),
        indent: Optional[int] = None) -> None:
    """
    Logs either a string message or a JSON serializable message (like QMP).
    If indent is provided, JSON serializable messages are pretty-printed.
    """
    for flt in filters:
        msg = flt(msg)
    if isinstance(msg, (dict, list)):
        # Don't sort if it's already sorted
        do_sort = not isinstance(msg, OrderedDict)
        test_logger.info(json.dumps(msg, sort_keys=do_sort, indent=indent))
    else:
        test_logger.info(msg)

class Timeout:
    def __init__(self, seconds, errmsg="Timeout"):
        self.seconds = seconds
        self.errmsg = errmsg
    def __enter__(self):
        if qemu_gdb or qemu_valgrind:
            return self
        signal.signal(signal.SIGALRM, self.timeout)
        signal.setitimer(signal.ITIMER_REAL, self.seconds)
        return self
    def __exit__(self, exc_type, value, traceback):
        if qemu_gdb or qemu_valgrind:
            return False
        signal.setitimer(signal.ITIMER_REAL, 0)
        return False
    def timeout(self, signum, frame):
        raise TimeoutError(self.errmsg)

def file_pattern(name):
    return "{0}-{1}".format(os.getpid(), name)

class FilePath:
    """
    Context manager generating multiple file names. The generated files are
    removed when exiting the context.

    Example usage:

        with FilePath('a.img', 'b.img') as (img_a, img_b):
            # Use img_a and img_b here...

        # a.img and b.img are automatically removed here.

    By default images are created in iotests.test_dir. To create sockets use
    iotests.sock_dir:

       with FilePath('a.sock', base_dir=iotests.sock_dir) as sock:

    For convenience, calling with one argument yields a single file instead of
    a tuple with one item.

    """
    def __init__(self, *names, base_dir=test_dir):
        self.paths = [os.path.join(base_dir, file_pattern(name))
                      for name in names]

    def __enter__(self):
        if len(self.paths) == 1:
            return self.paths[0]
        else:
            return self.paths

    def __exit__(self, exc_type, exc_val, exc_tb):
        for path in self.paths:
            try:
                os.remove(path)
            except OSError:
                pass
        return False


def try_remove(img):
    try:
        os.remove(img)
    except OSError:
        pass

def file_path_remover():
    for path in reversed(file_path_remover.paths):
        try_remove(path)


def file_path(*names, base_dir=test_dir):
    ''' Another way to get auto-generated filename that cleans itself up.

    Use is as simple as:

    img_a, img_b = file_path('a.img', 'b.img')
    sock = file_path('socket')
    '''

    if not hasattr(file_path_remover, 'paths'):
        file_path_remover.paths = []
        atexit.register(file_path_remover)

    paths = []
    for name in names:
        filename = file_pattern(name)
        path = os.path.join(base_dir, filename)
        file_path_remover.paths.append(path)
        paths.append(path)

    return paths[0] if len(paths) == 1 else paths

def remote_filename(path):
    if imgproto == 'file':
        return path
    elif imgproto == 'ssh':
        return "ssh://%s@127.0.0.1:22%s" % (os.environ.get('USER'), path)
    else:
        raise ValueError("Protocol %s not supported" % (imgproto))

class VM(qtest.QEMUQtestMachine):
    '''A QEMU VM'''

    def __init__(self, path_suffix=''):
        name = "qemu%s-%d" % (path_suffix, os.getpid())
        timer = 15.0 if not (qemu_gdb or qemu_valgrind) else None
        if qemu_gdb and qemu_valgrind:
            sys.stderr.write('gdb and valgrind are mutually exclusive\n')
            sys.exit(1)
        wrapper = qemu_gdb if qemu_gdb else qemu_valgrind
        super().__init__(qemu_prog, qemu_opts, wrapper=wrapper,
                         name=name,
                         base_temp_dir=test_dir,
                         qmp_timer=timer)
        self._num_drives = 0

    def _post_shutdown(self) -> None:
        super()._post_shutdown()
        if not qemu_valgrind or not self._popen:
            return
        valgrind_filename = f"{test_dir}/{self._popen.pid}.valgrind"
        if self.exitcode() == 99:
            with open(valgrind_filename, encoding='utf-8') as f:
                print(f.read())
        else:
            os.remove(valgrind_filename)

    def _pre_launch(self) -> None:
        super()._pre_launch()
        if qemu_print:
            # set QEMU binary output to stdout
            self._close_qemu_log_file()

    def add_object(self, opts):
        self._args.append('-object')
        self._args.append(opts)
        return self

    def add_device(self, opts):
        self._args.append('-device')
        self._args.append(opts)
        return self

    def add_drive_raw(self, opts):
        self._args.append('-drive')
        self._args.append(opts)
        return self

    def add_drive(self, path, opts='', interface='virtio', img_format=imgfmt):
        '''Add a virtio-blk drive to the VM'''
        options = ['if=%s' % interface,
                   'id=drive%d' % self._num_drives]

        if path is not None:
            options.append('file=%s' % path)
            options.append('format=%s' % img_format)
            options.append('cache=%s' % cachemode)
            options.append('aio=%s' % aiomode)

        if opts:
            options.append(opts)

        if img_format == 'luks' and 'key-secret' not in opts:
            # default luks support
            if luks_default_secret_object not in self._args:
                self.add_object(luks_default_secret_object)

            options.append(luks_default_key_secret_opt)

        self._args.append('-drive')
        self._args.append(','.join(options))
        self._num_drives += 1
        return self

    def add_blockdev(self, opts):
        self._args.append('-blockdev')
        if isinstance(opts, str):
            self._args.append(opts)
        else:
            self._args.append(','.join(opts))
        return self

    def add_incoming(self, addr):
        self._args.append('-incoming')
        self._args.append(addr)
        return self

    def hmp(self, command_line: str, use_log: bool = False) -> QMPMessage:
        cmd = 'human-monitor-command'
        kwargs: Dict[str, Any] = {'command-line': command_line}
        if use_log:
            return self.qmp_log(cmd, **kwargs)
        else:
            return self.qmp(cmd, **kwargs)

    def pause_drive(self, drive: str, event: Optional[str] = None) -> None:
        """Pause drive r/w operations"""
        if not event:
            self.pause_drive(drive, "read_aio")
            self.pause_drive(drive, "write_aio")
            return
        self.hmp(f'qemu-io {drive} "break {event} bp_{drive}"')

    def resume_drive(self, drive: str) -> None:
        """Resume drive r/w operations"""
        self.hmp(f'qemu-io {drive} "remove_break bp_{drive}"')

    def hmp_qemu_io(self, drive: str, cmd: str,
                    use_log: bool = False, qdev: bool = False) -> QMPMessage:
        """Write to a given drive using an HMP command"""
        d = '-d ' if qdev else ''
        return self.hmp(f'qemu-io {d}{drive} "{cmd}"', use_log=use_log)

    def flatten_qmp_object(self, obj, output=None, basestr=''):
        if output is None:
            output = {}
        if isinstance(obj, list):
            for i, item in enumerate(obj):
                self.flatten_qmp_object(item, output, basestr + str(i) + '.')
        elif isinstance(obj, dict):
            for key in obj:
                self.flatten_qmp_object(obj[key], output, basestr + key + '.')
        else:
            output[basestr[:-1]] = obj # Strip trailing '.'
        return output

    def qmp_to_opts(self, obj):
        obj = self.flatten_qmp_object(obj)
        output_list = []
        for key in obj:
            output_list += [key + '=' + obj[key]]
        return ','.join(output_list)

    def get_qmp_events_filtered(self, wait=60.0):
        result = []
        for ev in self.get_qmp_events(wait=wait):
            result.append(filter_qmp_event(ev))
        return result

    def qmp_log(self, cmd, filters=(), indent=None, **kwargs):
        full_cmd = OrderedDict((
            ("execute", cmd),
            ("arguments", ordered_qmp(kwargs))
        ))
        log(full_cmd, filters, indent=indent)
        result = self.qmp(cmd, **kwargs)
        log(result, filters, indent=indent)
        return result

    # Returns None on success, and an error string on failure
    def run_job(self, job: str, auto_finalize: bool = True,
                auto_dismiss: bool = False,
                pre_finalize: Optional[Callable[[], None]] = None,
                cancel: bool = False, wait: float = 60.0,
                filters: Iterable[Callable[[Any], Any]] = (),
                ) -> Optional[str]:
        """
        run_job moves a job from creation through to dismissal.

        :param job: String. ID of recently-launched job
        :param auto_finalize: Bool. True if the job was launched with
                              auto_finalize. Defaults to True.
        :param auto_dismiss: Bool. True if the job was launched with
                             auto_dismiss=True. Defaults to False.
        :param pre_finalize: Callback. A callable that takes no arguments to be
                             invoked prior to issuing job-finalize, if any.
        :param cancel: Bool. When true, cancels the job after the pre_finalize
                       callback.
        :param wait: Float. Timeout value specifying how long to wait for any
                     event, in seconds. Defaults to 60.0.
        """
        match_device = {'data': {'device': job}}
        match_id = {'data': {'id': job}}
        events = [
            ('BLOCK_JOB_COMPLETED', match_device),
            ('BLOCK_JOB_CANCELLED', match_device),
            ('BLOCK_JOB_ERROR', match_device),
            ('BLOCK_JOB_READY', match_device),
            ('BLOCK_JOB_PENDING', match_id),
            ('JOB_STATUS_CHANGE', match_id)
        ]
        error = None
        while True:
            ev = filter_qmp_event(self.events_wait(events, timeout=wait))
            if ev['event'] != 'JOB_STATUS_CHANGE':
                log(ev, filters=filters)
                continue
            status = ev['data']['status']
            if status == 'aborting':
                result = self.qmp('query-jobs')
                for j in result['return']:
                    if j['id'] == job:
                        error = j['error']
                        log('Job failed: %s' % (j['error']), filters=filters)
            elif status == 'ready':
                self.qmp_log('job-complete', id=job, filters=filters)
            elif status == 'pending' and not auto_finalize:
                if pre_finalize:
                    pre_finalize()
                if cancel:
                    self.qmp_log('job-cancel', id=job, filters=filters)
                else:
                    self.qmp_log('job-finalize', id=job, filters=filters)
            elif status == 'concluded' and not auto_dismiss:
                self.qmp_log('job-dismiss', id=job, filters=filters)
            elif status == 'null':
                return error

    # Returns None on success, and an error string on failure
    def blockdev_create(self, options, job_id='job0', filters=None):
        if filters is None:
            filters = [filter_qmp_testfiles]
        result = self.qmp_log('blockdev-create', filters=filters,
                              job_id=job_id, options=options)

        if 'return' in result:
            assert result['return'] == {}
            job_result = self.run_job(job_id, filters=filters)
        else:
            job_result = result['error']

        log("")
        return job_result

    def enable_migration_events(self, name):
        log('Enabling migration QMP events on %s...' % name)
        log(self.qmp('migrate-set-capabilities', capabilities=[
            {
                'capability': 'events',
                'state': True
            }
        ]))

    def wait_migration(self, expect_runstate: Optional[str]) -> bool:
        while True:
            event = self.event_wait('MIGRATION')
            # We use the default timeout, and with a timeout, event_wait()
            # never returns None
            assert event

            log(event, filters=[filter_qmp_event])
            if event['data']['status'] in ('completed', 'failed'):
                break

        if event['data']['status'] == 'completed':
            # The event may occur in finish-migrate, so wait for the expected
            # post-migration runstate
            runstate = None
            while runstate != expect_runstate:
                runstate = self.qmp('query-status')['return']['status']
            return True
        else:
            return False

    def node_info(self, node_name):
        nodes = self.qmp('query-named-block-nodes')
        for x in nodes['return']:
            if x['node-name'] == node_name:
                return x
        return None

    def query_bitmaps(self):
        res = self.qmp("query-named-block-nodes")
        return {device['node-name']: device['dirty-bitmaps']
                for device in res['return'] if 'dirty-bitmaps' in device}

    def get_bitmap(self, node_name, bitmap_name, recording=None, bitmaps=None):
        """
        get a specific bitmap from the object returned by query_bitmaps.
        :param recording: If specified, filter results by the specified value.
        :param bitmaps: If specified, use it instead of call query_bitmaps()
        """
        if bitmaps is None:
            bitmaps = self.query_bitmaps()

        for bitmap in bitmaps[node_name]:
            if bitmap.get('name', '') == bitmap_name:
                if recording is None or bitmap.get('recording') == recording:
                    return bitmap
        return None

    def check_bitmap_status(self, node_name, bitmap_name, fields):
        ret = self.get_bitmap(node_name, bitmap_name)

        return fields.items() <= ret.items()

    def assert_block_path(self, root, path, expected_node, graph=None):
        """
        Check whether the node under the given path in the block graph
        is @expected_node.

        @root is the node name of the node where the @path is rooted.

        @path is a string that consists of child names separated by
        slashes.  It must begin with a slash.

        Examples for @root + @path:
          - root="qcow2-node", path="/backing/file"
          - root="quorum-node", path="/children.2/file"

        Hypothetically, @path could be empty, in which case it would
        point to @root.  However, in practice this case is not useful
        and hence not allowed.

        @expected_node may be None.  (All elements of the path but the
        leaf must still exist.)

        @graph may be None or the result of an x-debug-query-block-graph
        call that has already been performed.
        """
        if graph is None:
            graph = self.qmp('x-debug-query-block-graph')['return']

        iter_path = iter(path.split('/'))

        # Must start with a /
        assert next(iter_path) == ''

        node = next((node for node in graph['nodes'] if node['name'] == root),
                    None)

        # An empty @path is not allowed, so the root node must be present
        assert node is not None, 'Root node %s not found' % root

        for child_name in iter_path:
            assert node is not None, 'Cannot follow path %s%s' % (root, path)

            try:
                node_id = next(edge['child'] for edge in graph['edges']
                               if (edge['parent'] == node['id'] and
                                   edge['name'] == child_name))

                node = next(node for node in graph['nodes']
                            if node['id'] == node_id)

            except StopIteration:
                node = None

        if node is None:
            assert expected_node is None, \
                   'No node found under %s (but expected %s)' % \
                   (path, expected_node)
        else:
            assert node['name'] == expected_node, \
                   'Found node %s under %s (but expected %s)' % \
                   (node['name'], path, expected_node)

index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')

class QMPTestCase(unittest.TestCase):
    '''Abstract base class for QMP test cases'''

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Many users of this class set a VM property we rely on heavily
        # in the methods below.
        self.vm = None

    def dictpath(self, d, path):
        '''Traverse a path in a nested dict'''
        for component in path.split('/'):
            m = index_re.match(component)
            if m:
                component, idx = m.groups()
                idx = int(idx)

            if not isinstance(d, dict) or component not in d:
                self.fail(f'failed path traversal for "{path}" in "{d}"')
            d = d[component]

            if m:
                if not isinstance(d, list):
                    self.fail(f'path component "{component}" in "{path}" '
                              f'is not a list in "{d}"')
                try:
                    d = d[idx]
                except IndexError:
                    self.fail(f'invalid index "{idx}" in path "{path}" '
                              f'in "{d}"')
        return d

    def assert_qmp_absent(self, d, path):
        try:
            result = self.dictpath(d, path)
        except AssertionError:
            return
        self.fail('path "%s" has value "%s"' % (path, str(result)))

    def assert_qmp(self, d, path, value):
        '''Assert that the value for a specific path in a QMP dict
           matches.  When given a list of values, assert that any of
           them matches.'''

        result = self.dictpath(d, path)

        # [] makes no sense as a list of valid values, so treat it as
        # an actual single value.
        if isinstance(value, list) and value != []:
            for v in value:
                if result == v:
                    return
            self.fail('no match for "%s" in %s' % (str(result), str(value)))
        else:
            self.assertEqual(result, value,
                             '"%s" is "%s", expected "%s"'
                             % (path, str(result), str(value)))

    def assert_no_active_block_jobs(self):
        result = self.vm.qmp('query-block-jobs')
        self.assert_qmp(result, 'return', [])

    def assert_has_block_node(self, node_name=None, file_name=None):
        """Issue a query-named-block-nodes and assert node_name and/or
        file_name is present in the result"""
        def check_equal_or_none(a, b):
            return a is None or b is None or a == b
        assert node_name or file_name
        result = self.vm.qmp('query-named-block-nodes')
        for x in result["return"]:
            if check_equal_or_none(x.get("node-name"), node_name) and \
                    check_equal_or_none(x.get("file"), file_name):
                return
        self.fail("Cannot find %s %s in result:\n%s" %
                  (node_name, file_name, result))

    def assert_json_filename_equal(self, json_filename, reference):
        '''Asserts that the given filename is a json: filename and that its
           content is equal to the given reference object'''
        self.assertEqual(json_filename[:5], 'json:')
        self.assertEqual(
            self.vm.flatten_qmp_object(json.loads(json_filename[5:])),
            self.vm.flatten_qmp_object(reference)
        )

    def cancel_and_wait(self, drive='drive0', force=False,
                        resume=False, wait=60.0):
        '''Cancel a block job and wait for it to finish, returning the event'''
        self.vm.cmd('block-job-cancel', device=drive, force=force)

        if resume:
            self.vm.resume_drive(drive)

        cancelled = False
        result = None
        while not cancelled:
            for event in self.vm.get_qmp_events(wait=wait):
                if event['event'] == 'BLOCK_JOB_COMPLETED' or \
                   event['event'] == 'BLOCK_JOB_CANCELLED':
                    self.assert_qmp(event, 'data/device', drive)
                    result = event
                    cancelled = True
                elif event['event'] == 'JOB_STATUS_CHANGE':
                    self.assert_qmp(event, 'data/id', drive)


        self.assert_no_active_block_jobs()
        return result

    def wait_until_completed(self, drive='drive0', check_offset=True,
                             wait=60.0, error=None):
        '''Wait for a block job to finish, returning the event'''
        while True:
            for event in self.vm.get_qmp_events(wait=wait):
                if event['event'] == 'BLOCK_JOB_COMPLETED':
                    self.assert_qmp(event, 'data/device', drive)
                    if error is None:
                        self.assert_qmp_absent(event, 'data/error')
                        if check_offset:
                            self.assert_qmp(event, 'data/offset',
                                            event['data']['len'])
                    else:
                        self.assert_qmp(event, 'data/error', error)
                    self.assert_no_active_block_jobs()
                    return event
                if event['event'] == 'JOB_STATUS_CHANGE':
                    self.assert_qmp(event, 'data/id', drive)

    def wait_ready(self, drive='drive0'):
        """Wait until a BLOCK_JOB_READY event, and return the event."""
        return self.vm.events_wait([
            ('BLOCK_JOB_READY',
             {'data': {'type': 'mirror', 'device': drive}}),
            ('BLOCK_JOB_READY',
             {'data': {'type': 'commit', 'device': drive}})
        ])

    def wait_ready_and_cancel(self, drive='drive0'):
        self.wait_ready(drive=drive)
        event = self.cancel_and_wait(drive=drive)
        self.assertEqual(event['event'], 'BLOCK_JOB_COMPLETED')
        self.assert_qmp(event, 'data/type', 'mirror')
        self.assert_qmp(event, 'data/offset', event['data']['len'])

    def complete_and_wait(self, drive='drive0', wait_ready=True,
                          completion_error=None):
        '''Complete a block job and wait for it to finish'''
        if wait_ready:
            self.wait_ready(drive=drive)

        self.vm.cmd('block-job-complete', device=drive)

        event = self.wait_until_completed(drive=drive, error=completion_error)
        self.assertTrue(event['data']['type'] in ['mirror', 'commit'])

    def pause_wait(self, job_id='job0'):
        with Timeout(3, "Timeout waiting for job to pause"):
            while True:
                result = self.vm.qmp('query-block-jobs')
                found = False
                for job in result['return']:
                    if job['device'] == job_id:
                        found = True
                        if job['paused'] and not job['busy']:
                            return job
                        break
                assert found

    def pause_job(self, job_id='job0', wait=True):
        self.vm.cmd('block-job-pause', device=job_id)
        if wait:
            self.pause_wait(job_id)

    def case_skip(self, reason):
        '''Skip this test case'''
        case_notrun(reason)
        self.skipTest(reason)


def notrun(reason):
    '''Skip this test suite'''
    # Each test in qemu-iotests has a number ("seq")
    seq = os.path.basename(sys.argv[0])

    with open('%s/%s.notrun' % (test_dir, seq), 'w', encoding='utf-8') \
            as outfile:
        outfile.write(reason + '\n')
    logger.warning("%s not run: %s", seq, reason)
    sys.exit(0)

def case_notrun(reason):
    '''Mark this test case as not having been run (without actually
    skipping it, that is left to the caller).  See
    QMPTestCase.case_skip() for a variant that actually skips the
    current test case.'''

    # Each test in qemu-iotests has a number ("seq")
    seq = os.path.basename(sys.argv[0])

    with open('%s/%s.casenotrun' % (test_dir, seq), 'a', encoding='utf-8') \
            as outfile:
        outfile.write('    [case not run] ' + reason + '\n')

def _verify_image_format(supported_fmts: Sequence[str] = (),
                         unsupported_fmts: Sequence[str] = ()) -> None:
    if 'generic' in supported_fmts and \
            os.environ.get('IMGFMT_GENERIC', 'true') == 'true':
        # similar to
        #   _supported_fmt generic
        # for bash tests
        supported_fmts = ()

    not_sup = supported_fmts and (imgfmt not in supported_fmts)
    if not_sup or (imgfmt in unsupported_fmts):
        notrun('not suitable for this image format: %s' % imgfmt)

    if imgfmt == 'luks':
        verify_working_luks()

def _verify_protocol(supported: Sequence[str] = (),
                     unsupported: Sequence[str] = ()) -> None:
    assert not (supported and unsupported)

    if 'generic' in supported:
        return

    not_sup = supported and (imgproto not in supported)
    if not_sup or (imgproto in unsupported):
        notrun('not suitable for this protocol: %s' % imgproto)

def _verify_platform(supported: Sequence[str] = (),
                     unsupported: Sequence[str] = ()) -> None:
    if any((sys.platform.startswith(x) for x in unsupported)):
        notrun('not suitable for this OS: %s' % sys.platform)

    if supported:
        if not any((sys.platform.startswith(x) for x in supported)):
            notrun('not suitable for this OS: %s' % sys.platform)

def _verify_cache_mode(supported_cache_modes: Sequence[str] = ()) -> None:
    if supported_cache_modes and (cachemode not in supported_cache_modes):
        notrun('not suitable for this cache mode: %s' % cachemode)

def _verify_aio_mode(supported_aio_modes: Sequence[str] = ()) -> None:
    if supported_aio_modes and (aiomode not in supported_aio_modes):
        notrun('not suitable for this aio mode: %s' % aiomode)

def _verify_formats(required_formats: Sequence[str] = ()) -> None:
    usf_list = list(set(required_formats) - set(supported_formats()))
    if usf_list:
        notrun(f'formats {usf_list} are not whitelisted')


def _verify_virtio_blk() -> None:
    out = qemu_pipe('-M', 'none', '-device', 'help')
    if 'virtio-blk' not in out:
        notrun('Missing virtio-blk in QEMU binary')

def verify_virtio_scsi_pci_or_ccw() -> None:
    out = qemu_pipe('-M', 'none', '-device', 'help')
    if 'virtio-scsi-pci' not in out and 'virtio-scsi-ccw' not in out:
        notrun('Missing virtio-scsi-pci or virtio-scsi-ccw in QEMU binary')


def _verify_imgopts(unsupported: Sequence[str] = ()) -> None:
    imgopts = os.environ.get('IMGOPTS')
    # One of usage examples for IMGOPTS is "data_file=$TEST_IMG.ext_data_file"
    # but it supported only for bash tests. We don't have a concept of global
    # TEST_IMG in iotests.py, not saying about somehow parsing $variables.
    # So, for simplicity let's just not support any IMGOPTS with '$' inside.
    unsup = list(unsupported) + ['$']
    if imgopts and any(x in imgopts for x in unsup):
        notrun(f'not suitable for this imgopts: {imgopts}')


def supports_quorum() -> bool:
    return 'quorum' in qemu_img('--help').stdout

def verify_quorum():
    '''Skip test suite if quorum support is not available'''
    if not supports_quorum():
        notrun('quorum support missing')

def has_working_luks() -> Tuple[bool, str]:
    """
    Check whether our LUKS driver can actually create images
    (this extends to LUKS encryption for qcow2).

    If not, return the reason why.
    """

    img_file = f'{test_dir}/luks-test.luks'
    res = qemu_img('create', '-f', 'luks',
                   '--object', luks_default_secret_object,
                   '-o', luks_default_key_secret_opt,
                   '-o', 'iter-time=10',
                   img_file, '1G',
                   check=False)
    try:
        os.remove(img_file)
    except OSError:
        pass

    if res.returncode:
        reason = res.stdout
        for line in res.stdout.splitlines():
            if img_file + ':' in line:
                reason = line.split(img_file + ':', 1)[1].strip()
                break

        return (False, reason)
    else:
        return (True, '')

def verify_working_luks():
    """
    Skip test suite if LUKS does not work
    """
    (working, reason) = has_working_luks()
    if not working:
        notrun(reason)

def supports_qcow2_zstd_compression() -> bool:
    img_file = f'{test_dir}/qcow2-zstd-test.qcow2'
    res = qemu_img('create', '-f', 'qcow2', '-o', 'compression_type=zstd',
                   img_file, '0',
                   check=False)
    try:
        os.remove(img_file)
    except OSError:
        pass

    if res.returncode == 1 and \
            "'compression-type' does not accept value 'zstd'" in res.stdout:
        return False
    else:
        return True

def verify_qcow2_zstd_compression():
    if not supports_qcow2_zstd_compression():
        notrun('zstd compression not supported')

def qemu_pipe(*args: str) -> str:
    """
    Run qemu with an option to print something and exit (e.g. a help option).

    :return: QEMU's stdout output.
    """
    full_args = [qemu_prog] + qemu_opts + list(args)
    output, _ = qemu_tool_pipe_and_status('qemu', full_args)
    return output

def supported_formats(read_only=False):
    '''Set 'read_only' to True to check ro-whitelist
       Otherwise, rw-whitelist is checked'''

    if not hasattr(supported_formats, "formats"):
        supported_formats.formats = {}

    if read_only not in supported_formats.formats:
        format_message = qemu_pipe("-drive", "format=help")
        line = 1 if read_only else 0
        supported_formats.formats[read_only] = \
            format_message.splitlines()[line].split(":")[1].split()

    return supported_formats.formats[read_only]

def skip_if_unsupported(required_formats=(), read_only=False):
    '''Skip Test Decorator
       Runs the test if all the required formats are whitelisted'''
    def skip_test_decorator(func):
        def func_wrapper(test_case: QMPTestCase, *args: List[Any],
                         **kwargs: Dict[str, Any]) -> None:
            if callable(required_formats):
                fmts = required_formats(test_case)
            else:
                fmts = required_formats

            usf_list = list(set(fmts) - set(supported_formats(read_only)))
            if usf_list:
                msg = f'{test_case}: formats {usf_list} are not whitelisted'
                test_case.case_skip(msg)
            else:
                func(test_case, *args, **kwargs)
        return func_wrapper
    return skip_test_decorator

def skip_for_formats(formats: Sequence[str] = ()) \
    -> Callable[[Callable[[QMPTestCase, List[Any], Dict[str, Any]], None]],
                Callable[[QMPTestCase, List[Any], Dict[str, Any]], None]]:
    '''Skip Test Decorator
       Skips the test for the given formats'''
    def skip_test_decorator(func):
        def func_wrapper(test_case: QMPTestCase, *args: List[Any],
                         **kwargs: Dict[str, Any]) -> None:
            if imgfmt in formats:
                msg = f'{test_case}: Skipped for format {imgfmt}'
                test_case.case_skip(msg)
            else:
                func(test_case, *args, **kwargs)
        return func_wrapper
    return skip_test_decorator

def skip_if_user_is_root(func):
    '''Skip Test Decorator
       Runs the test only without root permissions'''
    def func_wrapper(*args, **kwargs):
        if os.getuid() == 0:
            case_notrun('{}: cannot be run as root'.format(args[0]))
            return None
        else:
            return func(*args, **kwargs)
    return func_wrapper

# We need to filter out the time taken from the output so that
# qemu-iotest can reliably diff the results against master output,
# and hide skipped tests from the reference output.

class ReproducibleTestResult(unittest.TextTestResult):
    def addSkip(self, test, reason):
        # Same as TextTestResult, but print dot instead of "s"
        unittest.TestResult.addSkip(self, test, reason)
        if self.showAll:
            self.stream.writeln("skipped {0!r}".format(reason))
        elif self.dots:
            self.stream.write(".")
            self.stream.flush()

class ReproducibleStreamWrapper:
    def __init__(self, stream: TextIO):
        self.stream = stream

    def __getattr__(self, attr):
        if attr in ('stream', '__getstate__'):
            raise AttributeError(attr)
        return getattr(self.stream, attr)

    def write(self, arg=None):
        arg = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', arg)
        arg = re.sub(r' \(skipped=\d+\)', r'', arg)
        self.stream.write(arg)

class ReproducibleTestRunner(unittest.TextTestRunner):
    def __init__(self, stream: Optional[TextIO] = None,
                 resultclass: Type[unittest.TestResult] =
                 ReproducibleTestResult,
                 **kwargs: Any) -> None:
        rstream = ReproducibleStreamWrapper(stream or sys.stdout)
        super().__init__(stream=rstream,           # type: ignore
                         descriptions=True,
                         resultclass=resultclass,
                         **kwargs)

def execute_unittest(argv: List[str], debug: bool = False) -> None:
    """Executes unittests within the calling module."""

    # Some tests have warnings, especially ResourceWarnings for unclosed
    # files and sockets.  Ignore them for now to ensure reproducibility of
    # the test output.
    unittest.main(argv=argv,
                  testRunner=ReproducibleTestRunner,
                  verbosity=2 if debug else 1,
                  warnings=None if sys.warnoptions else 'ignore')

def execute_setup_common(supported_fmts: Sequence[str] = (),
                         supported_platforms: Sequence[str] = (),
                         supported_cache_modes: Sequence[str] = (),
                         supported_aio_modes: Sequence[str] = (),
                         unsupported_fmts: Sequence[str] = (),
                         supported_protocols: Sequence[str] = (),
                         unsupported_protocols: Sequence[str] = (),
                         required_fmts: Sequence[str] = (),
                         unsupported_imgopts: Sequence[str] = ()) -> bool:
    """
    Perform necessary setup for either script-style or unittest-style tests.

    :return: Bool; Whether or not debug mode has been requested via the CLI.
    """
    # Note: Python 3.6 and pylint do not like 'Collection' so use 'Sequence'.

    debug = '-d' in sys.argv
    if debug:
        sys.argv.remove('-d')
    logging.basicConfig(level=(logging.DEBUG if debug else logging.WARN))

    _verify_image_format(supported_fmts, unsupported_fmts)
    _verify_protocol(supported_protocols, unsupported_protocols)
    _verify_platform(supported=supported_platforms)
    _verify_cache_mode(supported_cache_modes)
    _verify_aio_mode(supported_aio_modes)
    _verify_formats(required_fmts)
    _verify_virtio_blk()
    _verify_imgopts(unsupported_imgopts)

    return debug

def execute_test(*args, test_function=None, **kwargs):
    """Run either unittest or script-style tests."""

    debug = execute_setup_common(*args, **kwargs)
    if not test_function:
        execute_unittest(sys.argv, debug)
    else:
        test_function()

def activate_logging():
    """Activate iotests.log() output to stdout for script-style tests."""
    handler = logging.StreamHandler(stream=sys.stdout)
    formatter = logging.Formatter('%(message)s')
    handler.setFormatter(formatter)
    test_logger.addHandler(handler)
    test_logger.setLevel(logging.INFO)
    test_logger.propagate = False

# This is called from script-style iotests without a single point of entry
def script_initialize(*args, **kwargs):
    """Initialize script-style tests without running any tests."""
    activate_logging()
    execute_setup_common(*args, **kwargs)

# This is called from script-style iotests with a single point of entry
def script_main(test_function, *args, **kwargs):
    """Run script-style tests outside of the unittest framework"""
    activate_logging()
    execute_test(*args, test_function=test_function, **kwargs)

# This is called from unittest style iotests
def main(*args, **kwargs):
    """Run tests using the unittest framework"""
    execute_test(*args, **kwargs)
