#!/usr/bin/env python3
# group: rw quick
#
# Test what happens when errors occur to a mirror job after it has
# been cancelled in the READY phase
#
# Copyright (C) 2021 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 os
import iotests


image_size = 1 * 1024 * 1024
source = os.path.join(iotests.test_dir, 'source.img')
target = os.path.join(iotests.test_dir, 'target.img')


class TestMirrorReadyCancelError(iotests.QMPTestCase):
    def setUp(self) -> None:
        iotests.qemu_img_create('-f', iotests.imgfmt, source, str(image_size))
        iotests.qemu_img_create('-f', iotests.imgfmt, target, str(image_size))

        # Ensure that mirror will copy something before READY so the
        # target format layer will forward the pre-READY flush to its
        # file child
        iotests.qemu_io('-c', 'write -P 1 0 64k', source)

        self.vm = iotests.VM()
        self.vm.launch()

    def tearDown(self) -> None:
        self.vm.shutdown()
        os.remove(source)
        os.remove(target)

    def add_blockdevs(self, once: bool) -> None:
        res = self.vm.qmp('blockdev-add',
                          **{'node-name': 'source',
                             'driver': iotests.imgfmt,
                             'file': {
                                 'driver': 'file',
                                 'filename': source
                             }})
        self.assert_qmp(res, 'return', {})

        # blkdebug notes:
        # Enter state 2 on the first flush, which happens before the
        # job enters the READY state.  The second flush will happen
        # when the job is about to complete, and we want that one to
        # fail.
        res = self.vm.qmp('blockdev-add',
                          **{'node-name': 'target',
                             'driver': iotests.imgfmt,
                             'file': {
                                 'driver': 'blkdebug',
                                 'image': {
                                     'driver': 'file',
                                     'filename': target
                                 },
                                 'set-state': [{
                                     'event': 'flush_to_disk',
                                     'state': 1,
                                     'new_state': 2
                                 }],
                                 'inject-error': [{
                                     'event': 'flush_to_disk',
                                     'once': once,
                                     'immediately': True,
                                     'state': 2
                                 }]}})
        self.assert_qmp(res, 'return', {})

    def start_mirror(self) -> None:
        res = self.vm.qmp('blockdev-mirror',
                          job_id='mirror',
                          device='source',
                          target='target',
                          filter_node_name='mirror-top',
                          sync='full',
                          on_target_error='stop')
        self.assert_qmp(res, 'return', {})

    def cancel_mirror_with_error(self) -> None:
        self.vm.event_wait('BLOCK_JOB_READY')

        # Write something so will not leave the job immediately, but
        # flush first (which will fail, thanks to blkdebug)
        res = self.vm.qmp('human-monitor-command',
                          command_line='qemu-io mirror-top "write -P 2 0 64k"')
        self.assert_qmp(res, 'return', '')

        # Drain status change events
        while self.vm.event_wait('JOB_STATUS_CHANGE', timeout=0.0) is not None:
            pass

        res = self.vm.qmp('block-job-cancel', device='mirror')
        self.assert_qmp(res, 'return', {})

        self.vm.event_wait('BLOCK_JOB_ERROR')

    def test_transient_error(self) -> None:
        self.add_blockdevs(True)
        self.start_mirror()
        self.cancel_mirror_with_error()

        while True:
            e = self.vm.event_wait('JOB_STATUS_CHANGE')
            if e['data']['status'] == 'standby':
                # Transient error, try again
                self.vm.qmp('block-job-resume', device='mirror')
            elif e['data']['status'] == 'null':
                break

    def test_persistent_error(self) -> None:
        self.add_blockdevs(False)
        self.start_mirror()
        self.cancel_mirror_with_error()

        while True:
            e = self.vm.event_wait('JOB_STATUS_CHANGE')
            if e['data']['status'] == 'standby':
                # Persistent error, no point in continuing
                self.vm.qmp('block-job-cancel', device='mirror', force=True)
            elif e['data']['status'] == 'null':
                break


if __name__ == '__main__':
    # LUKS would require special key-secret handling in add_blockdevs()
    iotests.main(supported_fmts=['generic'],
                 unsupported_fmts=['luks'],
                 supported_protocols=['file'])
