#!/usr/bin/env python
#
# Test vhdx and file image creation
#
# Copyright (C) 2018 Red Hat, Inc.
#
# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
#
# 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/>.
#

import iotests
from iotests import imgfmt

iotests.verify_image_format(supported_fmts=['vhdx'])
iotests.verify_protocol(supported=['file'])

def blockdev_create(vm, options):
    result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
                        filters=[iotests.filter_qmp_testfiles])

    if 'return' in result:
        assert result['return'] == {}
        vm.run_job('job0')
    iotests.log("")

with iotests.FilePath('t.vhdx') as disk_path, \
     iotests.VM() as vm:

    #
    # Successful image creation (defaults)
    #
    iotests.log("=== Successful image creation (defaults) ===")
    iotests.log("")

    size = 128 * 1024 * 1024

    vm.launch()
    blockdev_create(vm, { 'driver': 'file',
                          'filename': disk_path,
                          'size': 0 })

    vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
               node_name='imgfile', filters=[iotests.filter_qmp_testfiles])

    blockdev_create(vm, { 'driver': imgfmt,
                          'file': 'imgfile',
                          'size': size })
    vm.shutdown()

    iotests.img_info_log(disk_path)

    #
    # Successful image creation (explicit defaults)
    #
    iotests.log("=== Successful image creation (explicit defaults) ===")
    iotests.log("")

    # Choose a different size to show that we got a new image
    size = 64 * 1024 * 1024

    vm.launch()
    blockdev_create(vm, { 'driver': 'file',
                          'filename': disk_path,
                          'size': 0 })
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': {
                              'driver': 'file',
                              'filename': disk_path,
                          },
                          'size': size,
                          'log-size': 1048576,
                          'block-size': 8388608,
                          'subformat': 'dynamic',
                          'block-state-zero': True })
    vm.shutdown()

    iotests.img_info_log(disk_path)

    #
    # Successful image creation (with non-default options)
    #
    iotests.log("=== Successful image creation (with non-default options) ===")
    iotests.log("")

    # Choose a different size to show that we got a new image
    size = 32 * 1024 * 1024

    vm.launch()
    blockdev_create(vm, { 'driver': 'file',
                          'filename': disk_path,
                          'size': 0 })
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': {
                              'driver': 'file',
                              'filename': disk_path,
                          },
                          'size': size,
                          'log-size': 8388608,
                          'block-size': 268435456,
                          'subformat': 'fixed',
                          'block-state-zero': False })
    vm.shutdown()

    iotests.img_info_log(disk_path)

    #
    # Invalid BlockdevRef
    #
    iotests.log("=== Invalid BlockdevRef ===")
    iotests.log("")

    vm.launch()
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': "this doesn't exist",
                          'size': size })
    vm.shutdown()

    #
    # Zero size
    #
    iotests.log("=== Zero size ===")
    iotests.log("")

    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
    vm.launch()
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': 'node0',
                          'size': 0 })
    vm.shutdown()

    iotests.img_info_log(disk_path)

    #
    # Maximum size
    #
    iotests.log("=== Maximum size ===")
    iotests.log("")

    vm.launch()
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': 'node0',
                          'size': 70368744177664 })
    vm.shutdown()

    iotests.img_info_log(disk_path)

    #
    # Invalid sizes
    #

    # TODO Negative image sizes aren't handled correctly, but this is a problem
    # with QAPI's implementation of the 'size' type and affects other commands
    # as well. Once this is fixed, we may want to add a test case here.

    # 1. 2^64 - 512
    # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
    # 3. 2^63 - 512 (generally valid, but with the image header the file will
    #                exceed 63 bits)
    # 4. 2^46 + 1 (one byte more than maximum image size)

    iotests.log("=== Invalid sizes ===")
    iotests.log("")

    vm.launch()
    for size in [ 18446744073709551104, 9223372036854775808,
                  9223372036854775296, 70368744177665 ]:
        blockdev_create(vm, { 'driver': imgfmt,
                              'file': 'node0',
                              'size': size })
    vm.shutdown()

    #
    # Invalid block size
    #
    iotests.log("=== Invalid block size ===")
    iotests.log("")

    vm.launch()
    for bsize in [ 1234567, 128, 3145728, 536870912, 0 ]:
        blockdev_create(vm, { 'driver': imgfmt,
                              'file': 'node0',
                              'size': 67108864,
                              'block-size': bsize })
    vm.shutdown()

    #
    # Invalid log size
    #
    iotests.log("=== Invalid log size ===")
    iotests.log("")

    vm.launch()
    for lsize in [ 1234567, 128, 4294967296, 0 ]:
        blockdev_create(vm, { 'driver': imgfmt,
                              'file': 'node0',
                              'size': 67108864,
                              'log-size': lsize })
    vm.shutdown()
