#!/usr/bin/env python3
#
# 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)
