#!/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('== 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)
