#!/usr/bin/env python3
#
# Tests for image block commit.
#
# Copyright (C) 2012 IBM, Corp.
# 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/>.
#
# Test for live block commit
# Derived from Image Streaming Test 030

import time
import os
import iotests
from iotests import qemu_img, qemu_io
import struct
import errno

backing_img = os.path.join(iotests.test_dir, 'backing.img')
mid_img = os.path.join(iotests.test_dir, 'mid.img')
test_img = os.path.join(iotests.test_dir, 'test.img')

class ImageCommitTestCase(iotests.QMPTestCase):
    '''Abstract base class for image commit test cases'''

    def wait_for_complete(self, need_ready=False):
        completed = False
        ready = False
        while not completed:
            for event in self.vm.get_qmp_events(wait=True):
                if event['event'] == 'BLOCK_JOB_COMPLETED':
                    self.assert_qmp_absent(event, 'data/error')
                    self.assert_qmp(event, 'data/type', 'commit')
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.assert_qmp(event, 'data/offset', event['data']['len'])
                    if need_ready:
                        self.assertTrue(ready, "Expecting BLOCK_JOB_COMPLETED event")
                    completed = True
                elif event['event'] == 'BLOCK_JOB_READY':
                    ready = True
                    self.assert_qmp(event, 'data/type', 'commit')
                    self.assert_qmp(event, 'data/device', 'drive0')
                    self.vm.qmp('block-job-complete', device='drive0')

        self.assert_no_active_block_jobs()
        self.vm.shutdown()

    def run_commit_test(self, top, base, need_ready=False, node_names=False):
        self.assert_no_active_block_jobs()
        if node_names:
            result = self.vm.qmp('block-commit', device='drive0', top_node=top, base_node=base)
        else:
            result = self.vm.qmp('block-commit', device='drive0', top=top, base=base)
        self.assert_qmp(result, 'return', {})
        self.wait_for_complete(need_ready)

    def run_default_commit_test(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0')
        self.assert_qmp(result, 'return', {})
        self.wait_for_complete()

class TestSingleDrive(ImageCommitTestCase):
    # Need some space after the copied data so that throttling is effective in
    # tests that use it rather than just completing the job immediately
    image_len = 2 * 1024 * 1024
    test_len = 1 * 1024 * 256

    def setUp(self):
        iotests.create_image(backing_img, self.image_len)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
        qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
        self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=mid,backing.backing.node-name=base", interface="none")
        self.vm.add_device(iotests.get_virtio_scsi_device())
        self.vm.add_device("scsi-hd,id=scsi0,drive=drive0")
        self.vm.launch()
        self.has_quit = False

    def tearDown(self):
        self.vm.shutdown(has_quit=self.has_quit)
        os.remove(test_img)
        os.remove(mid_img)
        os.remove(backing_img)

    def test_commit(self):
        self.run_commit_test(mid_img, backing_img)
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))

    def test_commit_node(self):
        self.run_commit_test("mid", "base", node_names=True)
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))

    @iotests.skip_if_unsupported(['throttle'])
    def test_commit_with_filter_and_quit(self):
        result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg')
        self.assert_qmp(result, 'return', {})

        # Add a filter outside of the backing chain
        result = self.vm.qmp('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid')
        self.assert_qmp(result, 'return', {})

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

        # Quit immediately, thus forcing a simultaneous cancel of the
        # block job and a bdrv_drain_all()
        result = self.vm.qmp('quit')
        self.assert_qmp(result, 'return', {})

        self.has_quit = True

    # Same as above, but this time we add the filter after starting the job
    @iotests.skip_if_unsupported(['throttle'])
    def test_commit_plus_filter_and_quit(self):
        result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg')
        self.assert_qmp(result, 'return', {})

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

        # Add a filter outside of the backing chain
        result = self.vm.qmp('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid')
        self.assert_qmp(result, 'return', {})

        # Quit immediately, thus forcing a simultaneous cancel of the
        # block job and a bdrv_drain_all()
        result = self.vm.qmp('quit')
        self.assert_qmp(result, 'return', {})

        self.has_quit = True

    def test_device_not_found(self):
        result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img)
        self.assert_qmp(result, 'error/class', 'DeviceNotFound')

    def test_top_same_base(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % backing_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % backing_img)

    def test_top_invalid(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % backing_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Top image file badfile not found')

    def test_base_invalid(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % mid_img, base='badfile')
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')

    def test_top_node_invalid(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top_node='badfile', base_node='base')
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', "Cannot find device= nor node_name=badfile")

    def test_base_node_invalid(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top_node='mid', base_node='badfile')
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', "Cannot find device= nor node_name=badfile")

    def test_top_path_and_node(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top_node='mid', base_node='base', top='%s' % mid_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', "'top-node' and 'top' are mutually exclusive")

    def test_base_path_and_node(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top_node='mid', base_node='base', base='%s' % backing_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', "'base-node' and 'base' are mutually exclusive")

    def test_top_is_active(self):
        self.run_commit_test(test_img, backing_img, need_ready=True)
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))

    def test_top_is_default_active(self):
        self.run_default_commit_test()
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))

    def test_top_and_base_reversed(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % mid_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mid_img)

    def test_top_and_base_node_reversed(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top_node='base', base_node='top')
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', "'top' is not in this backing file chain")

    def test_top_node_in_wrong_chain(self):
        self.assert_no_active_block_jobs()

        result = self.vm.qmp('blockdev-add', driver='null-co', node_name='null')
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('block-commit', device='drive0', top_node='null', base_node='base')
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', "'null' is not in this backing file chain")

    # When the job is running on a BB that is automatically deleted on hot
    # unplug, the job is cancelled when the device disappears
    def test_hot_unplug(self):
        if self.image_len == 0:
            return

        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top=mid_img,
                             base=backing_img, speed=(self.image_len // 4))
        self.assert_qmp(result, 'return', {})
        result = self.vm.qmp('device_del', id='scsi0')
        self.assert_qmp(result, 'return', {})

        cancelled = False
        deleted = False
        while not cancelled or not deleted:
            for event in self.vm.get_qmp_events(wait=True):
                if event['event'] == 'DEVICE_DELETED':
                    self.assert_qmp(event, 'data/device', 'scsi0')
                    deleted = True
                elif event['event'] == 'BLOCK_JOB_CANCELLED':
                    self.assert_qmp(event, 'data/device', 'drive0')
                    cancelled = True
                elif event['event'] == 'JOB_STATUS_CHANGE':
                    self.assert_qmp(event, 'data/id', 'drive0')
                else:
                    self.fail("Unexpected event %s" % (event['event']))

        self.assert_no_active_block_jobs()

    # Tests that the insertion of the commit_top filter node doesn't make a
    # difference to query-blockstat
    def test_implicit_node(self):
        if self.image_len == 0:
            return

        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top=mid_img,
                             base=backing_img, speed=(self.image_len // 4))
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('query-block')
        self.assert_qmp(result, 'return[0]/inserted/file', test_img)
        self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt)
        self.assert_qmp(result, 'return[0]/inserted/backing_file', mid_img)
        self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 2)
        self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img)
        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', mid_img)
        self.assert_qmp(result, 'return[0]/inserted/image/backing-image/backing-image/filename', backing_img)

        result = self.vm.qmp('query-blockstats')
        self.assert_qmp(result, 'return[0]/node-name', 'top')
        self.assert_qmp(result, 'return[0]/backing/node-name', 'mid')
        self.assert_qmp(result, 'return[0]/backing/backing/node-name', 'base')

        self.cancel_and_wait()
        self.assert_no_active_block_jobs()

class TestRelativePaths(ImageCommitTestCase):
    image_len = 1 * 1024 * 1024
    test_len = 1 * 1024 * 256

    dir1 = "dir1"
    dir2 = "dir2/"
    dir3 = "dir2/dir3/"

    test_img = os.path.join(iotests.test_dir, dir3, 'test.img')
    mid_img = "../mid.img"
    backing_img = "../dir1/backing.img"

    backing_img_abs = os.path.join(iotests.test_dir, dir1, 'backing.img')
    mid_img_abs = os.path.join(iotests.test_dir, dir2, 'mid.img')

    def setUp(self):
        try:
            os.mkdir(os.path.join(iotests.test_dir, self.dir1))
            os.mkdir(os.path.join(iotests.test_dir, self.dir2))
            os.mkdir(os.path.join(iotests.test_dir, self.dir3))
        except OSError as exception:
            if exception.errno != errno.EEXIST:
                raise
        iotests.create_image(self.backing_img_abs, TestRelativePaths.image_len)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img_abs, self.mid_img_abs)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img_abs, self.test_img)
        qemu_img('rebase', '-u', '-b', self.backing_img, self.mid_img_abs)
        qemu_img('rebase', '-u', '-b', self.mid_img, self.test_img)
        qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', self.backing_img_abs)
        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', self.mid_img_abs)
        self.vm = iotests.VM().add_drive(self.test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(self.test_img)
        os.remove(self.mid_img_abs)
        os.remove(self.backing_img_abs)
        try:
            os.rmdir(os.path.join(iotests.test_dir, self.dir1))
            os.rmdir(os.path.join(iotests.test_dir, self.dir3))
            os.rmdir(os.path.join(iotests.test_dir, self.dir2))
        except OSError as exception:
            if exception.errno != errno.EEXIST and exception.errno != errno.ENOTEMPTY:
                raise

    def test_commit(self):
        self.run_commit_test(self.mid_img, self.backing_img)
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))

    def test_device_not_found(self):
        result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % self.mid_img)
        self.assert_qmp(result, 'error/class', 'DeviceNotFound')

    def test_top_same_base(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img, base='%s' % self.mid_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.mid_img)

    def test_top_invalid(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % self.backing_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Top image file badfile not found')

    def test_base_invalid(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img, base='badfile')
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')

    def test_top_is_active(self):
        self.run_commit_test(self.test_img, self.backing_img)
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
        self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))

    def test_top_and_base_reversed(self):
        self.assert_no_active_block_jobs()
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.backing_img, base='%s' % self.mid_img)
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.mid_img)


class TestSetSpeed(ImageCommitTestCase):
    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, mid_img)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 0 512', test_img)
        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
        self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(mid_img)
        os.remove(backing_img)

    def test_set_speed(self):
        self.assert_no_active_block_jobs()

        self.vm.pause_drive('drive0')
        result = self.vm.qmp('block-commit', device='drive0', top=mid_img, speed=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', 1024 * 1024)

        self.cancel_and_wait(resume=True)

class TestActiveZeroLengthImage(TestSingleDrive):
    image_len = 0

class TestReopenOverlay(ImageCommitTestCase):
    image_len = 1024 * 1024
    img0 = os.path.join(iotests.test_dir, '0.img')
    img1 = os.path.join(iotests.test_dir, '1.img')
    img2 = os.path.join(iotests.test_dir, '2.img')
    img3 = os.path.join(iotests.test_dir, '3.img')

    def setUp(self):
        iotests.create_image(self.img0, self.image_len)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.img0, self.img1)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.img1, self.img2)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.img2, self.img3)
        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xab 0 128K', self.img1)
        self.vm = iotests.VM().add_drive(self.img3)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        os.remove(self.img0)
        os.remove(self.img1)
        os.remove(self.img2)
        os.remove(self.img3)

    # This tests what happens when the overlay image of the 'top' node
    # needs to be reopened in read-write mode in order to update the
    # backing image string.
    def test_reopen_overlay(self):
        self.run_commit_test(self.img1, self.img0)

class TestErrorHandling(iotests.QMPTestCase):
    image_len = 2 * 1024 * 1024

    def setUp(self):
        iotests.create_image(backing_img, self.image_len)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)

        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x11 0 512k', mid_img)
        qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x22 0 512k', test_img)

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

        self.blkdebug_file = iotests.file_path("blkdebug.conf")

    def tearDown(self):
        self.vm.shutdown()
        os.remove(test_img)
        os.remove(mid_img)
        os.remove(backing_img)

    def blockdev_add(self, **kwargs):
        result = self.vm.qmp('blockdev-add', **kwargs)
        self.assert_qmp(result, 'return', {})

    def add_block_nodes(self, base_debug=None, mid_debug=None, top_debug=None):
        self.blockdev_add(node_name='base-file', driver='file',
                          filename=backing_img)
        self.blockdev_add(node_name='mid-file', driver='file',
                          filename=mid_img)
        self.blockdev_add(node_name='top-file', driver='file',
                          filename=test_img)

        if base_debug:
            self.blockdev_add(node_name='base-dbg', driver='blkdebug',
                              image='base-file', inject_error=base_debug)
        if mid_debug:
            self.blockdev_add(node_name='mid-dbg', driver='blkdebug',
                              image='mid-file', inject_error=mid_debug)
        if top_debug:
            self.blockdev_add(node_name='top-dbg', driver='blkdebug',
                              image='top-file', inject_error=top_debug)

        self.blockdev_add(node_name='base-fmt', driver='raw',
                          file=('base-dbg' if base_debug else 'base-file'))
        self.blockdev_add(node_name='mid-fmt', driver=iotests.imgfmt,
                          file=('mid-dbg' if mid_debug else 'mid-file'),
                          backing='base-fmt')
        self.blockdev_add(node_name='top-fmt', driver=iotests.imgfmt,
                          file=('top-dbg' if top_debug else 'top-file'),
                          backing='mid-fmt')

    def run_job(self, expected_events, error_pauses_job=False):
        match_device = {'data': {'device': 'job0'}}
        events = [
            ('BLOCK_JOB_COMPLETED', match_device),
            ('BLOCK_JOB_CANCELLED', match_device),
            ('BLOCK_JOB_ERROR', match_device),
            ('BLOCK_JOB_READY', match_device),
        ]

        completed = False
        log = []
        while not completed:
            ev = self.vm.events_wait(events, timeout=5.0)
            if ev['event'] == 'BLOCK_JOB_COMPLETED':
                completed = True
            elif ev['event'] == 'BLOCK_JOB_ERROR':
                if error_pauses_job:
                    result = self.vm.qmp('block-job-resume', device='job0')
                    self.assert_qmp(result, 'return', {})
            elif ev['event'] == 'BLOCK_JOB_READY':
                result = self.vm.qmp('block-job-complete', device='job0')
                self.assert_qmp(result, 'return', {})
            else:
                self.fail("Unexpected event: %s" % ev)
            log.append(iotests.filter_qmp_event(ev))

        self.maxDiff = None
        self.assertEqual(expected_events, log)

    def event_error(self, op, action):
        return {
            'event': 'BLOCK_JOB_ERROR',
            'data': {'action': action, 'device': 'job0', 'operation': op},
            'timestamp': {'microseconds': 'USECS', 'seconds': 'SECS'}
        }

    def event_ready(self):
        return {
            'event': 'BLOCK_JOB_READY',
            'data': {'device': 'job0',
                     'len': 524288,
                     'offset': 524288,
                     'speed': 0,
                     'type': 'commit'},
            'timestamp': {'microseconds': 'USECS', 'seconds': 'SECS'},
        }

    def event_completed(self, errmsg=None, active=True):
        max_len = 524288 if active else self.image_len
        data = {
            'device': 'job0',
            'len': max_len,
            'offset': 0 if errmsg else max_len,
            'speed': 0,
            'type': 'commit'
        }
        if errmsg:
            data['error'] = errmsg

        return {
            'event': 'BLOCK_JOB_COMPLETED',
            'data': data,
            'timestamp': {'microseconds': 'USECS', 'seconds': 'SECS'},
        }

    def blkdebug_event(self, event, is_raw=False):
        if event:
            return [{
                'event': event,
                'sector': 512 if is_raw else 1024,
                'once': True,
            }]
        return None

    def prepare_and_start_job(self, on_error, active=True,
                              top_event=None, mid_event=None, base_event=None):

        top_debug = self.blkdebug_event(top_event)
        mid_debug = self.blkdebug_event(mid_event)
        base_debug = self.blkdebug_event(base_event, True)

        self.add_block_nodes(top_debug=top_debug, mid_debug=mid_debug,
                             base_debug=base_debug)

        result = self.vm.qmp('block-commit', job_id='job0', device='top-fmt',
                             top_node='top-fmt' if active else 'mid-fmt',
                             base_node='mid-fmt' if active else 'base-fmt',
                             on_error=on_error)
        self.assert_qmp(result, 'return', {})

    def testActiveReadErrorReport(self):
        self.prepare_and_start_job('report', top_event='read_aio')
        self.run_job([
            self.event_error('read', 'report'),
            self.event_completed('Input/output error')
        ])

        self.vm.shutdown()
        self.assertFalse(iotests.compare_images(test_img, mid_img),
                         'target image matches source after error')

    def testActiveReadErrorStop(self):
        self.prepare_and_start_job('stop', top_event='read_aio')
        self.run_job([
            self.event_error('read', 'stop'),
            self.event_ready(),
            self.event_completed()
        ], error_pauses_job=True)

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

    def testActiveReadErrorIgnore(self):
        self.prepare_and_start_job('ignore', top_event='read_aio')
        self.run_job([
            self.event_error('read', 'ignore'),
            self.event_ready(),
            self.event_completed()
        ])

        # For commit, 'ignore' actually means retry, so this will succeed
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, mid_img),
                        'target image does not match source after commit')

    def testActiveWriteErrorReport(self):
        self.prepare_and_start_job('report', mid_event='write_aio')
        self.run_job([
            self.event_error('write', 'report'),
            self.event_completed('Input/output error')
        ])

        self.vm.shutdown()
        self.assertFalse(iotests.compare_images(test_img, mid_img),
                         'target image matches source after error')

    def testActiveWriteErrorStop(self):
        self.prepare_and_start_job('stop', mid_event='write_aio')
        self.run_job([
            self.event_error('write', 'stop'),
            self.event_ready(),
            self.event_completed()
        ], error_pauses_job=True)

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

    def testActiveWriteErrorIgnore(self):
        self.prepare_and_start_job('ignore', mid_event='write_aio')
        self.run_job([
            self.event_error('write', 'ignore'),
            self.event_ready(),
            self.event_completed()
        ])

        # For commit, 'ignore' actually means retry, so this will succeed
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(test_img, mid_img),
                        'target image does not match source after commit')

    def testIntermediateReadErrorReport(self):
        self.prepare_and_start_job('report', active=False, mid_event='read_aio')
        self.run_job([
            self.event_error('read', 'report'),
            self.event_completed('Input/output error', active=False)
        ])

        self.vm.shutdown()
        self.assertFalse(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
                         'target image matches source after error')

    def testIntermediateReadErrorStop(self):
        self.prepare_and_start_job('stop', active=False, mid_event='read_aio')
        self.run_job([
            self.event_error('read', 'stop'),
            self.event_completed(active=False)
        ], error_pauses_job=True)

        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
                        'target image does not match source after commit')

    def testIntermediateReadErrorIgnore(self):
        self.prepare_and_start_job('ignore', active=False, mid_event='read_aio')
        self.run_job([
            self.event_error('read', 'ignore'),
            self.event_completed(active=False)
        ])

        # For commit, 'ignore' actually means retry, so this will succeed
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
                        'target image does not match source after commit')

    def testIntermediateWriteErrorReport(self):
        self.prepare_and_start_job('report', active=False, base_event='write_aio')
        self.run_job([
            self.event_error('write', 'report'),
            self.event_completed('Input/output error', active=False)
        ])

        self.vm.shutdown()
        self.assertFalse(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
                         'target image matches source after error')

    def testIntermediateWriteErrorStop(self):
        self.prepare_and_start_job('stop', active=False, base_event='write_aio')
        self.run_job([
            self.event_error('write', 'stop'),
            self.event_completed(active=False)
        ], error_pauses_job=True)

        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
                        'target image does not match source after commit')

    def testIntermediateWriteErrorIgnore(self):
        self.prepare_and_start_job('ignore', active=False, base_event='write_aio')
        self.run_job([
            self.event_error('write', 'ignore'),
            self.event_completed(active=False)
        ])

        # For commit, 'ignore' actually means retry, so this will succeed
        self.vm.shutdown()
        self.assertTrue(iotests.compare_images(mid_img, backing_img, fmt2='raw'),
                        'target image does not match source after commit')

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