1*2d7abfbeSKevin 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# 7*2d7abfbeSKevin Wolf# Creator/Owner: Kevin Wolf <kwolf@redhat.com> 8*2d7abfbeSKevin 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 23*2d7abfbeSKevin Wolfimport iotests 24*2d7abfbeSKevin Wolffrom iotests import imgfmt 25e8f6ea6fSKevin Wolf 26*2d7abfbeSKevin Wolfiotests.verify_image_format(supported_fmts=['parallels']) 27*2d7abfbeSKevin Wolfiotests.verify_protocol(supported=['file']) 28e8f6ea6fSKevin Wolf 29*2d7abfbeSKevin Wolfdef blockdev_create(vm, options): 30*2d7abfbeSKevin Wolf result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options) 31e8f6ea6fSKevin Wolf 32*2d7abfbeSKevin Wolf if 'return' in result: 33*2d7abfbeSKevin Wolf assert result['return'] == {} 34*2d7abfbeSKevin Wolf vm.run_job('job0') 35*2d7abfbeSKevin Wolf iotests.log("") 36e8f6ea6fSKevin Wolf 37*2d7abfbeSKevin Wolfwith iotests.FilePath('t.parallels') as disk_path, \ 38*2d7abfbeSKevin Wolf iotests.VM() as vm: 39e8f6ea6fSKevin Wolf 40*2d7abfbeSKevin Wolf # 41*2d7abfbeSKevin Wolf # Successful image creation (defaults) 42*2d7abfbeSKevin Wolf # 43*2d7abfbeSKevin Wolf iotests.log("=== Successful image creation (defaults) ===") 44*2d7abfbeSKevin Wolf iotests.log("") 45e8f6ea6fSKevin Wolf 46*2d7abfbeSKevin Wolf size = 128 * 1024 * 1024 47e8f6ea6fSKevin Wolf 48*2d7abfbeSKevin Wolf vm.launch() 49*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': 'file', 50*2d7abfbeSKevin Wolf 'filename': disk_path, 51*2d7abfbeSKevin Wolf 'size': 0 }) 52e8f6ea6fSKevin Wolf 53*2d7abfbeSKevin Wolf vm.qmp_log('blockdev-add', driver='file', filename=disk_path, 54*2d7abfbeSKevin Wolf node_name='imgfile') 55e8f6ea6fSKevin Wolf 56*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 57*2d7abfbeSKevin Wolf 'file': 'imgfile', 58*2d7abfbeSKevin Wolf 'size': size }) 59*2d7abfbeSKevin Wolf vm.shutdown() 60e8f6ea6fSKevin Wolf 61*2d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 62e8f6ea6fSKevin Wolf 63*2d7abfbeSKevin Wolf # 64*2d7abfbeSKevin Wolf # Successful image creation (explicit defaults) 65*2d7abfbeSKevin Wolf # 66*2d7abfbeSKevin Wolf iotests.log("=== Successful image creation (explicit defaults) ===") 67*2d7abfbeSKevin Wolf iotests.log("") 68e8f6ea6fSKevin Wolf 69e8f6ea6fSKevin Wolf # Choose a different size to show that we got a new image 70*2d7abfbeSKevin Wolf size = 64 * 1024 * 1024 71e8f6ea6fSKevin Wolf 72*2d7abfbeSKevin Wolf vm.launch() 73*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': 'file', 74*2d7abfbeSKevin Wolf 'filename': disk_path, 75*2d7abfbeSKevin Wolf 'size': 0 }) 76*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 77*2d7abfbeSKevin Wolf 'file': { 78*2d7abfbeSKevin Wolf 'driver': 'file', 79*2d7abfbeSKevin Wolf 'filename': disk_path, 80e8f6ea6fSKevin Wolf }, 81*2d7abfbeSKevin Wolf 'size': size, 82*2d7abfbeSKevin Wolf 'cluster-size': 1048576 }) 83*2d7abfbeSKevin Wolf vm.shutdown() 84e8f6ea6fSKevin Wolf 85*2d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 86e8f6ea6fSKevin Wolf 87*2d7abfbeSKevin Wolf # 88*2d7abfbeSKevin Wolf # Successful image creation (with non-default options) 89*2d7abfbeSKevin Wolf # 90*2d7abfbeSKevin Wolf iotests.log("=== Successful image creation (with non-default options) ===") 91*2d7abfbeSKevin Wolf iotests.log("") 92e8f6ea6fSKevin Wolf 93e8f6ea6fSKevin Wolf # Choose a different size to show that we got a new image 94*2d7abfbeSKevin Wolf size = 32 * 1024 * 1024 95e8f6ea6fSKevin Wolf 96*2d7abfbeSKevin Wolf vm.launch() 97*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': 'file', 98*2d7abfbeSKevin Wolf 'filename': disk_path, 99*2d7abfbeSKevin Wolf 'size': 0 }) 100*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 101*2d7abfbeSKevin Wolf 'file': { 102*2d7abfbeSKevin Wolf 'driver': 'file', 103*2d7abfbeSKevin Wolf 'filename': disk_path, 104e8f6ea6fSKevin Wolf }, 105*2d7abfbeSKevin Wolf 'size': size, 106*2d7abfbeSKevin Wolf 'cluster-size': 65536 }) 107*2d7abfbeSKevin Wolf vm.shutdown() 108e8f6ea6fSKevin Wolf 109*2d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 110e8f6ea6fSKevin Wolf 111*2d7abfbeSKevin Wolf # 112*2d7abfbeSKevin Wolf # Invalid BlockdevRef 113*2d7abfbeSKevin Wolf # 114*2d7abfbeSKevin Wolf iotests.log("=== Invalid BlockdevRef ===") 115*2d7abfbeSKevin Wolf iotests.log("") 116e8f6ea6fSKevin Wolf 117*2d7abfbeSKevin Wolf vm.launch() 118*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 119*2d7abfbeSKevin Wolf 'file': "this doesn't exist", 120*2d7abfbeSKevin Wolf 'size': size }) 121*2d7abfbeSKevin Wolf vm.shutdown() 122e8f6ea6fSKevin Wolf 123*2d7abfbeSKevin Wolf # 124*2d7abfbeSKevin Wolf # Zero size 125*2d7abfbeSKevin Wolf # 126*2d7abfbeSKevin Wolf iotests.log("=== Zero size ===") 127*2d7abfbeSKevin Wolf iotests.log("") 128e8f6ea6fSKevin Wolf 129*2d7abfbeSKevin Wolf vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path)) 130*2d7abfbeSKevin Wolf vm.launch() 131*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 132*2d7abfbeSKevin Wolf 'file': 'node0', 133*2d7abfbeSKevin Wolf 'size': 0 }) 134*2d7abfbeSKevin Wolf vm.shutdown() 135e8f6ea6fSKevin Wolf 136*2d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 137e8f6ea6fSKevin Wolf 138*2d7abfbeSKevin Wolf # 139*2d7abfbeSKevin Wolf # Maximum size 140*2d7abfbeSKevin Wolf # 141*2d7abfbeSKevin Wolf iotests.log("=== Maximum size ===") 142*2d7abfbeSKevin Wolf iotests.log("") 143e8f6ea6fSKevin Wolf 144*2d7abfbeSKevin Wolf vm.launch() 145*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 146*2d7abfbeSKevin Wolf 'file': 'node0', 147*2d7abfbeSKevin Wolf 'size': 4503599627369984}) 148*2d7abfbeSKevin Wolf vm.shutdown() 149e8f6ea6fSKevin Wolf 150*2d7abfbeSKevin Wolf iotests.img_info_log(disk_path) 151e8f6ea6fSKevin Wolf 152*2d7abfbeSKevin Wolf # 153*2d7abfbeSKevin Wolf # Invalid sizes 154*2d7abfbeSKevin Wolf # 155e8f6ea6fSKevin Wolf 156e8f6ea6fSKevin Wolf # TODO Negative image sizes aren't handled correctly, but this is a problem 157*2d7abfbeSKevin Wolf # with QAPI's implementation of the 'size' type and affects other commands 158*2d7abfbeSKevin Wolf # as well. Once this is fixed, we may want to add a test case here. 159e8f6ea6fSKevin Wolf 160e8f6ea6fSKevin Wolf # 1. Misaligned image size 161e8f6ea6fSKevin Wolf # 2. 2^64 - 512 162e8f6ea6fSKevin Wolf # 3. 2^63 = 8 EB (qemu-img enforces image sizes less than this) 163e8f6ea6fSKevin Wolf # 4. 2^63 - 512 (generally valid, but with the image header the file will 164e8f6ea6fSKevin Wolf # exceed 63 bits) 165e8f6ea6fSKevin Wolf # 5. 2^52 (512 bytes more than maximum image size) 166e8f6ea6fSKevin Wolf 167*2d7abfbeSKevin Wolf iotests.log("=== Invalid sizes ===") 168*2d7abfbeSKevin Wolf iotests.log("") 169e8f6ea6fSKevin Wolf 170*2d7abfbeSKevin Wolf vm.launch() 171*2d7abfbeSKevin Wolf for size in [ 1234, 18446744073709551104, 9223372036854775808, 172*2d7abfbeSKevin Wolf 9223372036854775296, 4503599627370497 ]: 173*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 174*2d7abfbeSKevin Wolf 'file': 'node0', 175*2d7abfbeSKevin Wolf 'size': size }) 176*2d7abfbeSKevin Wolf vm.shutdown() 177e8f6ea6fSKevin Wolf 178*2d7abfbeSKevin Wolf # 179*2d7abfbeSKevin Wolf # Invalid cluster size 180*2d7abfbeSKevin Wolf # 181*2d7abfbeSKevin Wolf iotests.log("=== Invalid cluster size ===") 182*2d7abfbeSKevin Wolf iotests.log("") 183e8f6ea6fSKevin Wolf 184*2d7abfbeSKevin Wolf vm.launch() 185*2d7abfbeSKevin Wolf for csize in [ 1234, 128, 4294967296, 9223372036854775808, 186*2d7abfbeSKevin Wolf 18446744073709551104, 0 ]: 187*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 188*2d7abfbeSKevin Wolf 'file': 'node0', 189*2d7abfbeSKevin Wolf 'size': 67108864, 190*2d7abfbeSKevin Wolf 'cluster-size': csize }) 191*2d7abfbeSKevin Wolf blockdev_create(vm, { 'driver': imgfmt, 192*2d7abfbeSKevin Wolf 'file': 'node0', 193*2d7abfbeSKevin Wolf 'size': 281474976710656, 194*2d7abfbeSKevin Wolf 'cluster-size': 512 }) 195*2d7abfbeSKevin Wolf vm.shutdown() 196