#!/usr/bin/env python
#
# Test vmdk 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 math
import iotests
from iotests import imgfmt

iotests.verify_image_format(supported_fmts=['vmdk'])

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.vmdk') as disk_path, \
     iotests.FilePath('t.vmdk.1') as extent1_path, \
     iotests.FilePath('t.vmdk.2') as extent2_path, \
     iotests.FilePath('t.vmdk.3') as extent3_path, \
     iotests.VM() as vm:

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

    size = 5 * 1024 * 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 (inline blockdev-add, explicit defaults)
    #
    iotests.log("=== Successful image creation (inline blockdev-add, 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,
                          'extents': [],
                          'subformat': 'monolithicSparse',
                          'adapter-type': 'ide',
                          'hwversion': '4',
                          'zeroed-grain': False })
    vm.shutdown()

    iotests.img_info_log(disk_path)

    #
    # Successful image creation (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,
                          'extents': [],
                          'subformat': 'monolithicSparse',
                          'adapter-type': 'buslogic',
                          'zeroed-grain': True })
    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()

    #
    # Adapter types
    #

    iotests.log("=== Adapter types ===")
    iotests.log("")

    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))

    # Valid
    iotests.log("== Valid adapter types ==")
    iotests.log("")

    vm.launch()
    for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]:
        blockdev_create(vm, { 'driver': imgfmt,
                              'file': 'node0',
                              'size': size,
                              'adapter-type': adapter_type })
    vm.shutdown()

    # Invalid
    iotests.log("== Invalid adapter types ==")
    iotests.log("")

    vm.launch()
    for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]:
        blockdev_create(vm, { 'driver': imgfmt,
                              'file': 'node0',
                              'size': size,
                              'adapter-type': adapter_type })
    vm.shutdown()

    #
    # Other subformats
    #
    iotests.log("=== Other subformats ===")
    iotests.log("")

    for path in [ extent1_path, extent2_path, extent3_path ]:
        msg = iotests.qemu_img_pipe('create', '-f', imgfmt, path, '0')
        iotests.log(msg, [iotests.filter_testfiles])

    vm.add_blockdev('driver=file,filename=%s,node-name=ext1' % (extent1_path))
    vm.add_blockdev('driver=file,filename=%s,node-name=ext2' % (extent2_path))
    vm.add_blockdev('driver=file,filename=%s,node-name=ext3' % (extent3_path))

    # Missing extent
    iotests.log("== Missing extent ==")
    iotests.log("")

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

    # Correct extent
    iotests.log("== Correct extent ==")
    iotests.log("")

    vm.launch()
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': 'node0',
                          'size': size,
                          'subformat': 'monolithicFlat',
                          'extents': ['ext1'] })
    vm.shutdown()

    # Extra extent
    iotests.log("== Extra extent ==")
    iotests.log("")

    vm.launch()
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': 'node0',
                          'size': 512,
                          'subformat': 'monolithicFlat',
                          'extents': ['ext1', 'ext2', 'ext3'] })
    vm.shutdown()

    # Split formats
    iotests.log("== Split formats ==")
    iotests.log("")

    for size in [ 512, 1073741824, 2147483648, 5368709120 ]:
        for subfmt in [ 'twoGbMaxExtentFlat', 'twoGbMaxExtentSparse' ]:
            iotests.log("= %s %d =" % (subfmt, size))
            iotests.log("")

            num_extents = int(math.ceil(size / 2.0**31))
            extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ]

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

            iotests.img_info_log(disk_path)
