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

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

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

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

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

        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.assertIn(result['return'][0]['status'], ['running', 'ready'])
        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')

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

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

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

        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_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):
        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'])
