12d7abfbeSKevin Wolf#!/usr/bin/env python 2e8f6ea6fSKevin Wolf# 3e8f6ea6fSKevin Wolf# Test parallels and file image creation 4e8f6ea6fSKevin Wolf# 5e8f6ea6fSKevin Wolf# Copyright (C) 2018 Red Hat, Inc. 6e8f6ea6fSKevin Wolf# 72d7abfbeSKevin Wolf# Creator/Owner: Kevin Wolf <kwolf@redhat.com> 82d7abfbeSKevin Wolf# 9e8f6ea6fSKevin Wolf# This program is free software; you can redistribute it and/or modify 10e8f6ea6fSKevin Wolf# it under the terms of the GNU General Public License as published by 11e8f6ea6fSKevin Wolf# the Free Software Foundation; either version 2 of the License, or 12e8f6ea6fSKevin Wolf# (at your option) any later version. 13e8f6ea6fSKevin Wolf# 14e8f6ea6fSKevin Wolf# This program is distributed in the hope that it will be useful, 15e8f6ea6fSKevin Wolf# but WITHOUT ANY WARRANTY; without even the implied warranty of 16e8f6ea6fSKevin Wolf# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17e8f6ea6fSKevin Wolf# GNU General Public License for more details. 18e8f6ea6fSKevin Wolf# 19e8f6ea6fSKevin Wolf# You should have received a copy of the GNU General Public License 20e8f6ea6fSKevin Wolf# along with this program. If not, see <http://www.gnu.org/licenses/>. 21e8f6ea6fSKevin Wolf# 22e8f6ea6fSKevin Wolf 232d7abfbeSKevin Wolfimport iotests 242d7abfbeSKevin Wolffrom iotests import imgfmt 25e8f6ea6fSKevin Wolf 262d7abfbeSKevin Wolfiotests.verify_image_format(supported_fmts=['parallels']) 272d7abfbeSKevin Wolfiotests.verify_protocol(supported=['file']) 28e8f6ea6fSKevin Wolf 292d7abfbeSKevin Wolfdef blockdev_create(vm, options): 30*250c04f5SMax Reitz result = vm.qmp_log('blockdev-create', job_id='job0', options=options, 31*250c04f5SMax Reitz filters=[iotests.filter_qmp_testfiles]) 32e8f6ea6fSKevin Wolf 332d7abfbeSKevin Wolf if 'return' in result: 342d7abfbeSKevin Wolf assert result['return'] == {} 352d7abfbeSKevin Wolf vm.run_job('job0') 362d7abfbeSKevin Wolf iotests.log("") 37e8f6ea6fSKevin Wolf 382d7abfbeSKevin Wolfwith iotests.FilePath('t.parallels') as disk_path, \ 392d7abfbeSKevin Wolf iotests.VM() as vm: 40e8f6ea6fSKevin Wolf 412d7abfbeSKevin Wolf # 422d7abfbeSKevin Wolf # Successful image creation (defaults) 432d7abfbeSKevin Wolf # 442d7abfbeSKevin Wolf iotests.log("=== Successful image creation (defaults) ===") 452d7abfbeSKevin Wolf iotests.log("") 46e8f6ea6fSKevin Wolf 472d7abfbeSKevin Wolf size = 128 * 1024 * 1024 48e8f6ea6fSKevin Wolf 492d7abfbeSKevin Wolf vm.launch() 502d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': 'file', 512d7abfbeSKevin Wolf 'filename': disk_path, 522d7abfbeSKevin Wolf 'size': 0 }) 53e8f6ea6fSKevin Wolf 542d7abfbeSKevin Wolf vm.qmp_log('blockdev-add', driver='file', filename=disk_path, 55*250c04f5SMax Reitz node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) 56e8f6ea6fSKevin Wolf 572d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 582d7abfbeSKevin Wolf 'file': 'imgfile', 592d7abfbeSKevin Wolf 'size': size }) 602d7abfbeSKevin Wolf vm.shutdown() 61e8f6ea6fSKevin Wolf 622d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 63e8f6ea6fSKevin Wolf 642d7abfbeSKevin Wolf # 652d7abfbeSKevin Wolf # Successful image creation (explicit defaults) 662d7abfbeSKevin Wolf # 672d7abfbeSKevin Wolf iotests.log("=== Successful image creation (explicit defaults) ===") 682d7abfbeSKevin Wolf iotests.log("") 69e8f6ea6fSKevin Wolf 70e8f6ea6fSKevin Wolf # Choose a different size to show that we got a new image 712d7abfbeSKevin Wolf size = 64 * 1024 * 1024 72e8f6ea6fSKevin Wolf 732d7abfbeSKevin Wolf vm.launch() 742d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': 'file', 752d7abfbeSKevin Wolf 'filename': disk_path, 762d7abfbeSKevin Wolf 'size': 0 }) 772d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 782d7abfbeSKevin Wolf 'file': { 792d7abfbeSKevin Wolf 'driver': 'file', 802d7abfbeSKevin Wolf 'filename': disk_path, 81e8f6ea6fSKevin Wolf }, 822d7abfbeSKevin Wolf 'size': size, 832d7abfbeSKevin Wolf 'cluster-size': 1048576 }) 842d7abfbeSKevin Wolf vm.shutdown() 85e8f6ea6fSKevin Wolf 862d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 87e8f6ea6fSKevin Wolf 882d7abfbeSKevin Wolf # 892d7abfbeSKevin Wolf # Successful image creation (with non-default options) 902d7abfbeSKevin Wolf # 912d7abfbeSKevin Wolf iotests.log("=== Successful image creation (with non-default options) ===") 922d7abfbeSKevin Wolf iotests.log("") 93e8f6ea6fSKevin Wolf 94e8f6ea6fSKevin Wolf # Choose a different size to show that we got a new image 952d7abfbeSKevin Wolf size = 32 * 1024 * 1024 96e8f6ea6fSKevin Wolf 972d7abfbeSKevin Wolf vm.launch() 982d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': 'file', 992d7abfbeSKevin Wolf 'filename': disk_path, 1002d7abfbeSKevin Wolf 'size': 0 }) 1012d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1022d7abfbeSKevin Wolf 'file': { 1032d7abfbeSKevin Wolf 'driver': 'file', 1042d7abfbeSKevin Wolf 'filename': disk_path, 105e8f6ea6fSKevin Wolf }, 1062d7abfbeSKevin Wolf 'size': size, 1072d7abfbeSKevin Wolf 'cluster-size': 65536 }) 1082d7abfbeSKevin Wolf vm.shutdown() 109e8f6ea6fSKevin Wolf 1102d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 111e8f6ea6fSKevin Wolf 1122d7abfbeSKevin Wolf # 1132d7abfbeSKevin Wolf # Invalid BlockdevRef 1142d7abfbeSKevin Wolf # 1152d7abfbeSKevin Wolf iotests.log("=== Invalid BlockdevRef ===") 1162d7abfbeSKevin Wolf iotests.log("") 117e8f6ea6fSKevin Wolf 1182d7abfbeSKevin Wolf vm.launch() 1192d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1202d7abfbeSKevin Wolf 'file': "this doesn't exist", 1212d7abfbeSKevin Wolf 'size': size }) 1222d7abfbeSKevin Wolf vm.shutdown() 123e8f6ea6fSKevin Wolf 1242d7abfbeSKevin Wolf # 1252d7abfbeSKevin Wolf # Zero size 1262d7abfbeSKevin Wolf # 1272d7abfbeSKevin Wolf iotests.log("=== Zero size ===") 1282d7abfbeSKevin Wolf iotests.log("") 129e8f6ea6fSKevin Wolf 1302d7abfbeSKevin Wolf vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) 1312d7abfbeSKevin Wolf vm.launch() 1322d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1332d7abfbeSKevin Wolf 'file': 'node0', 1342d7abfbeSKevin Wolf 'size': 0 }) 1352d7abfbeSKevin Wolf vm.shutdown() 136e8f6ea6fSKevin Wolf 1372d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 138e8f6ea6fSKevin Wolf 1392d7abfbeSKevin Wolf # 1402d7abfbeSKevin Wolf # Maximum size 1412d7abfbeSKevin Wolf # 1422d7abfbeSKevin Wolf iotests.log("=== Maximum size ===") 1432d7abfbeSKevin Wolf iotests.log("") 144e8f6ea6fSKevin Wolf 1452d7abfbeSKevin Wolf vm.launch() 1462d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1472d7abfbeSKevin Wolf 'file': 'node0', 1482d7abfbeSKevin Wolf 'size': 4503599627369984}) 1492d7abfbeSKevin Wolf vm.shutdown() 150e8f6ea6fSKevin Wolf 1512d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 152e8f6ea6fSKevin Wolf 1532d7abfbeSKevin Wolf # 1542d7abfbeSKevin Wolf # Invalid sizes 1552d7abfbeSKevin Wolf # 156e8f6ea6fSKevin Wolf 157e8f6ea6fSKevin Wolf # TODO Negative image sizes aren't handled correctly, but this is a problem 1582d7abfbeSKevin Wolf # with QAPI's implementation of the 'size' type and affects other commands 1592d7abfbeSKevin Wolf # as well. Once this is fixed, we may want to add a test case here. 160e8f6ea6fSKevin Wolf 161e8f6ea6fSKevin Wolf # 1. Misaligned image size 162e8f6ea6fSKevin Wolf # 2. 2^64 - 512 163e8f6ea6fSKevin Wolf # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) 164e8f6ea6fSKevin Wolf # 4. 2^63 - 512 (generally valid, but with the image header the file will 165e8f6ea6fSKevin Wolf # exceed 63 bits) 166e8f6ea6fSKevin Wolf # 5. 2^52 (512 bytes more than maximum image size) 167e8f6ea6fSKevin Wolf 1682d7abfbeSKevin Wolf iotests.log("=== Invalid sizes ===") 1692d7abfbeSKevin Wolf iotests.log("") 170e8f6ea6fSKevin Wolf 1712d7abfbeSKevin Wolf vm.launch() 1722d7abfbeSKevin Wolf for size in [ 1234, 18446744073709551104, 9223372036854775808, 1732d7abfbeSKevin Wolf 9223372036854775296, 4503599627370497 ]: 1742d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1752d7abfbeSKevin Wolf 'file': 'node0', 1762d7abfbeSKevin Wolf 'size': size }) 1772d7abfbeSKevin Wolf vm.shutdown() 178e8f6ea6fSKevin Wolf 1792d7abfbeSKevin Wolf # 1802d7abfbeSKevin Wolf # Invalid cluster size 1812d7abfbeSKevin Wolf # 1822d7abfbeSKevin Wolf iotests.log("=== Invalid cluster size ===") 1832d7abfbeSKevin Wolf iotests.log("") 184e8f6ea6fSKevin Wolf 1852d7abfbeSKevin Wolf vm.launch() 1862d7abfbeSKevin Wolf for csize in [ 1234, 128, 4294967296, 9223372036854775808, 1872d7abfbeSKevin Wolf 18446744073709551104, 0 ]: 1882d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1892d7abfbeSKevin Wolf 'file': 'node0', 1902d7abfbeSKevin Wolf 'size': 67108864, 1912d7abfbeSKevin Wolf 'cluster-size': csize }) 1922d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 1932d7abfbeSKevin Wolf 'file': 'node0', 1942d7abfbeSKevin Wolf 'size': 281474976710656, 1952d7abfbeSKevin Wolf 'cluster-size': 512 }) 1962d7abfbeSKevin Wolf vm.shutdown() 197