#!/usr/bin/env python
#
# Tests for drive-backup and blockdev-backup
#
# Copyright (C) 2013, 2014 Red Hat, Inc.
#
# Based on 041.
#
# 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

test_img = os.path.join(iotests.test_dir, 'test.img')
target_img = os.path.join(iotests.test_dir, 'target.img')
blockdev_target_img = os.path.join(iotests.test_dir, 'blockdev-target.img')

image_len = 64 * 1024 * 1024 # MB

def setUpModule():
    qemu_img('create', '-f', iotests.imgfmt, test_img, str(image_len))
    qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x11 0 64k', test_img)
    qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x00 64k 128k', test_img)
    qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x22 162k 32k', test_img)
    qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
    qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
    qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x33 67043328 64k', test_img)

def tearDownModule():
    os.remove(test_img)


class TestSingleDrive(iotests.QMPTestCase):
    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))

        self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
        self.vm.add_drive(blockdev_target_img, interface="none")
        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(blockdev_target_img)
        try:
            os.remove(target_img)
        except OSError:
            pass

    def do_test_cancel(self, cmd, target):
        self.assert_no_active_block_jobs()

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

        event = self.cancel_and_wait(resume=True)
        self.assert_qmp(event, 'data/type', 'backup')

    def test_cancel_drive_backup(self):
        self.do_test_cancel('drive-backup', target_img)

    def test_cancel_blockdev_backup(self):
        self.do_test_cancel('blockdev-backup', 'drive1')

    def do_test_pause(self, cmd, target, image):
        self.assert_no_active_block_jobs()

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

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

        self.vm.resume_drive('drive0')
        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.wait_until_completed()

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

    def test_pause_drive_backup(self):
        self.do_test_pause('drive-backup', target_img, target_img)

    def test_pause_blockdev_backup(self):
        self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)

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

        result = self.vm.qmp('drive-backup', device='drive2', # CD-ROM
                             target=target_img, sync='full')
        self.assert_qmp(result, 'error/class', 'GenericError')

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

        result = self.vm.qmp('blockdev-backup', device='drive2', # CD-ROM
                             target='drive1', sync='full')
        self.assert_qmp(result, 'error/class', 'GenericError')

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

    def test_invalid_format(self):
        result = self.vm.qmp('drive-backup', device='drive0',
                             target=target_img, sync='full',
                             format='spaghetti-noodles')
        self.assert_qmp(result, 'error/class', 'GenericError')

    def do_test_device_not_found(self, cmd, **args):
        result = self.vm.qmp(cmd, **args)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_device_not_found(self):
        self.do_test_device_not_found('drive-backup', device='nonexistent',
                                      target=target_img, sync='full')

        self.do_test_device_not_found('blockdev-backup', device='nonexistent',
                                      target='drive0', sync='full')

        self.do_test_device_not_found('blockdev-backup', device='drive0',
                                      target='nonexistent', sync='full')

        self.do_test_device_not_found('blockdev-backup', device='nonexistent',
                                      target='nonexistent', sync='full')

    def test_target_is_source(self):
        result = self.vm.qmp('blockdev-backup', device='drive0',
                             target='drive0', sync='full')
        self.assert_qmp(result, 'error/class', 'GenericError')

class TestSetSpeed(iotests.QMPTestCase):
    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))

        self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
        self.vm.add_drive(blockdev_target_img, interface="none")
        self.vm.launch()

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

    def do_test_set_speed(self, cmd, target):
        self.assert_no_active_block_jobs()

        self.vm.pause_drive('drive0')
        result = self.vm.qmp(cmd, device='drive0', target=target, sync='full')
        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)

        event = self.cancel_and_wait(resume=True)
        self.assert_qmp(event, 'data/type', 'backup')

        # Check setting speed option works
        self.vm.pause_drive('drive0')
        result = self.vm.qmp(cmd, device='drive0',
                             target=target, sync='full', 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)

        event = self.cancel_and_wait(resume=True)
        self.assert_qmp(event, 'data/type', 'backup')

    def test_set_speed_drive_backup(self):
        self.do_test_set_speed('drive-backup', target_img)

    def test_set_speed_blockdev_backup(self):
        self.do_test_set_speed('blockdev-backup', 'drive1')

    def do_test_set_speed_invalid(self, cmd, target):
        self.assert_no_active_block_jobs()

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

        self.assert_no_active_block_jobs()

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

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

        event = self.cancel_and_wait(resume=True)
        self.assert_qmp(event, 'data/type', 'backup')

    def test_set_speed_invalid_drive_backup(self):
        self.do_test_set_speed_invalid('drive-backup', target_img)

    def test_set_speed_invalid_blockdev_backup(self):
        self.do_test_set_speed_invalid('blockdev-backup',  'drive1')

# Note: We cannot use pause_drive() here, or the transaction command
#       would stall.  Instead, we limit the block job speed here.
class TestSingleTransaction(iotests.QMPTestCase):
    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len))

        self.vm = iotests.VM().add_drive(test_img)
        self.vm.add_drive(blockdev_target_img, interface="none")
        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(blockdev_target_img)
        try:
            os.remove(target_img)
        except OSError:
            pass

    def do_test_cancel(self, cmd, target):
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('transaction', actions=[{
                'type': cmd,
                'data': { 'device': 'drive0',
                          'target': target,
                          'sync': 'full',
                          'speed': 64 * 1024 },
            }
        ])

        self.assert_qmp(result, 'return', {})

        event = self.cancel_and_wait()
        self.assert_qmp(event, 'data/type', 'backup')

    def test_cancel_drive_backup(self):
        self.do_test_cancel('drive-backup', target_img)

    def test_cancel_blockdev_backup(self):
        self.do_test_cancel('blockdev-backup', 'drive1')

    def do_test_pause(self, cmd, target, image):
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('transaction', actions=[{
                'type': cmd,
                'data': { 'device': 'drive0',
                          'target': target,
                          'sync': 'full',
                          'speed': 64 * 1024 },
            }
        ])
        self.assert_qmp(result, 'return', {})

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

        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0)
        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.wait_until_completed()

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

    def test_pause_drive_backup(self):
        self.do_test_pause('drive-backup', target_img, target_img)

    def test_pause_blockdev_backup(self):
        self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)

    def do_test_medium_not_found(self, cmd, target):
        if iotests.qemu_default_machine != 'pc':
            return

        result = self.vm.qmp('transaction', actions=[{
                'type': cmd,
                'data': { 'device': 'drive2', # CD-ROM
                          'target': target,
                          'sync': 'full' },
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_medium_not_found_drive_backup(self):
        self.do_test_medium_not_found('drive-backup', target_img)

    def test_medium_not_found_blockdev_backup(self):
        self.do_test_medium_not_found('blockdev-backup', 'drive1')

    def test_image_not_found(self):
        result = self.vm.qmp('transaction', actions=[{
                'type': 'drive-backup',
                'data': { 'device': 'drive0',
                          'mode': 'existing',
                          'target': target_img,
                          'sync': 'full' },
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_device_not_found(self):
        result = self.vm.qmp('transaction', actions=[{
                'type': 'drive-backup',
                'data': { 'device': 'nonexistent',
                          'mode': 'existing',
                          'target': target_img,
                          'sync': 'full' },
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')

        result = self.vm.qmp('transaction', actions=[{
                'type': 'blockdev-backup',
                'data': { 'device': 'nonexistent',
                          'target': 'drive1',
                          'sync': 'full' },
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')

        result = self.vm.qmp('transaction', actions=[{
                'type': 'blockdev-backup',
                'data': { 'device': 'drive0',
                          'target': 'nonexistent',
                          'sync': 'full' },
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')

        result = self.vm.qmp('transaction', actions=[{
                'type': 'blockdev-backup',
                'data': { 'device': 'nonexistent',
                          'target': 'nonexistent',
                          'sync': 'full' },
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_target_is_source(self):
        result = self.vm.qmp('transaction', actions=[{
                'type': 'blockdev-backup',
                'data': { 'device': 'drive0',
                          'target': 'drive0',
                          'sync': 'full' },
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_abort(self):
        result = self.vm.qmp('transaction', actions=[{
                'type': 'drive-backup',
                'data': { 'device': 'nonexistent',
                          'mode': 'existing',
                          'target': target_img,
                          'sync': 'full' },
            }, {
                'type': 'Abort',
                'data': {},
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('transaction', actions=[{
                'type': 'blockdev-backup',
                'data': { 'device': 'nonexistent',
                          'target': 'drive1',
                          'sync': 'full' },
            }, {
                'type': 'Abort',
                'data': {},
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('transaction', actions=[{
                'type': 'blockdev-backup',
                'data': { 'device': 'drive0',
                          'target': 'nonexistent',
                          'sync': 'full' },
            }, {
                'type': 'Abort',
                'data': {},
            }
        ])
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_no_active_block_jobs()


class TestDriveCompression(iotests.QMPTestCase):
    image_len = 64 * 1024 * 1024 # MB
    fmt_supports_compression = [{'type': 'qcow2', 'args': ()},
                                {'type': 'vmdk', 'args': ('-o', 'subformat=streamOptimized')}]

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

    def do_prepare_drives(self, fmt, args, attach_target):
        self.vm = iotests.VM().add_drive('blkdebug::' + test_img)

        qemu_img('create', '-f', fmt, blockdev_target_img,
                 str(TestDriveCompression.image_len), *args)
        if attach_target:
            self.vm.add_drive(blockdev_target_img, format=fmt, interface="none")

        self.vm.launch()

    def do_test_compress_complete(self, cmd, format, attach_target, **args):
        self.do_prepare_drives(format['type'], format['args'], attach_target)

        self.assert_no_active_block_jobs()

        result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args)
        self.assert_qmp(result, 'return', {})

        self.wait_until_completed()

        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
                                               iotests.imgfmt, format['type']),
                        'target image does not match source after backup')

    def test_complete_compress_drive_backup(self):
        for format in TestDriveCompression.fmt_supports_compression:
            self.do_test_compress_complete('drive-backup', format, False,
                                           target=blockdev_target_img, mode='existing')

    def test_complete_compress_blockdev_backup(self):
        for format in TestDriveCompression.fmt_supports_compression:
            self.do_test_compress_complete('blockdev-backup', format, True,
                                           target='drive1')

    def do_test_compress_cancel(self, cmd, format, attach_target, **args):
        self.do_prepare_drives(format['type'], format['args'], attach_target)

        self.assert_no_active_block_jobs()

        self.vm.pause_drive('drive0')
        result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args)
        self.assert_qmp(result, 'return', {})

        event = self.cancel_and_wait(resume=True)
        self.assert_qmp(event, 'data/type', 'backup')

        self.vm.shutdown()

    def test_compress_cancel_drive_backup(self):
        for format in TestDriveCompression.fmt_supports_compression:
            self.do_test_compress_cancel('drive-backup', format, False,
                                         target=blockdev_target_img, mode='existing')

    def test_compress_cancel_blockdev_backup(self):
       for format in TestDriveCompression.fmt_supports_compression:
            self.do_test_compress_cancel('blockdev-backup', format, True,
                                         target='drive1')

    def do_test_compress_pause(self, cmd, format, attach_target, **args):
        self.do_prepare_drives(format['type'], format['args'], attach_target)

        self.assert_no_active_block_jobs()

        self.vm.pause_drive('drive0')
        result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args)
        self.assert_qmp(result, 'return', {})

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

        self.vm.resume_drive('drive0')
        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.wait_until_completed()

        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
                                               iotests.imgfmt, format['type']),
                        'target image does not match source after backup')

    def test_compress_pause_drive_backup(self):
        for format in TestDriveCompression.fmt_supports_compression:
            self.do_test_compress_pause('drive-backup', format, False,
                                        target=blockdev_target_img, mode='existing')

    def test_compress_pause_blockdev_backup(self):
        for format in TestDriveCompression.fmt_supports_compression:
            self.do_test_compress_pause('blockdev-backup', format, True,
                                        target='drive1')

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