#!/usr/bin/env python
#
# This test covers what happens when a mirror block job is cancelled
# in various phases of its existence.
#
# Note that this test only checks the emitted events (i.e.
# BLOCK_JOB_COMPLETED vs. BLOCK_JOB_CANCELLED), it does not compare
# whether the target is in sync with the source when the
# BLOCK_JOB_COMPLETED event occurs.  This is covered by other tests
# (such as 041).
#
# Copyright (C) 2018 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/>.
#
# Creator/Owner: Max Reitz <mreitz@redhat.com>

import iotests
from iotests import log, qemu_img, qemu_io_silent

iotests.verify_image_format(supported_fmts=['qcow2', 'raw'])


# Launches the VM, adds two null-co nodes (source and target), and
# starts a blockdev-mirror job on them.
#
# Either both or none of speed and buf_size must be given.

def start_mirror(vm, speed=None, buf_size=None):
    vm.launch()

    ret = vm.qmp('blockdev-add',
                     node_name='source',
                     driver='null-co',
                     size=1048576)
    assert ret['return'] == {}

    ret = vm.qmp('blockdev-add',
                     node_name='target',
                     driver='null-co',
                     size=1048576)
    assert ret['return'] == {}

    if speed is not None:
        ret = vm.qmp('blockdev-mirror',
                         job_id='mirror',
                         device='source',
                         target='target',
                         sync='full',
                         speed=speed,
                         buf_size=buf_size)
    else:
        ret = vm.qmp('blockdev-mirror',
                         job_id='mirror',
                         device='source',
                         target='target',
                         sync='full')

    assert ret['return'] == {}


log('')
log('=== Cancel mirror job before convergence ===')
log('')

log('--- force=false ---')
log('')

with iotests.VM() as vm:
    # Low speed so it does not converge
    start_mirror(vm, 65536, 65536)

    log('Cancelling job')
    log(vm.qmp('block-job-cancel', device='mirror', force=False))

    log(vm.event_wait('BLOCK_JOB_CANCELLED'),
        filters=[iotests.filter_qmp_event])

log('')
log('--- force=true ---')
log('')

with iotests.VM() as vm:
    # Low speed so it does not converge
    start_mirror(vm, 65536, 65536)

    log('Cancelling job')
    log(vm.qmp('block-job-cancel', device='mirror', force=True))

    log(vm.event_wait('BLOCK_JOB_CANCELLED'),
        filters=[iotests.filter_qmp_event])


log('')
log('=== Cancel mirror job after convergence ===')
log('')

log('--- force=false ---')
log('')

with iotests.VM() as vm:
    start_mirror(vm)

    log(vm.event_wait('BLOCK_JOB_READY'),
        filters=[iotests.filter_qmp_event])

    log('Cancelling job')
    log(vm.qmp('block-job-cancel', device='mirror', force=False))

    log(vm.event_wait('BLOCK_JOB_COMPLETED'),
        filters=[iotests.filter_qmp_event])

log('')
log('--- force=true ---')
log('')

with iotests.VM() as vm:
    start_mirror(vm)

    log(vm.event_wait('BLOCK_JOB_READY'),
        filters=[iotests.filter_qmp_event])

    log('Cancelling job')
    log(vm.qmp('block-job-cancel', device='mirror', force=True))

    log(vm.event_wait('BLOCK_JOB_CANCELLED'),
        filters=[iotests.filter_qmp_event])

log('')
log('=== Cancel mirror job from throttled node by quitting ===')
log('')

with iotests.VM() as vm, \
     iotests.FilePath('src.img') as src_img_path:

    assert qemu_img('create', '-f', iotests.imgfmt, src_img_path, '64M') == 0
    assert qemu_io_silent('-f', iotests.imgfmt, src_img_path,
                          '-c', 'write -P 42 0M 64M') == 0

    vm.launch()

    ret = vm.qmp('object-add', qom_type='throttle-group', id='tg',
                 props={'x-bps-read': 4096})
    assert ret['return'] == {}

    ret = vm.qmp('blockdev-add',
                 node_name='source',
                 driver=iotests.imgfmt,
                 file={
                     'driver': 'file',
                     'filename': src_img_path
                 })
    assert ret['return'] == {}

    ret = vm.qmp('blockdev-add',
                 node_name='throttled-source',
                 driver='throttle',
                 throttle_group='tg',
                 file='source')
    assert ret['return'] == {}

    ret = vm.qmp('blockdev-add',
                 node_name='target',
                 driver='null-co',
                 size=(64 * 1048576))
    assert ret['return'] == {}

    ret = vm.qmp('blockdev-mirror',
                 job_id='mirror',
                 device='throttled-source',
                 target='target',
                 sync='full')
    assert ret['return'] == {}

    log(vm.qmp('quit'))

    with iotests.Timeout(5, 'Timeout waiting for VM to quit'):
        vm.shutdown(has_quit=True)
