#!/usr/bin/env python
#
# 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 iotests
from iotests import qemu_img, 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')

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, 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)
        self.vm.shutdown()

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

        self.vm.shutdown()

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

    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

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

        self.assert_no_active_block_jobs()
        self.vm.shutdown()

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

    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), 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)
        self.assertEquals(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, 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()
        self.vm.shutdown()

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), 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()
        self.vm.shutdown()

    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.get_qmp_event(wait=True)
        self.assertEquals(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()
        self.vm.shutdown()

    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()
        self.vm.shutdown()

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, 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().add_drive(test_img)
        self.vm.launch()

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

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

    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(TestSingleDrive.image_len))
            # Assign a node name to each quorum image in order to manipulate
            # them
            opts = "node-name=img%i" % self.IMAGES.index(i)
            self.vm = self.vm.add_drive(i, 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" ] }
        if iotests.supports_quorum():
            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 ]:
            # Do a try/except because the test may have deleted some images
            try:
                os.remove(i)
            except OSError:
                pass

    def test_complete(self):
        if not iotests.supports_quorum():
            return

        self.assert_no_active_block_jobs()

        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)
        # TODO: a better test requiring some QEMU infrastructure will be added
        #       to check that this file is really driven by quorum
        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):
        if not iotests.supports_quorum():
            return

        self.assert_no_active_block_jobs()

        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)
        self.vm.shutdown()

    def test_cancel_after_ready(self):
        if not iotests.supports_quorum():
            return

        self.assert_no_active_block_jobs()

        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):
        if not iotests.supports_quorum():
            return

        self.assert_no_active_block_jobs()

        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 not iotests.supports_quorum():
            return

        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):
        if not iotests.supports_quorum():
            return

        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):
        if not iotests.supports_quorum():
            return

        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):
        if not iotests.supports_quorum():
            return

        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):
        if not iotests.supports_quorum():
            return

        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):
        if not iotests.supports_quorum():
            return

        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):
        if not iotests.supports_quorum():
            return

        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)
        # TODO: a better test requiring some QEMU infrastructure will be added
        #       to check that this file is really driven by quorum
        self.vm.shutdown()

# 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.qmp_to_opts(blk0))
        self.vm.add_blockdev(self.qmp_to_opts(blk1))
        self.vm.add_blockdev(self.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')

if __name__ == '__main__':
    iotests.main(supported_fmts=['qcow2', 'qed'])
