#!/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:
            self.vm.cmd('block-commit', device='drive0', top_node=top, base_node=base)
        else:
            self.vm.cmd('block-commit', device='drive0', top=top, base=base)
        self.wait_for_complete(need_ready)

    def run_default_commit_test(self):
        self.assert_no_active_block_jobs()
        self.vm.cmd('block-commit', device='drive0')
        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)
        if self.image_len:
            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)
        if not self.image_len:
            return
        qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img)
        qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img)

    def test_commit_node(self):
        self.run_commit_test("mid", "base", node_names=True)
        if not self.image_len:
            return
        qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img)
        qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img)

    @iotests.skip_if_unsupported(['throttle'])
    def test_commit_with_filter_and_quit(self):
        self.vm.cmd('object-add', qom_type='throttle-group', id='tg')

        # Add a filter outside of the backing chain
        self.vm.cmd('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid')

        self.vm.cmd('block-commit', device='drive0')

        # Quit immediately, thus forcing a simultaneous cancel of the
        # block job and a bdrv_drain_all()
        self.vm.cmd('quit')

    # 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):
        self.vm.cmd('object-add', qom_type='throttle-group', id='tg')

        self.vm.cmd('block-commit', device='drive0')

        # Add a filter outside of the backing chain
        self.vm.cmd('blockdev-add', driver='throttle', node_name='filter', throttle_group='tg', file='mid')

        # Quit immediately, thus forcing a simultaneous cancel of the
        # block job and a bdrv_drain_all()
        self.vm.cmd('quit')

    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)
        if not self.image_len:
            return
        qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img)
        qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img)

    def test_top_is_default_active(self):
        self.run_default_commit_test()
        if not self.image_len:
            return
        qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img)
        qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img)

    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()

        self.vm.cmd('blockdev-add', driver='null-co', node_name='null')

        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()
        self.vm.cmd('block-commit', device='drive0', top=mid_img,
                    base=backing_img, speed=(self.image_len // 4))
        self.vm.cmd('device_del', id='scsi0')

        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()
        self.vm.cmd('block-commit', device='drive0', top=mid_img,
                    base=backing_img, speed=(self.image_len // 4))

        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)
        qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs)
        qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs)

    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)
        qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs)
        qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs)

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

        # 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):
        self.vm.cmd('blockdev-add', **kwargs)

    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:
                    self.vm.cmd('block-job-resume', device='job0')
            elif ev['event'] == 'BLOCK_JOB_READY':
                self.vm.cmd('block-job-complete', device='job0')
            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)

        self.vm.cmd('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)

    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):
            qemu_io('-f', iotests.imgfmt,
                    '-c',
                    f'{read_or_write} -P {index + 1} {index}M 1M',
                    pattern_file)

    @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()

        self.vm.cmd('object-add', qom_type='throttle-group', id='tg')

        self.vm.cmd('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
                                    }
                                }
                            }
                        }
                    }
                }
            })

    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):
        self.vm.cmd('block-commit',
                    job_id='commit',
                    device='top-filter',
                    top_node='cow-2',
                    base_node='cow-1',
                    backing_file=self.img1)
        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 committed into 1
        self.pattern_files[2] = self.img1

    def test_commit_through_filter(self):
        self.vm.cmd('block-commit',
                    job_id='commit',
                    device='top-filter',
                    top_node='cow-1',
                    base_node='cow-0',
                    backing_file=self.img0)
        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 committed 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)
        self.vm.cmd('device_add', id='drv0', driver='scsi-hd',
                    bus='vio-scsi.0', drive='top-filter')

        # 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')

        self.vm.cmd('block-commit',
                    job_id='commit',
                    device='top-filter',
                    base_node='cow-2')
        self.complete_and_wait(drive='commit')

        # Try to release our reference to top-filter again
        self.vm.cmd('blockdev-del', node_name='top-filter')

        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 committed into 2
        self.pattern_files[3] = self.img2

    def test_filtered_active_commit_without_filter(self):
        self.vm.cmd('block-commit',
                    job_id='commit',
                    device='top-filter',
                    top_node='cow-3',
                    base_node='cow-2')
        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 committed 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
        self.vm.cmd('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
                            }
                        }
                    })

    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)
        self.vm.cmd('block-commit',
                    job_id='commit',
                    device='top',
                    base=self.img_base_b)

        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'])
