#!/usr/bin/env python3
# group: rw auto
#
# 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, '-F', 'raw', mid_img)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % mid_img,
                 '-F', iotests.imgfmt, 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('virtio-scsi')
        self.vm.add_device("scsi-hd,id=scsi0,drive=drive0")
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        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', {})

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

    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', "Can't find '%s' in the backing chain" % 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', "Can't find 'badfile' in the backing chain")

    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', "Can't find '%s' in the backing chain" % 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,
                 '-F', 'raw', self.mid_img_abs)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % self.mid_img_abs,
                 '-F', iotests.imgfmt, self.test_img)
        qemu_img('rebase', '-u', '-b', self.backing_img,
                 '-F', 'raw', self.mid_img_abs)
        qemu_img('rebase', '-u', '-b', self.mid_img,
                 '-F', iotests.imgfmt, 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', "Can't find '%s' in the backing chain" % 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', "Can't find 'badfile' in the backing chain")

    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', "Can't find '%s' in the backing chain" % 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, '-F', 'raw', mid_img)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % mid_img,
                 '-F', iotests.imgfmt, 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, '-F', 'raw', self.img1)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % self.img1,
                 '-F', iotests.imgfmt, self.img2)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % self.img2,
                 '-F', iotests.imgfmt, 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,
                 '-F', 'raw', mid_img)
        qemu_img('create', '-f', iotests.imgfmt,
                 '-o', 'backing_file=%s' % mid_img,
                 '-F', iotests.imgfmt, 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')

class TestCommitWithFilters(iotests.QMPTestCase):
    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 do_test_io(self, read_or_write):
        for index, pattern_file in enumerate(self.pattern_files):
            result = qemu_io('-f', iotests.imgfmt,
                             '-c',
                             f'{read_or_write} -P {index + 1} {index}M 1M',
                             pattern_file)
            self.assertFalse('Pattern verification failed' in result)

    @iotests.skip_if_unsupported(['throttle'])
    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, self.img0, '64M')
        qemu_img('create', '-f', iotests.imgfmt, self.img1, '64M')
        qemu_img('create', '-f', iotests.imgfmt, self.img2, '64M')
        qemu_img('create', '-f', iotests.imgfmt, self.img3, '64M')

        # Distributions of the patterns in the files; this is checked
        # by tearDown() and should be changed by the test cases as is
        # necessary
        self.pattern_files = [self.img0, self.img1, self.img2, self.img3]

        self.do_test_io('write')

        self.vm = iotests.VM().add_device('virtio-scsi,id=vio-scsi')
        self.vm.launch()

        result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg')
        self.assert_qmp(result, 'return', {})

        result = self.vm.qmp('blockdev-add', **{
                'node-name': 'top-filter',
                'driver': 'throttle',
                'throttle-group': 'tg',
                'file': {
                    'node-name': 'cow-3',
                    'driver': iotests.imgfmt,
                    'file': {
                        'driver': 'file',
                        'filename': self.img3
                    },
                    'backing': {
                        'node-name': 'cow-2',
                        'driver': iotests.imgfmt,
                        'file': {
                            'driver': 'file',
                            'filename': self.img2
                        },
                        'backing': {
                            'node-name': 'cow-1',
                            'driver': iotests.imgfmt,
                            'file': {
                                'driver': 'file',
                                'filename': self.img1
                            },
                            'backing': {
                                'node-name': 'bottom-filter',
                                'driver': 'throttle',
                                'throttle-group': 'tg',
                                'file': {
                                    'node-name': 'cow-0',
                                    'driver': iotests.imgfmt,
                                    'file': {
                                        'driver': 'file',
                                        'filename': self.img0
                                    }
                                }
                            }
                        }
                    }
                }
            })
        self.assert_qmp(result, 'return', {})

    def tearDown(self):
        self.vm.shutdown()
        self.do_test_io('read')

        os.remove(self.img3)
        os.remove(self.img2)
        os.remove(self.img1)
        os.remove(self.img0)

    # Filters make for funny filenames, so we cannot just use
    # self.imgX to get them
    def get_filename(self, node):
        return self.vm.node_info(node)['image']['filename']

    def test_filterless_commit(self):
        result = self.vm.qmp('block-commit',
                             job_id='commit',
                             device='top-filter',
                             top_node='cow-2',
                             base_node='cow-1')
        self.assert_qmp(result, 'return', {})
        self.wait_until_completed(drive='commit')

        self.assertIsNotNone(self.vm.node_info('cow-3'))
        self.assertIsNone(self.vm.node_info('cow-2'))
        self.assertIsNotNone(self.vm.node_info('cow-1'))

        # 2 has been comitted into 1
        self.pattern_files[2] = self.img1

    def test_commit_through_filter(self):
        result = self.vm.qmp('block-commit',
                             job_id='commit',
                             device='top-filter',
                             top_node='cow-1',
                             base_node='cow-0')
        self.assert_qmp(result, 'return', {})
        self.wait_until_completed(drive='commit')

        self.assertIsNotNone(self.vm.node_info('cow-2'))
        self.assertIsNone(self.vm.node_info('cow-1'))
        self.assertIsNone(self.vm.node_info('bottom-filter'))
        self.assertIsNotNone(self.vm.node_info('cow-0'))

        # 1 has been comitted into 0
        self.pattern_files[1] = self.img0

    def test_filtered_active_commit_with_filter(self):
        # Add a device, so the commit job finds a parent it can change
        # to point to the base node (so we can test that top-filter is
        # dropped from the graph)
        result = self.vm.qmp('device_add', id='drv0', driver='scsi-hd',
                             bus='vio-scsi.0', drive='top-filter')
        self.assert_qmp(result, 'return', {})

        # Try to release our reference to top-filter; that should not
        # work because drv0 uses it
        result = self.vm.qmp('blockdev-del', node_name='top-filter')
        self.assert_qmp(result, 'error/class', 'GenericError')
        self.assert_qmp(result, 'error/desc', 'Node top-filter is in use')

        result = self.vm.qmp('block-commit',
                             job_id='commit',
                             device='top-filter',
                             base_node='cow-2')
        self.assert_qmp(result, 'return', {})
        self.complete_and_wait(drive='commit')

        # Try to release our reference to top-filter again
        result = self.vm.qmp('blockdev-del', node_name='top-filter')
        self.assert_qmp(result, 'return', {})

        self.assertIsNone(self.vm.node_info('top-filter'))
        self.assertIsNone(self.vm.node_info('cow-3'))
        self.assertIsNotNone(self.vm.node_info('cow-2'))

        # Check that drv0 is now connected to cow-2
        blockdevs = self.vm.qmp('query-block')['return']
        drv0 = next(dev for dev in blockdevs if dev['qdev'] == 'drv0')
        self.assertEqual(drv0['inserted']['node-name'], 'cow-2')

        # 3 has been comitted into 2
        self.pattern_files[3] = self.img2

    def test_filtered_active_commit_without_filter(self):
        result = self.vm.qmp('block-commit',
                             job_id='commit',
                             device='top-filter',
                             top_node='cow-3',
                             base_node='cow-2')
        self.assert_qmp(result, 'return', {})
        self.complete_and_wait(drive='commit')

        self.assertIsNotNone(self.vm.node_info('top-filter'))
        self.assertIsNone(self.vm.node_info('cow-3'))
        self.assertIsNotNone(self.vm.node_info('cow-2'))

        # 3 has been comitted into 2
        self.pattern_files[3] = self.img2

class TestCommitWithOverriddenBacking(iotests.QMPTestCase):
    img_base_a = os.path.join(iotests.test_dir, 'base_a.img')
    img_base_b = os.path.join(iotests.test_dir, 'base_b.img')
    img_top = os.path.join(iotests.test_dir, 'top.img')

    def setUp(self):
        qemu_img('create', '-f', iotests.imgfmt, self.img_base_a, '1M')
        qemu_img('create', '-f', iotests.imgfmt, self.img_base_b, '1M')
        qemu_img('create', '-f', iotests.imgfmt, '-b', self.img_base_a,
                 '-F', iotests.imgfmt, self.img_top)

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

        # Use base_b instead of base_a as the backing of top
        result = self.vm.qmp('blockdev-add', **{
                                'node-name': 'top',
                                'driver': iotests.imgfmt,
                                'file': {
                                    'driver': 'file',
                                    'filename': self.img_top
                                },
                                'backing': {
                                    'node-name': 'base',
                                    'driver': iotests.imgfmt,
                                    'file': {
                                        'driver': 'file',
                                        'filename': self.img_base_b
                                    }
                                }
                            })
        self.assert_qmp(result, 'return', {})

    def tearDown(self):
        self.vm.shutdown()
        os.remove(self.img_top)
        os.remove(self.img_base_a)
        os.remove(self.img_base_b)

    def test_commit_to_a(self):
        # Try committing to base_a (which should fail, as top's
        # backing image is base_b instead)
        result = self.vm.qmp('block-commit',
                             job_id='commit',
                             device='top',
                             base=self.img_base_a)
        self.assert_qmp(result, 'error/class', 'GenericError')

    def test_commit_to_b(self):
        # Try committing to base_b (which should work, since that is
        # actually top's backing image)
        result = self.vm.qmp('block-commit',
                             job_id='commit',
                             device='top',
                             base=self.img_base_b)
        self.assert_qmp(result, 'return', {})

        self.vm.event_wait('BLOCK_JOB_READY')
        self.vm.qmp('block-job-complete', device='commit')
        self.vm.event_wait('BLOCK_JOB_COMPLETED')

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