#!/usr/bin/env python3
# group: rw
#
# 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()
        self.vm.add_drive('blkdebug::' + test_img, 'node-name=source')
        self.vm.add_drive(blockdev_target_img, 'node-name=target',
                          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', {})

        self.pause_job('drive0', wait=False)
        self.vm.resume_drive('drive0')
        self.pause_wait('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_resize_blockdev_backup(self, device, node):
        def pre_finalize():
            result = self.vm.qmp('block_resize', device=device, size=65536)
            self.assert_qmp(result, 'error/class', 'GenericError')

            result = self.vm.qmp('block_resize', node_name=node, size=65536)
            self.assert_qmp(result, 'error/class', 'GenericError')

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

        self.vm.run_job('job0', auto_finalize=False, pre_finalize=pre_finalize)

    def test_source_resize_blockdev_backup(self):
        self.do_test_resize_blockdev_backup('drive0', 'source')

    def test_target_resize_blockdev_backup(self):
        self.do_test_resize_blockdev_backup('drive1', 'target')

    def do_test_target_size(self, size):
        result = self.vm.qmp('block_resize', device='drive1', size=size)
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0',
                             target='drive1', sync='full')
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_small_target(self):
        self.do_test_target_size(image_len // 2)

    def test_large_target(self):
        self.do_test_target_size(image_len * 2)

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

        self.pause_job('drive0', wait=False)

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

        self.pause_wait('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 TestCompressedToQcow2(iotests.QMPTestCase):
    image_len = 64 * 1024 * 1024 # MB
    target_fmt = {'type': 'qcow2', 'args': (), 'drive-opts': ''}

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

    def do_prepare_drives(self, attach_target):
        self.vm = iotests.VM().add_drive('blkdebug::' + test_img,
                                         opts=self.target_fmt['drive-opts'])

        qemu_img('create', '-f', self.target_fmt['type'], blockdev_target_img,
                 str(self.image_len), *self.target_fmt['args'])
        if attach_target:
            self.vm.add_drive(blockdev_target_img,
                              img_format=self.target_fmt['type'],
                              interface="none",
                              opts=self.target_fmt['drive-opts'])

        self.vm.launch()

    def do_test_compress_complete(self, cmd, attach_target, **args):
        self.do_prepare_drives(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,
                                               self.target_fmt['type']),
                        'target image does not match source after backup')

    def test_complete_compress_drive_backup(self):
        self.do_test_compress_complete('drive-backup', False,
                                       target=blockdev_target_img,
                                       mode='existing')

    def test_complete_compress_blockdev_backup(self):
        self.do_test_compress_complete('blockdev-backup',
                                       True, target='drive1')

    def do_test_compress_cancel(self, cmd, attach_target, **args):
        self.do_prepare_drives(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):
        self.do_test_compress_cancel('drive-backup', False,
                                     target=blockdev_target_img,
                                     mode='existing')

    def test_compress_cancel_blockdev_backup(self):
        self.do_test_compress_cancel('blockdev-backup', True,
                                     target='drive1')

    def do_test_compress_pause(self, cmd, attach_target, **args):
        self.do_prepare_drives(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', {})

        self.pause_job('drive0', wait=False)
        self.vm.resume_drive('drive0')
        self.pause_wait('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,
                                               self.target_fmt['type']),
                        'target image does not match source after backup')

    def test_compress_pause_drive_backup(self):
        self.do_test_compress_pause('drive-backup', False,
                                    target=blockdev_target_img,
                                    mode='existing')

    def test_compress_pause_blockdev_backup(self):
        self.do_test_compress_pause('blockdev-backup', True,
                                    target='drive1')


class TestCompressedToVmdk(TestCompressedToQcow2):
    target_fmt = {'type': 'vmdk', 'args': ('-o', 'subformat=streamOptimized'),
                  'drive-opts': 'cache.no-flush=on'}

    @iotests.skip_if_unsupported(['vmdk'])
    def setUp(self):
        pass


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