#!/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_pipe, 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()

        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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)

        result = self.vm.qmp('block-job-resume', device='drive0')
        self.assert_qmp(result, 'return', {})

        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
        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             buf_size=4096, target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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)
        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             buf_size=65536, mode='existing', target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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)
        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             mode='existing', target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full',
                             target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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' } }
        result = self.vm.qmp("blockdev-add", **args)
        self.assert_qmp(result, 'return', {})

    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')

        result = self.vm.qmp(self.qmp_cmd, job_id='job0', device='drive0',
                             sync='full', target=self.qmp_target,
                             auto_finalize=False, auto_dismiss=False)
        self.assert_qmp(result, 'return', {})

        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):
        result = self.vm.qmp('block_resize', node_name=self.qmp_target,
                             size=size)
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp(self.qmp_cmd, job_id='job0',
                             device='drive0', sync='full', auto_dismiss=False,
                             target=self.qmp_target)
        self.assert_qmp(result, 'return', {})

        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)
        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             mode='existing', target=target_img)
        self.assert_qmp(result, 'return', {})

        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)
        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             mode='existing', target=target_img)
        self.assert_qmp(result, 'return', {})

        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)

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             mode='existing', target=target_img)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
                             target=target_img)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img, on_source_error='ignore')
        self.assert_qmp(result, 'return', {})

        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.assert_qmp(result, 'return[0]/paused', False)
        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)
        result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
                             on_source_error='ignore',
                             mode='existing', target=target_img)
        self.assert_qmp(result, 'return', {})

        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.assert_qmp(result, 'return[0]/paused', False)
        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img, on_source_error='stop')
        self.assert_qmp(result, 'return', {})

        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')

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

                    result = self.vm.qmp('block-job-resume', device='drive0')
                    self.assert_qmp(result, 'return', {})
                    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]/paused', False)
        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             mode='existing', target=self.target_img)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             mode='existing', target=self.target_img,
                             on_target_error='ignore')
        self.assert_qmp(result, 'return', {})

        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.assert_qmp(result, 'return[0]/paused', False)
        self.complete_and_wait()

    def test_stop_write(self):
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             mode='existing', target=self.target_img,
                             on_target_error='stop')
        self.assert_qmp(result, 'return', {})

        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')

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

                    result = self.vm.qmp('block-job-resume', device='drive0')
                    self.assert_qmp(result, 'return', {})

                    result = self.vm.qmp('query-block-jobs')
                    self.assert_qmp(result, 'return[0]/paused', False)
                    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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img)
        self.assert_qmp(result, 'return', {})

        # 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)

        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
        self.assert_qmp(result, 'return', {})

        # 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
        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img, speed=4*1024*1024)
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
                             target=target_img)
        self.assert_qmp(result, 'return', {})

        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()
        result = self.vm.qmp('blockdev-add', node_name='drive0',
                             driver=iotests.imgfmt,
                             file={
                                 'driver': 'file',
                                 'filename': test_img,
                             })
        self.assert_qmp(result, 'return', {})

    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()
        result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
                             sync='full', target=target_img,
                             mode='absolute-paths')
        self.assert_qmp(result, 'return', {})
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

    def test_absolute_paths_top(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
                             sync='top', target=target_img,
                             mode='absolute-paths')
        self.assert_qmp(result, 'return', {})
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

    def test_absolute_paths_none(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
                             sync='none', target=target_img,
                             mode='absolute-paths')
        self.assert_qmp(result, 'return', {})
        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()
        result = self.vm.qmp('drive-mirror', job_id='drive0', device='drive0',
                             sync='full', target=target_img, mode='existing')
        self.assert_qmp(result, 'return', {})
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('blockdev-del', node_name='drive0')
        self.assert_qmp(result, 'return', {})

        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)

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

        self.assert_no_active_block_jobs()
        result = self.vm.qmp('blockdev-mirror', job_id='drive0', device='drive0',
                             sync='full', target='target')
        self.assert_qmp(result, 'return', {})
        self.complete_and_wait()
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('blockdev-del', node_name='drive0')
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('blockdev-del', node_name='target')
        self.assert_qmp(result, 'return', {})

        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()
        result = self.vm.qmp('drive-mirror', device='drive0',
                             sync='full', target=target_img,
                             mode='absolute-paths', granularity=8192)
        self.assert_qmp(result, 'return', {})

        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" ] }
        result = self.vm.qmp("blockdev-add", **args)
        self.assert_qmp(result, 'return', {})


    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):
        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, 'return', {})

        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):
        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, 'return', {})

        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):
        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, 'return', {})

        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):
        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, 'return', {})

        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)

        result = self.vm.qmp('block-job-resume', device='job0')
        self.assert_qmp(result, 'return', {})

        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):
        result = self.vm.qmp('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')

        result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
                             sync='full', node_name='repair0', replaces="snap1",
                             target=quorum_repair_img, format=iotests.imgfmt)
        self.assert_qmp(result, 'return', {})

        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.
        """
        result = self.vm.qmp('nbd-server-start',
                             addr={
                                 'type': 'unix',
                                 'data': {'path': nbd_sock_path}
                             })
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('nbd-server-add', device='img1')
        self.assert_qmp(result, 'return', {})

        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.
        """
        result = self.vm.qmp('nbd-server-start',
                             addr={
                                 'type': 'unix',
                                 'data': {'path': nbd_sock_path}
                             })
        self.assert_qmp(result, 'return', {})

        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, 'return', {})

        result = self.vm.qmp('nbd-server-add', device='img1')
        self.assert_qmp(result, 'return', {})

        # 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()

        result = self.vm.qmp('blockdev-mirror', job_id='job', device='src',
                             sync='full', target='dest')
        self.assert_qmp(result, 'return', {})

        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)
        result = self.vm.qmp('blockdev-add',
                             driver='blkdebug',
                             node_name='dest-perm',
                             image='dest',
                             unshare_child_perms=['consistent-read'])
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('blockdev-mirror', job_id='job', device='src',
                             sync='full', target='dest',
                             filter_node_name='mirror-filter')
        self.assert_qmp(result, 'return', {})

        # 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)
        result = self.vm.qmp('blockdev-add',
                             driver='blkdebug',
                             node_name='src-perm',
                             image='src',
                             take_child_perms=['consistent-read'])
        self.assert_qmp(result, 'return', {})

        # 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.
        """
        result = self.vm.qmp('blockdev-add', **{
                                 'driver': 'copy-on-read',
                                 'node-name': 'filter0',
                                 'file': {
                                     'driver': 'copy-on-read',
                                     'node-name': 'filter1',
                                     'file': {
                                         'driver': 'null-co'
                                     }
                                 }
                             })
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('blockdev-add',
                             node_name='target', driver='null-co')
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('blockdev-mirror', job_id='mirror', device='filter0',
                             target='target', sync='full', replaces='filter1')
        self.assert_qmp(result, 'return', {})

        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()

        result = self.vm.qmp('blockdev-add', **{
                                'node-name': 'target',
                                'driver': iotests.imgfmt,
                                'file': {
                                    'driver': 'file',
                                    'filename': target_img
                                },
                                'backing': None
                            })
        self.assert_qmp(result, 'return', {})

        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):
        result = self.vm.qmp('blockdev-add', **{
                                'node-name': 'filter',
                                'driver': 'copy-on-read',
                                'file': self.filterless_chain
                            })
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('blockdev-mirror',
                             job_id='mirror',
                             device='filter',
                             target='target',
                             sync='top')
        self.assert_qmp(result, 'return', {})

        self.complete_and_wait('mirror')

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

        target_map = qemu_img_pipe('map', '--output=json', target_img)
        target_map = json.loads(target_map)

        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):
        result = self.vm.qmp('blockdev-add', **self.filterless_chain)
        self.assert_qmp(result, 'return', {})

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

        result = self.vm.qmp('blockdev-mirror',
                             job_id='mirror',
                             device='source',
                             target='target',
                             sync='top')
        self.assert_qmp(result, 'return', {})

        # 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
        result = self.vm.qmp('blockdev-add', **self.filterless_chain)
        self.assert_qmp(result, 'return', {})

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

        result = self.vm.qmp('blockdev-mirror',
                             job_id='mirror',
                             device='source',
                             target='target',
                             sync='top',
                             filter_node_name='mirror-filter')
        self.assert_qmp(result, 'return', {})

        # 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'])
