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

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

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

        time.sleep(1)
        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')

    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 = {'options':
                    {'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(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(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 has_quorum(self):
        return 'quorum' in iotests.qemu_img_pipe('--help')

    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 = { "options" : { "driver": "quorum", "id": "quorum0",
                 "vote-threshold": 2, "children": [ "img0", "img1", "img2" ] } }
        if self.has_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 ]:
            # 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 self.has_quorum():
            return

        self.assert_no_active_block_jobs()

        result = self.vm.qmp('drive-mirror', 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="quorum0")
        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 self.has_quorum():
            return

        self.assert_no_active_block_jobs()

        result = self.vm.qmp('drive-mirror', 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="quorum0", 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 self.has_quorum():
            return

        self.assert_no_active_block_jobs()

        result = self.vm.qmp('drive-mirror', 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="quorum0")
        # 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 self.has_quorum():
            return

        self.assert_no_active_block_jobs()

        result = self.vm.qmp('drive-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('block-job-pause', device='quorum0')
        self.assert_qmp(result, 'return', {})

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

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

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

        self.complete_and_wait(drive="quorum0")
        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 self.has_quorum():
            return

        if iotests.qemu_default_machine != 'pc':
            return

        result = self.vm.qmp('drive-mirror', 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 self.has_quorum():
            return

        result = self.vm.qmp('drive-mirror', 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 self.has_quorum():
            return

        result = self.vm.qmp('drive-mirror', 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 self.has_quorum():
            return

        result = self.vm.qmp('drive-mirror', device='quorum0',
                             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 self.has_quorum():
            return

        result = self.vm.qmp('drive-mirror', 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 self.has_quorum():
            return

        result = self.vm.qmp('drive-mirror', 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 self.has_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', 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', 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(drive="quorum0")
        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()

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