#!/usr/bin/env python3
# group: rw backing
#
# Copyright (C) 2019 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
#
# Some tests for short backing files and short overlays

import iotests

iotests.script_initialize(supported_fmts=['qcow2'],
                          supported_platforms=['linux'])

size_short = 1 * 1024 * 1024
size_long = 2 * 1024 * 1024
size_diff = size_long - size_short

def create_chain() -> None:
    iotests.qemu_img_log('create', '-f', iotests.imgfmt, base,
                         str(size_long))
    iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base,
                         '-F', iotests.imgfmt, mid, str(size_short))
    iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', mid,
                         '-F', iotests.imgfmt, top, str(size_long))

    iotests.qemu_io_log('-c', 'write -P 1 0 %d' % size_long, base)

def create_vm() -> iotests.VM:
    vm = iotests.VM()
    vm.add_blockdev('file,filename=%s,node-name=base-file' % base)
    vm.add_blockdev('%s,file=base-file,node-name=base' % iotests.imgfmt)
    vm.add_blockdev('file,filename=%s,node-name=mid-file' % mid)
    vm.add_blockdev('%s,file=mid-file,node-name=mid,backing=base'
                    % iotests.imgfmt)
    vm.add_drive(top, 'backing=mid,node-name=top')
    return vm

with iotests.FilePath('base') as base, \
     iotests.FilePath('mid') as mid, \
     iotests.FilePath('top') as top:

    iotests.log('== Commit tests ==')

    create_chain()

    iotests.log('=== Check visible data ===')

    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, top)
    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), top)

    iotests.log('=== Checking allocation status ===')

    iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
                        '-c', 'alloc %d %d' % (size_short, size_diff),
                        base)

    iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
                        '-c', 'alloc %d %d' % (size_short, size_diff),
                        mid)

    iotests.qemu_io_log('-c', 'alloc 0 %d' % size_short,
                        '-c', 'alloc %d %d' % (size_short, size_diff),
                        top)

    iotests.log('=== Checking map ===')

    iotests.qemu_img_log('map', '--output=json', base)
    iotests.qemu_img_log('map', '--output=human', base)
    iotests.qemu_img_log('map', '--output=json', mid)
    iotests.qemu_img_log('map', '--output=human', mid)
    iotests.qemu_img_log('map', '--output=json', top)
    iotests.qemu_img_log('map', '--output=human', top)

    iotests.log('=== Testing qemu-img commit (top -> mid) ===')

    iotests.qemu_img_log('commit', top)
    iotests.img_info_log(mid)
    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)

    iotests.log('=== Testing HMP commit (top -> mid) ===')

    create_chain()
    with create_vm() as vm:
        vm.launch()
        vm.qmp_log('human-monitor-command', command_line='commit drive0')

    iotests.img_info_log(mid)
    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)

    iotests.log('=== Testing QMP active commit (top -> mid) ===')

    create_chain()
    with create_vm() as vm:
        vm.launch()
        vm.qmp_log('block-commit', device='top', base_node='mid',
                   job_id='job0', auto_dismiss=False)
        vm.run_job('job0', wait=5)

    iotests.img_info_log(mid)
    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, mid)
    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), mid)

    iotests.log('=== Testing qemu-img commit (top -> base) ===')

    create_chain()
    iotests.qemu_img_log('commit', '-b', base, top)
    iotests.img_info_log(base)
    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, base)
    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), base)

    iotests.log('=== Testing QMP active commit (top -> base) ===')

    create_chain()
    with create_vm() as vm:
        vm.launch()
        vm.qmp_log('block-commit', device='top', base_node='base',
                   job_id='job0', auto_dismiss=False)
        vm.run_job('job0', wait=5)

    iotests.img_info_log(mid)
    iotests.qemu_io_log('-c', 'read -P 1 0 %d' % size_short, base)
    iotests.qemu_io_log('-c', 'read -P 0 %d %d' % (size_short, size_diff), base)

    iotests.log('== Resize tests ==')

    # Use different sizes for different allocation modes:
    #
    # We want to have at least one test where 32 bit truncation in the size of
    # the overlapping area becomes visible. This is covered by the
    # prealloc='off' case (1G to 6G is an overlap of 5G).
    #
    # However, we can only do this for modes that don't preallocate data
    # because otherwise we might run out of space on the test host.
    #
    # We also want to test some unaligned combinations.
    for (prealloc, base_size, top_size_old, top_size_new, off) in [
            ('off',       '6G',    '1G',   '8G',   '5G'),
            ('metadata', '32G',   '30G',  '33G',  '31G'),
            ('falloc',   '10M',    '5M',  '15M',   '9M'),
            ('full',     '16M',    '8M',  '12M',  '11M'),
            ('off',      '384k', '253k', '512k', '253k'),
            ('off',      '400k', '256k', '512k', '336k'),
            ('off',      '512k', '256k', '500k', '436k')]:

        iotests.log('=== preallocation=%s ===' % prealloc)
        iotests.qemu_img_log('create', '-f', iotests.imgfmt, base, base_size)
        iotests.qemu_img_log('create', '-f', iotests.imgfmt, '-b', base,
                             '-F', iotests.imgfmt, top, top_size_old)
        iotests.qemu_io_log('-c', 'write -P 1 %s 64k' % off, base)

        # After this, top_size_old to base_size should be allocated/zeroed.
        #
        # In theory, leaving base_size to top_size_new unallocated would be
        # correct, but in practice, if we zero out anything, we zero out
        # everything up to top_size_new.
        iotests.qemu_img_log('resize', '-f', iotests.imgfmt,
                             '--preallocation', prealloc, top, top_size_new)
        iotests.qemu_io_log('-c', 'read -P 0 %s 64k' % off, top)
        iotests.qemu_io_log('-c', 'map', top)
        iotests.qemu_img_log('map', '--output=json', top)
