#!/usr/bin/env python3
# group: rw auto backing
#
# Tests for image mirroring.
#
# Copyright (C) 2012 Red Hat, Inc.
#
# 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 time
import os
import re
import json
import iotests
from iotests import qemu_img, qemu_img_map, qemu_io

backing_img = os.path.join(iotests.test_dir, 'backing.img')
target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img')
test_img = os.path.join(iotests.test_dir, 'test.img')
target_img = os.path.join(iotests.test_dir, 'target.img')

quorum_img1 = os.path.join(iotests.test_dir, 'quorum1.img')
quorum_img2 = os.path.join(iotests.test_dir, 'quorum2.img')
quorum_img3 = os.path.join(iotests.test_dir, 'quorum3.img')
quorum_repair_img = os.path.join(iotests.test_dir, 'quorum_repair.img')
quorum_snapshot_file = os.path.join(iotests.test_dir, 'quorum_snapshot.img')

nbd_sock_path = os.path.join(iotests.sock_dir, 'nbd.sock')

class TestSingleDrive(iotests.QMPTestCase):
    image_len = 1 * 1024 * 1024 # MB
    qmp_cmd = 'drive-mirror'
    qmp_target = target_img

    def setUp(self):
        iotests.create_image(backing_img, self.image_len)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % backing_img, '-F', 'raw', test_img)
        self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=base")
        if iotests.qemu_default_machine == 'pc':
            self.vm.add_drive(None, 'media=cdrom', 'ide')
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(backing_img)
        try:
            os.remove(target_img)
        except OSError:
            pass

    def test_complete(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    target=self.qmp_target)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_cancel(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    target=self.qmp_target)

        self.cancel_and_wait(force=True)
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', test_img)

    def test_cancel_after_ready(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    target=self.qmp_target)

        self.wait_ready_and_cancel()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_pause(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    target=self.qmp_target)

        self.pause_job('drive0')

        result = self.vm.qmp('query-block-jobs')
        offset = self.dictpath(result, 'return[0]/offset')

        time.sleep(0.5)
        result = self.vm.qmp('query-block-jobs')
        self.assert_qmp(result, 'return[0]/offset', offset)

        self.vm.cmd('block-job-resume', device='drive0')

        self.complete_and_wait()
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_small_buffer(self):
        self.assert_no_active_block_jobs()

        # A small buffer is rounded up automatically
        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    buf_size=4096, target=self.qmp_target)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_small_buffer2(self):
        self.assert_no_active_block_jobs()

        qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,size=%d'
                        % (self.image_len, self.image_len), target_img)
        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    buf_size=65536, mode='existing', target=self.qmp_target)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_large_cluster(self):
        self.assert_no_active_block_jobs()

        qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
                        % (self.image_len, backing_img),
                 '-F', 'raw', target_img)
        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    mode='existing', target=self.qmp_target)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    # Tests that the insertion of the mirror_top filter node doesn't make a
    # difference to query-block
    def test_implicit_node(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd(self.qmp_cmd, device='drive0', sync='full',
                    target=self.qmp_target)

        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
        self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt)
        self.assert_qmp(result, 'return[0]/inserted/backing_file', backing_img)
        self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 1)
        self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img)
        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', backing_img)

        result = self.vm.qmp('query-blockstats')
        self.assert_qmp(result, 'return[0]/node-name', 'top')
        self.assert_qmp(result, 'return[0]/backing/node-name', 'base')

        self.cancel_and_wait(force=True)
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
        self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt)
        self.assert_qmp(result, 'return[0]/inserted/backing_file', backing_img)
        self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 1)
        self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img)
        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', backing_img)

        result = self.vm.qmp('query-blockstats')
        self.assert_qmp(result, 'return[0]/node-name', 'top')
        self.assert_qmp(result, 'return[0]/backing/node-name', 'base')

    def test_medium_not_found(self):
        if iotests.qemu_default_machine != 'pc':
            return

        result = self.vm.qmp(self.qmp_cmd, device='ide1-cd0', sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_image_not_found(self):
        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             mode='existing', target=self.qmp_target)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_device_not_found(self):
        result = self.vm.qmp(self.qmp_cmd, device='nonexistent', sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'error/class', 'GenericError')

class TestSingleBlockdev(TestSingleDrive):
    qmp_cmd = 'blockdev-mirror'
    qmp_target = 'node1'

    def setUp(self):
        TestSingleDrive.setUp(self)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % backing_img, '-F', 'raw', target_img)
        args = {'driver': iotests.imgfmt,
                'node-name': self.qmp_target,
                'file': { 'filename': target_img, 'driver': 'file' } }
        self.vm.cmd("blockdev-add", args)

    def test_mirror_to_self(self):
        result = self.vm.qmp(self.qmp_cmd, job_id='job0',
                             device=self.qmp_target, sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def do_test_resize(self, device, node):
        def pre_finalize():
            if device:
                result = self.vm.qmp('block_resize', device=device, size=65536)
                self.assert_qmp(result, 'error/class', 'GenericError')

            result = self.vm.qmp('block_resize', node_name=node, size=65536)
            self.assert_qmp(result, 'error/class', 'GenericError')

        self.vm.cmd(self.qmp_cmd, job_id='job0', device='drive0',
                    sync='full', target=self.qmp_target,
                    auto_finalize=False, auto_dismiss=False)

        result = self.vm.run_job('job0', auto_finalize=False,
                                 pre_finalize=pre_finalize)
        self.assertEqual(result, None)

    def test_source_resize(self):
        self.do_test_resize('drive0', 'top')

    def test_target_resize(self):
        self.do_test_resize(None, self.qmp_target)

    def do_test_target_size(self, size):
        self.vm.cmd('block_resize', node_name=self.qmp_target,
                    size=size)

        self.vm.cmd(self.qmp_cmd, job_id='job0',
                    device='drive0', sync='full', auto_dismiss=False,
                    target=self.qmp_target)

        result = self.vm.run_job('job0')
        self.assertEqual(result, 'Source and target image have different sizes')

    # qed does not support shrinking
    @iotests.skip_for_formats(('qed'))
    def test_small_target(self):
        self.do_test_target_size(self.image_len // 2)

    def test_large_target(self):
        self.do_test_target_size(self.image_len * 2)

    test_large_cluster = None
    test_image_not_found = None
    test_small_buffer2 = None

class TestSingleDriveZeroLength(TestSingleDrive):
    image_len = 0
    test_small_buffer2 = None
    test_large_cluster = None

class TestSingleBlockdevZeroLength(TestSingleBlockdev):
    image_len = 0
    test_small_target = None
    test_large_target = None

class TestSingleDriveUnalignedLength(TestSingleDrive):
    image_len = 1025 * 1024
    test_small_buffer2 = None
    test_large_cluster = None

class TestSingleBlockdevUnalignedLength(TestSingleBlockdev):
    image_len = 1025 * 1024

class TestMirrorNoBacking(iotests.QMPTestCase):
    image_len = 2 * 1024 * 1024 # MB

    def setUp(self):
        iotests.create_image(backing_img, TestMirrorNoBacking.image_len)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % backing_img, '-F', 'raw', test_img)
        self.vm = iotests.VM().add_drive(test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(backing_img)
        try:
            os.remove(target_backing_img)
        except:
            pass
        os.remove(target_img)

    def test_complete(self):
        self.assert_no_active_block_jobs()

        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % backing_img, '-F', 'raw', target_img)
        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    mode='existing', target=target_img)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_cancel(self):
        self.assert_no_active_block_jobs()

        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % backing_img, '-F', 'raw', target_img)
        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    mode='existing', target=target_img)

        self.wait_ready_and_cancel()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_large_cluster(self):
        self.assert_no_active_block_jobs()

        # qemu-img create fails if the image is not there
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'size=%d'
                        %(TestMirrorNoBacking.image_len), target_backing_img)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
                        % (TestMirrorNoBacking.image_len, target_backing_img),
                 '-F', iotests.imgfmt, target_img)

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    mode='existing', target=target_img)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

class TestMirrorResized(iotests.QMPTestCase):
    backing_len = 1 * 1024 * 1024 # MB
    image_len = 2 * 1024 * 1024 # MB

    def setUp(self):
        iotests.create_image(backing_img, TestMirrorResized.backing_len)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % backing_img, '-F', 'raw', test_img)
        qemu_img('resize', test_img, '2M')
        self.vm = iotests.VM().add_drive(test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(backing_img)
        try:
            os.remove(target_img)
        except OSError:
            pass

    def test_complete_top(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='top',
                    target=target_img)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_complete_full(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    target=target_img)

        self.complete_and_wait()
        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', target_img)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

class TestReadErrors(iotests.QMPTestCase):
    image_len = 2 * 1024 * 1024 # MB

    # this should be a multiple of twice the default granularity
    # so that we hit this offset first in state 1
    MIRROR_GRANULARITY = 1024 * 1024

    def create_blkdebug_file(self, name, event, errno):
        file = open(name, 'w')
        file.write('''
[inject-error]
state = "1"
event = "%s"
errno = "%d"
immediately = "off"
once = "on"
sector = "%d"

[set-state]
state = "1"
event = "%s"
new_state = "2"

[set-state]
state = "2"
event = "%s"
new_state = "1"
''' % (event, errno, self.MIRROR_GRANULARITY // 512, event, event))
        file.close()

    def setUp(self):
        self.blkdebug_file = backing_img + ".blkdebug"
        iotests.create_image(backing_img, TestReadErrors.image_len)
        self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw'
                       % (self.blkdebug_file, backing_img),
                 test_img)
        # Write something for tests that use sync='top'
        qemu_io('-c', 'write %d 512' % (self.MIRROR_GRANULARITY + 65536),
                        test_img)
        self.vm = iotests.VM().add_drive(test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(target_img)
        os.remove(backing_img)
        os.remove(self.blkdebug_file)

    def test_report_read(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    target=target_img)

        completed = False
        error = False
        while not completed:
            for event in self.vm.get_qmp_events(wait=True):
                if event['event'] == 'BLOCK_JOB_ERROR':
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.assert_qmp(event, 'data/operation', 'read')
                    error = True
                elif event['event'] == 'BLOCK_JOB_READY':
                    self.assertTrue(False, 'job completed unexpectedly')
                elif event['event'] == 'BLOCK_JOB_COMPLETED':
                    self.assertTrue(error, 'job completed unexpectedly')
                    self.assert_qmp(event, 'data/type', 'mirror')
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.assert_qmp(event, 'data/error', 'Input/output error')
                    completed = True
                elif event['event'] == 'JOB_STATUS_CHANGE':
                    self.assert_qmp(event, 'data/id', 'drive0')

        self.assert_no_active_block_jobs()

    def test_ignore_read(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    target=target_img, on_source_error='ignore')

        event = self.vm.get_qmp_event(wait=True)
        while event['event'] == 'JOB_STATUS_CHANGE':
            self.assert_qmp(event, 'data/id', 'drive0')
            event = self.vm.get_qmp_event(wait=True)

        self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
        self.assert_qmp(event, 'data/device', 'drive0')
        self.assert_qmp(event, 'data/operation', 'read')
        result = self.vm.qmp('query-block-jobs')
        self.assertIn(result['return'][0]['status'], ['running', 'ready'])
        self.complete_and_wait()

    def test_large_cluster(self):
        self.assert_no_active_block_jobs()

        # Test COW into the target image.  The first half of the
        # cluster at MIRROR_GRANULARITY has to be copied from
        # backing_img, even though sync='top'.
        qemu_img('create', '-f', iotests.imgfmt,
                 '-ocluster_size=131072,backing_file=%s' %(backing_img),
                 '-F', 'raw', target_img)
        self.vm.cmd('drive-mirror', device='drive0', sync='top',
                    on_source_error='ignore',
                    mode='existing', target=target_img)

        event = self.vm.get_qmp_event(wait=True)
        while event['event'] == 'JOB_STATUS_CHANGE':
            self.assert_qmp(event, 'data/id', 'drive0')
            event = self.vm.get_qmp_event(wait=True)

        self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
        self.assert_qmp(event, 'data/device', 'drive0')
        self.assert_qmp(event, 'data/operation', 'read')
        result = self.vm.qmp('query-block-jobs')
        self.assertIn(result['return'][0]['status'], ['running', 'ready'])
        self.complete_and_wait()
        self.vm.shutdown()

        # Detach blkdebug to compare images successfully
        qemu_img('rebase', '-f', iotests.imgfmt, '-u', '-b', backing_img,
                 '-F', 'raw', test_img)
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_stop_read(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    target=target_img, on_source_error='stop')

        error = False
        ready = False
        while not ready:
            for event in self.vm.get_qmp_events(wait=True):
                if event['event'] == 'BLOCK_JOB_ERROR':
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.assert_qmp(event, 'data/operation', 'read')

                    if self.vm.qmp('query-block-jobs')['return'][0]['status'] != 'paused':
                        self.vm.events_wait([(
                            'JOB_STATUS_CHANGE',
                            {'data': {'id': 'drive0', 'status': 'paused'}}
                        )])

                    result = self.vm.qmp('query-block-jobs')
                    self.assert_qmp(result, 'return[0]/status', 'paused')
                    self.assert_qmp(result, 'return[0]/io-status', 'failed')

                    self.vm.cmd('block-job-resume', device='drive0')
                    error = True
                elif event['event'] == 'BLOCK_JOB_READY':
                    self.assertTrue(error, 'job completed unexpectedly')
                    self.assert_qmp(event, 'data/device', 'drive0')
                    ready = True

        result = self.vm.qmp('query-block-jobs')
        self.assert_qmp(result, 'return[0]/status', 'ready')
        self.assert_qmp(result, 'return[0]/io-status', 'ok')

        self.complete_and_wait(wait_ready=False)
        self.assert_no_active_block_jobs()

class TestWriteErrors(iotests.QMPTestCase):
    image_len = 2 * 1024 * 1024 # MB

    # this should be a multiple of twice the default granularity
    # so that we hit this offset first in state 1
    MIRROR_GRANULARITY = 1024 * 1024

    def create_blkdebug_file(self, name, event, errno):
        file = open(name, 'w')
        file.write('''
[inject-error]
state = "1"
event = "%s"
errno = "%d"
immediately = "off"
once = "on"
sector = "%d"

[set-state]
state = "1"
event = "%s"
new_state = "2"

[set-state]
state = "2"
event = "%s"
new_state = "1"
''' % (event, errno, self.MIRROR_GRANULARITY // 512, event, event))
        file.close()

    def setUp(self):
        self.blkdebug_file = target_img + ".blkdebug"
        iotests.create_image(backing_img, TestWriteErrors.image_len)
        self.create_blkdebug_file(self.blkdebug_file, "write_aio", 5)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-obacking_file=%s' %(backing_img), '-F', 'raw', test_img)
        self.vm = iotests.VM().add_drive(test_img)
        self.target_img = 'blkdebug:%s:%s' % (self.blkdebug_file, target_img)
        qemu_img('create', '-f', iotests.imgfmt, '-osize=%d' %(TestWriteErrors.image_len), target_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(target_img)
        os.remove(backing_img)
        os.remove(self.blkdebug_file)

    def test_report_write(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    mode='existing', target=self.target_img)

        completed = False
        error = False
        while not completed:
            for event in self.vm.get_qmp_events(wait=True):
                if event['event'] == 'BLOCK_JOB_ERROR':
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.assert_qmp(event, 'data/operation', 'write')
                    error = True
                elif event['event'] == 'BLOCK_JOB_READY':
                    self.assertTrue(False, 'job completed unexpectedly')
                elif event['event'] == 'BLOCK_JOB_COMPLETED':
                    self.assertTrue(error, 'job completed unexpectedly')
                    self.assert_qmp(event, 'data/type', 'mirror')
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.assert_qmp(event, 'data/error', 'Input/output error')
                    completed = True

        self.assert_no_active_block_jobs()

    def test_ignore_write(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    mode='existing', target=self.target_img,
                    on_target_error='ignore')

        event = self.vm.event_wait(name='BLOCK_JOB_ERROR')
        self.assertEqual(event['event'], 'BLOCK_JOB_ERROR')
        self.assert_qmp(event, 'data/device', 'drive0')
        self.assert_qmp(event, 'data/operation', 'write')
        result = self.vm.qmp('query-block-jobs')
        self.assertIn(result['return'][0]['status'], ['running', 'ready'])
        self.complete_and_wait()

    def test_stop_write(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    mode='existing', target=self.target_img,
                    on_target_error='stop')

        error = False
        ready = False
        while not ready:
            for event in self.vm.get_qmp_events(wait=True):
                if event['event'] == 'BLOCK_JOB_ERROR':
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.assert_qmp(event, 'data/operation', 'write')

                    if self.vm.qmp('query-block-jobs')['return'][0]['status'] != 'paused':
                        self.vm.events_wait([(
                            'JOB_STATUS_CHANGE',
                            {'data': {'id': 'drive0', 'status': 'paused'}}
                        )])

                    result = self.vm.qmp('query-block-jobs')
                    self.assert_qmp(result, 'return[0]/status', 'paused')
                    self.assert_qmp(result, 'return[0]/io-status', 'failed')

                    self.vm.cmd('block-job-resume', device='drive0')

                    result = self.vm.qmp('query-block-jobs')
                    self.assertIn(result['return'][0]['status'], ['running', 'ready'])
                    self.assert_qmp(result, 'return[0]/io-status', 'ok')
                    error = True
                elif event['event'] == 'BLOCK_JOB_READY':
                    self.assertTrue(error, 'job completed unexpectedly')
                    self.assert_qmp(event, 'data/device', 'drive0')
                    ready = True

        self.complete_and_wait(wait_ready=False)
        self.assert_no_active_block_jobs()

class TestSetSpeed(iotests.QMPTestCase):
    image_len = 80 * 1024 * 1024 # MB

    def setUp(self):
        qemu_img('create', backing_img, str(TestSetSpeed.image_len))
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % backing_img, '-F', 'raw', test_img)
        self.vm = iotests.VM().add_drive(test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(backing_img)
        os.remove(target_img)

    def test_set_speed(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    target=target_img)

        # Default speed is 0
        result = self.vm.qmp('query-block-jobs')
        self.assert_qmp(result, 'return[0]/device', 'drive0')
        self.assert_qmp(result, 'return[0]/speed', 0)

        self.vm.cmd('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)

        # Ensure the speed we set was accepted
        result = self.vm.qmp('query-block-jobs')
        self.assert_qmp(result, 'return[0]/device', 'drive0')
        self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)

        self.wait_ready_and_cancel()

        # Check setting speed in drive-mirror works
        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    target=target_img, speed=4*1024*1024)

        result = self.vm.qmp('query-block-jobs')
        self.assert_qmp(result, 'return[0]/device', 'drive0')
        self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)

        self.wait_ready_and_cancel()

    def test_set_speed_invalid(self):
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img, speed=-1)
        self.assert_qmp(result, 'error/class', 'GenericError')

        self.assert_no_active_block_jobs()

        self.vm.cmd('drive-mirror', device='drive0', sync='full',
                    target=target_img)

        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
        self.assert_qmp(result, 'error/class', 'GenericError')

        self.wait_ready_and_cancel()

class TestUnbackedSource(iotests.QMPTestCase):
    image_len = 2 * 1024 * 1024 # MB

    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, test_img,
                 str(TestUnbackedSource.image_len))
        self.vm = iotests.VM()
        self.vm.launch()
        self.vm.cmd('blockdev-add', node_name='drive0',
                    driver=iotests.imgfmt,
                    file={
                        'driver': 'file',
                        'filename': test_img,
                    })

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(target_img)

    def test_absolute_paths_full(self):
        self.assert_no_active_block_jobs()
        self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
                    sync='full', target=target_img,
                    mode='absolute-paths')
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

    def test_absolute_paths_top(self):
        self.assert_no_active_block_jobs()
        self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
                    sync='top', target=target_img,
                    mode='absolute-paths')
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

    def test_absolute_paths_none(self):
        self.assert_no_active_block_jobs()
        self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
                    sync='none', target=target_img,
                    mode='absolute-paths')
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

    def test_existing_full(self):
        qemu_img('create', '-f', iotests.imgfmt, target_img,
                 str(self.image_len))
        qemu_io('-c', 'write -P 42 0 64k', target_img)

        self.assert_no_active_block_jobs()
        self.vm.cmd('drive-mirror', job_id='drive0', device='drive0',
                    sync='full', target=target_img, mode='existing')
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

        self.vm.cmd('blockdev-del', node_name='drive0')

        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

    def test_blockdev_full(self):
        qemu_img('create', '-f', iotests.imgfmt, target_img,
                 str(self.image_len))
        qemu_io('-c', 'write -P 42 0 64k', target_img)

        self.vm.cmd('blockdev-add', node_name='target',
                    driver=iotests.imgfmt,
                    file={
                        'driver': 'file',
                        'filename': target_img,
                    })

        self.assert_no_active_block_jobs()
        self.vm.cmd('blockdev-mirror', job_id='drive0', device='drive0',
                    sync='full', target='target')
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

        self.vm.cmd('blockdev-del', node_name='drive0')

        self.vm.cmd('blockdev-del', node_name='target')

        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')

class TestGranularity(iotests.QMPTestCase):
    image_len = 10 * 1024 * 1024 # MB

    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, test_img,
                 str(TestGranularity.image_len))
        qemu_io('-c', 'write 0 %d' % (self.image_len),
                test_img)
        self.vm = iotests.VM().add_drive(test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, target_img),
                        'target image does not match source after mirroring')
        os.remove(test_img)
        os.remove(target_img)

    def test_granularity(self):
        self.assert_no_active_block_jobs()
        self.vm.cmd('drive-mirror', device='drive0',
                    sync='full', target=target_img,
                    mode='absolute-paths', granularity=8192)

        event = self.vm.get_qmp_event(wait=60.0)
        while event['event'] == 'JOB_STATUS_CHANGE':
            self.assert_qmp(event, 'data/id', 'drive0')
            event = self.vm.get_qmp_event(wait=60.0)

        # Failures will manifest as COMPLETED/ERROR.
        self.assert_qmp(event, 'event', 'BLOCK_JOB_READY')
        self.complete_and_wait(drive='drive0', wait_ready=False)
        self.assert_no_active_block_jobs()

class TestRepairQuorum(iotests.QMPTestCase):
    """ This class test quorum file repair using drive-mirror.
        It's mostly a fork of TestSingleDrive """
    image_len = 1 * 1024 * 1024 # MB
    IMAGES = [ quorum_img1, quorum_img2, quorum_img3 ]

    @iotests.skip_if_unsupported(['quorum'])
    def setUp(self):
        self.vm = iotests.VM()

        if iotests.qemu_default_machine == 'pc':
            self.vm.add_drive(None, 'media=cdrom', 'ide')

        # Add each individual quorum images
        for i in self.IMAGES:
            qemu_img('create', '-f', iotests.imgfmt, i,
                     str(self.image_len))
            # Assign a node name to each quorum image in order to manipulate
            # them
            opts = "node-name=img%i" % self.IMAGES.index(i)
            opts += ',driver=%s' % iotests.imgfmt
            opts += ',file.driver=file'
            opts += ',file.filename=%s' % i
            self.vm = self.vm.add_blockdev(opts)

        self.vm.launch()

        #assemble the quorum block device from the individual files
        args = { "driver": "quorum", "node-name": "quorum0",
                 "vote-threshold": 2, "children": [ "img0", "img1", "img2" ] }
        self.vm.cmd("blockdev-add", args)


    def tearDown(self):
        self.vm.shutdown()
        for i in self.IMAGES + [ quorum_repair_img, quorum_snapshot_file,
                                 nbd_sock_path ]:
            # Do a try/except because the test may have deleted some images
            try:
                os.remove(i)
            except OSError:
                pass

    def test_complete(self):
        self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
                    sync='full', node_name="repair0", replaces="img1",
                    target=quorum_repair_img, format=iotests.imgfmt)

        self.complete_and_wait(drive="job0")
        self.assert_has_block_node("repair0", quorum_repair_img)
        self.vm.assert_block_path('quorum0', '/children.1', 'repair0')
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
                        'target image does not match source after mirroring')

    def test_cancel(self):
        self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
                    sync='full', node_name="repair0", replaces="img1",
                    target=quorum_repair_img, format=iotests.imgfmt)

        self.cancel_and_wait(drive="job0", force=True)
        # here we check that the last registered quorum file has not been
        # swapped out and unref
        self.assert_has_block_node(None, quorum_img3)

    def test_cancel_after_ready(self):
        self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
                    sync='full', node_name="repair0", replaces="img1",
                    target=quorum_repair_img, format=iotests.imgfmt)

        self.wait_ready_and_cancel(drive="job0")
        # here we check that the last registered quorum file has not been
        # swapped out and unref
        self.assert_has_block_node(None, quorum_img3)
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
                        'target image does not match source after mirroring')

    def test_pause(self):
        self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
                    sync='full', node_name="repair0", replaces="img1",
                    target=quorum_repair_img, format=iotests.imgfmt)

        self.pause_job('job0')

        result = self.vm.qmp('query-block-jobs')
        offset = self.dictpath(result, 'return[0]/offset')

        time.sleep(0.5)
        result = self.vm.qmp('query-block-jobs')
        self.assert_qmp(result, 'return[0]/offset', offset)

        self.vm.cmd('block-job-resume', device='job0')

        self.complete_and_wait(drive="job0")
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
                        'target image does not match source after mirroring')

    def test_medium_not_found(self):
        if iotests.qemu_default_machine != 'pc':
            return

        result = self.vm.qmp('drive-mirror', job_id='job0', device='drive0', # CD-ROM
                             sync='full',
                             node_name='repair0',
                             replaces='img1',
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_image_not_found(self):
        result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                             sync='full', node_name='repair0', replaces='img1',
                             mode='existing', target=quorum_repair_img,
                             format=iotests.imgfmt)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_device_not_found(self):
        result = self.vm.qmp('drive-mirror', job_id='job0',
                             device='nonexistent', sync='full',
                             node_name='repair0',
                             replaces='img1',
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_wrong_sync_mode(self):
        result = self.vm.qmp('drive-mirror', device='quorum0', job_id='job0',
                             node_name='repair0',
                             replaces='img1',
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_no_node_name(self):
        result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                             sync='full', replaces='img1',
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_nonexistent_replaces(self):
        result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                             sync='full', node_name='repair0', replaces='img77',
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_after_a_quorum_snapshot(self):
        self.vm.cmd('blockdev-snapshot-sync', node_name='img1',
                    snapshot_file=quorum_snapshot_file,
                    snapshot_node_name="snap1")

        result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                             sync='full', node_name='repair0', replaces="img1",
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'error/class', 'GenericError')

        self.vm.cmd('drive-mirror', job_id='job0', device='quorum0',
                    sync='full', node_name='repair0', replaces="snap1",
                    target=quorum_repair_img, format=iotests.imgfmt)

        self.complete_and_wait('job0')
        self.assert_has_block_node("repair0", quorum_repair_img)
        self.vm.assert_block_path('quorum0', '/children.1', 'repair0')

    def test_with_other_parent(self):
        """
        Check that we cannot replace a Quorum child when it has other
        parents.
        """
        self.vm.cmd('nbd-server-start',
                    addr={
                        'type': 'unix',
                        'data': {'path': nbd_sock_path}
                    })

        self.vm.cmd('nbd-server-add', device='img1')

        result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0',
                             sync='full', node_name='repair0', replaces='img1',
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'error/desc',
                        "Cannot replace 'img1' by a node mirrored from "
                        "'quorum0', because it cannot be guaranteed that doing "
                        "so would not lead to an abrupt change of visible data")

    def test_with_other_parents_after_mirror_start(self):
        """
        The same as test_with_other_parent(), but add the NBD server
        only when the mirror job is already running.
        """
        self.vm.cmd('nbd-server-start',
                    addr={
                        'type': 'unix',
                        'data': {'path': nbd_sock_path}
                    })

        self.vm.cmd('drive-mirror', job_id='mirror', device='quorum0',
                    sync='full', node_name='repair0', replaces='img1',
                    target=quorum_repair_img, format=iotests.imgfmt)

        self.vm.cmd('nbd-server-add', device='img1')

        # The full error message goes to stderr, we will check it later
        self.complete_and_wait('mirror',
                               completion_error='Operation not permitted')

        # Should not have been replaced
        self.vm.assert_block_path('quorum0', '/children.1', 'img1')

        # Check the full error message now
        self.vm.shutdown()
        log = self.vm.get_log()
        log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log)
        log = re.sub(r'^Formatting.*\n', '', log)
        log = re.sub(r'\n\[I \+\d+\.\d+\] CLOSED\n?$', '', log)
        log = re.sub(r'^%s: ' % os.path.basename(iotests.qemu_prog), '', log)

        self.assertEqual(log,
                         "Can no longer replace 'img1' by 'repair0', because " +
                         "it can no longer be guaranteed that doing so would " +
                         "not lead to an abrupt change of visible data")


# Test mirroring with a source that does not have any parents (not even a
# BlockBackend)
class TestOrphanedSource(iotests.QMPTestCase):
    def setUp(self):
        blk0 = { 'node-name': 'src',
                 'driver': 'null-co' }

        blk1 = { 'node-name': 'dest',
                 'driver': 'null-co' }

        blk2 = { 'node-name': 'dest-ro',
                 'driver': 'null-co',
                 'read-only': 'on' }

        self.vm = iotests.VM()
        self.vm.add_blockdev(self.vm.qmp_to_opts(blk0))
        self.vm.add_blockdev(self.vm.qmp_to_opts(blk1))
        self.vm.add_blockdev(self.vm.qmp_to_opts(blk2))
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()

    def test_no_job_id(self):
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('blockdev-mirror', device='src', sync='full',
                             target='dest')
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_success(self):
        self.assert_no_active_block_jobs()

        self.vm.cmd('blockdev-mirror', job_id='job', device='src',
                    sync='full', target='dest')

        self.complete_and_wait('job')

    def test_failing_permissions(self):
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('blockdev-mirror', device='src', sync='full',
                             target='dest-ro')
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_failing_permission_in_complete(self):
        self.assert_no_active_block_jobs()

        # Unshare consistent-read on the target
        # (The mirror job does not care)
        self.vm.cmd('blockdev-add',
                    driver='blkdebug',
                    node_name='dest-perm',
                    image='dest',
                    unshare_child_perms=['consistent-read'])

        self.vm.cmd('blockdev-mirror', job_id='job', device='src',
                    sync='full', target='dest',
                    filter_node_name='mirror-filter')

        # Require consistent-read on the source
        # (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)
        self.vm.cmd('blockdev-add',
                    driver='blkdebug',
                    node_name='src-perm',
                    image='src',
                    take_child_perms=['consistent-read'])

        # While completing, mirror will attempt to replace src by
        # dest, which must fail because src-perm requires
        # consistent-read but dest-perm does not share it; thus
        # aborting the job when it is supposed to complete
        self.complete_and_wait('job',
                               completion_error='Operation not permitted')

        # Assert that all of our nodes are still there (except for the
        # mirror filter, which should be gone despite the failure)
        nodes = self.vm.qmp('query-named-block-nodes')['return']
        nodes = [node['node-name'] for node in nodes]

        for expect in ('src', 'src-perm', 'dest', 'dest-perm'):
            self.assertTrue(expect in nodes, '%s disappeared' % expect)
        self.assertFalse('mirror-filter' in nodes,
                         'Mirror filter node did not disappear')

# Test cases for @replaces that do not necessarily involve Quorum
class TestReplaces(iotests.QMPTestCase):
    # Each of these test cases needs their own block graph, so do not
    # create any nodes here
    def setUp(self):
        self.vm = iotests.VM()
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        for img in (test_img, target_img):
            try:
                os.remove(img)
            except OSError:
                pass

    @iotests.skip_if_unsupported(['copy-on-read'])
    def test_replace_filter(self):
        """
        Check that we can replace filter nodes.
        """
        self.vm.cmd('blockdev-add', {
                        'driver': 'copy-on-read',
                        'node-name': 'filter0',
                        'file': {
                            'driver': 'copy-on-read',
                            'node-name': 'filter1',
                            'file': {
                                'driver': 'null-co'
                            }
                        }
                    })

        self.vm.cmd('blockdev-add',
                    node_name='target', driver='null-co')

        self.vm.cmd('blockdev-mirror', job_id='mirror', device='filter0',
                    target='target', sync='full', replaces='filter1')

        self.complete_and_wait('mirror')

        self.vm.assert_block_path('filter0', '/file', 'target')

# Tests for mirror with filters (and how the mirror filter behaves, as
# an example for an implicit filter)
class TestFilters(iotests.QMPTestCase):
    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, backing_img, '1M')
        qemu_img('create', '-f', iotests.imgfmt, '-b', backing_img,
                 '-F', iotests.imgfmt, test_img)
        qemu_img('create', '-f', iotests.imgfmt, '-b', backing_img,
                 '-F', iotests.imgfmt, target_img)

        qemu_io('-c', 'write -P 1 0 512k', backing_img)
        qemu_io('-c', 'write -P 2 512k 512k', test_img)

        self.vm = iotests.VM().add_device('virtio-scsi,id=vio-scsi')
        self.vm.launch()

        self.vm.cmd('blockdev-add', {
                        'node-name': 'target',
                        'driver': iotests.imgfmt,
                        'file': {
                            'driver': 'file',
                            'filename': target_img
                        },
                        'backing': None
                    })

        self.filterless_chain = {
                'node-name': 'source',
                'driver': iotests.imgfmt,
                'file': {
                    'driver': 'file',
                    'filename': test_img
                },
                'backing': {
                    'node-name': 'backing',
                    'driver': iotests.imgfmt,
                    'file': {
                        'driver': 'file',
                        'filename': backing_img
                    }
                }
            }

    def tearDown(self):
        self.vm.shutdown()

        os.remove(test_img)
        os.remove(target_img)
        os.remove(backing_img)

    def test_cor(self):
        self.vm.cmd('blockdev-add', {
                        'node-name': 'filter',
                        'driver': 'copy-on-read',
                        'file': self.filterless_chain
                    })

        self.vm.cmd('blockdev-mirror',
                    job_id='mirror',
                    device='filter',
                    target='target',
                    sync='top')

        self.complete_and_wait('mirror')

        self.vm.qmp('blockdev-del', node_name='target')

        target_map = qemu_img_map(target_img)

        assert target_map[0]['start'] == 0
        assert target_map[0]['length'] == 512 * 1024
        assert target_map[0]['depth'] == 1

        assert target_map[1]['start'] == 512 * 1024
        assert target_map[1]['length'] == 512 * 1024
        assert target_map[1]['depth'] == 0

    def test_implicit_mirror_filter(self):
        self.vm.cmd('blockdev-add', self.filterless_chain)

        # We need this so we can query from above the mirror node
        self.vm.cmd('device_add',
                    driver='scsi-hd',
                    id='virtio',
                    bus='vio-scsi.0',
                    drive='source')

        self.vm.cmd('blockdev-mirror',
                    job_id='mirror',
                    device='source',
                    target='target',
                    sync='top')

        # The mirror filter is now an implicit node, so it should be
        # invisible when querying the backing chain
        blockdevs = self.vm.qmp('query-block')['return']
        device_info = next(dev for dev in blockdevs if dev['qdev'] == 'virtio')

        assert device_info['inserted']['node-name'] == 'source'

        image_info = device_info['inserted']['image']
        assert image_info['filename'] == test_img
        assert image_info['backing-image']['filename'] == backing_img

        self.complete_and_wait('mirror')

    def test_explicit_mirror_filter(self):
        # Same test as above, but this time we give the mirror filter
        # a node-name so it will not be invisible
        self.vm.cmd('blockdev-add', self.filterless_chain)

        # We need this so we can query from above the mirror node
        self.vm.cmd('device_add',
                    driver='scsi-hd',
                    id='virtio',
                    bus='vio-scsi.0',
                    drive='source')

        self.vm.cmd('blockdev-mirror',
                    job_id='mirror',
                    device='source',
                    target='target',
                    sync='top',
                    filter_node_name='mirror-filter')

        # With a node-name given to it, the mirror filter should now
        # be visible
        blockdevs = self.vm.qmp('query-block')['return']
        device_info = next(dev for dev in blockdevs if dev['qdev'] == 'virtio')

        assert device_info['inserted']['node-name'] == 'mirror-filter'

        self.complete_and_wait('mirror')


if __name__ == '__main__':
    iotests.main(supported_fmts=['qcow2', 'qed'],
                 supported_protocols=['file'],
                 supported_platforms=['linux', 'freebsd', 'netbsd', 'openbsd'])
