1*44c7ca5eSPaolo Bonzini#!/usr/bin/env python 2*44c7ca5eSPaolo Bonzini# 3*44c7ca5eSPaolo Bonzini# Tests for image mirroring. 4*44c7ca5eSPaolo Bonzini# 5*44c7ca5eSPaolo Bonzini# Copyright (C) 2012 Red Hat, Inc. 6*44c7ca5eSPaolo Bonzini# 7*44c7ca5eSPaolo Bonzini# This program is free software; you can redistribute it and/or modify 8*44c7ca5eSPaolo Bonzini# it under the terms of the GNU General Public License as published by 9*44c7ca5eSPaolo Bonzini# the Free Software Foundation; either version 2 of the License, or 10*44c7ca5eSPaolo Bonzini# (at your option) any later version. 11*44c7ca5eSPaolo Bonzini# 12*44c7ca5eSPaolo Bonzini# This program is distributed in the hope that it will be useful, 13*44c7ca5eSPaolo Bonzini# but WITHOUT ANY WARRANTY; without even the implied warranty of 14*44c7ca5eSPaolo Bonzini# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*44c7ca5eSPaolo Bonzini# GNU General Public License for more details. 16*44c7ca5eSPaolo Bonzini# 17*44c7ca5eSPaolo Bonzini# You should have received a copy of the GNU General Public License 18*44c7ca5eSPaolo Bonzini# along with this program. If not, see <http://www.gnu.org/licenses/>. 19*44c7ca5eSPaolo Bonzini# 20*44c7ca5eSPaolo Bonzini 21*44c7ca5eSPaolo Bonziniimport time 22*44c7ca5eSPaolo Bonziniimport os 23*44c7ca5eSPaolo Bonziniimport iotests 24*44c7ca5eSPaolo Bonzinifrom iotests import qemu_img, qemu_io 25*44c7ca5eSPaolo Bonziniimport struct 26*44c7ca5eSPaolo Bonzini 27*44c7ca5eSPaolo Bonzinibacking_img = os.path.join(iotests.test_dir, 'backing.img') 28*44c7ca5eSPaolo Bonzinitarget_backing_img = os.path.join(iotests.test_dir, 'target-backing.img') 29*44c7ca5eSPaolo Bonzinitest_img = os.path.join(iotests.test_dir, 'test.img') 30*44c7ca5eSPaolo Bonzinitarget_img = os.path.join(iotests.test_dir, 'target.img') 31*44c7ca5eSPaolo Bonzini 32*44c7ca5eSPaolo Bonziniclass ImageMirroringTestCase(iotests.QMPTestCase): 33*44c7ca5eSPaolo Bonzini '''Abstract base class for image mirroring test cases''' 34*44c7ca5eSPaolo Bonzini 35*44c7ca5eSPaolo Bonzini def assert_no_active_mirrors(self): 36*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block-jobs') 37*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', []) 38*44c7ca5eSPaolo Bonzini 39*44c7ca5eSPaolo Bonzini def cancel_and_wait(self, drive='drive0', wait_ready=True): 40*44c7ca5eSPaolo Bonzini '''Cancel a block job and wait for it to finish''' 41*44c7ca5eSPaolo Bonzini if wait_ready: 42*44c7ca5eSPaolo Bonzini ready = False 43*44c7ca5eSPaolo Bonzini while not ready: 44*44c7ca5eSPaolo Bonzini for event in self.vm.get_qmp_events(wait=True): 45*44c7ca5eSPaolo Bonzini if event['event'] == 'BLOCK_JOB_READY': 46*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/type', 'mirror') 47*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/device', drive) 48*44c7ca5eSPaolo Bonzini ready = True 49*44c7ca5eSPaolo Bonzini 50*44c7ca5eSPaolo Bonzini result = self.vm.qmp('block-job-cancel', device=drive, 51*44c7ca5eSPaolo Bonzini force=not wait_ready) 52*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 53*44c7ca5eSPaolo Bonzini 54*44c7ca5eSPaolo Bonzini cancelled = False 55*44c7ca5eSPaolo Bonzini while not cancelled: 56*44c7ca5eSPaolo Bonzini for event in self.vm.get_qmp_events(wait=True): 57*44c7ca5eSPaolo Bonzini if event['event'] == 'BLOCK_JOB_COMPLETED' or \ 58*44c7ca5eSPaolo Bonzini event['event'] == 'BLOCK_JOB_CANCELLED': 59*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/type', 'mirror') 60*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/device', drive) 61*44c7ca5eSPaolo Bonzini if wait_ready: 62*44c7ca5eSPaolo Bonzini self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED') 63*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/offset', self.image_len) 64*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/len', self.image_len) 65*44c7ca5eSPaolo Bonzini cancelled = True 66*44c7ca5eSPaolo Bonzini 67*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 68*44c7ca5eSPaolo Bonzini 69*44c7ca5eSPaolo Bonzini def complete_and_wait(self, drive='drive0', wait_ready=True): 70*44c7ca5eSPaolo Bonzini '''Complete a block job and wait for it to finish''' 71*44c7ca5eSPaolo Bonzini if wait_ready: 72*44c7ca5eSPaolo Bonzini ready = False 73*44c7ca5eSPaolo Bonzini while not ready: 74*44c7ca5eSPaolo Bonzini for event in self.vm.get_qmp_events(wait=True): 75*44c7ca5eSPaolo Bonzini if event['event'] == 'BLOCK_JOB_READY': 76*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/type', 'mirror') 77*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/device', drive) 78*44c7ca5eSPaolo Bonzini ready = True 79*44c7ca5eSPaolo Bonzini 80*44c7ca5eSPaolo Bonzini result = self.vm.qmp('block-job-complete', device=drive) 81*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 82*44c7ca5eSPaolo Bonzini 83*44c7ca5eSPaolo Bonzini completed = False 84*44c7ca5eSPaolo Bonzini while not completed: 85*44c7ca5eSPaolo Bonzini for event in self.vm.get_qmp_events(wait=True): 86*44c7ca5eSPaolo Bonzini if event['event'] == 'BLOCK_JOB_COMPLETED': 87*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/type', 'mirror') 88*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/device', drive) 89*44c7ca5eSPaolo Bonzini self.assert_qmp_absent(event, 'data/error') 90*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/offset', self.image_len) 91*44c7ca5eSPaolo Bonzini self.assert_qmp(event, 'data/len', self.image_len) 92*44c7ca5eSPaolo Bonzini completed = True 93*44c7ca5eSPaolo Bonzini 94*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 95*44c7ca5eSPaolo Bonzini 96*44c7ca5eSPaolo Bonzini def create_image(self, name, size): 97*44c7ca5eSPaolo Bonzini file = open(name, 'w') 98*44c7ca5eSPaolo Bonzini i = 0 99*44c7ca5eSPaolo Bonzini while i < size: 100*44c7ca5eSPaolo Bonzini sector = struct.pack('>l504xl', i / 512, i / 512) 101*44c7ca5eSPaolo Bonzini file.write(sector) 102*44c7ca5eSPaolo Bonzini i = i + 512 103*44c7ca5eSPaolo Bonzini file.close() 104*44c7ca5eSPaolo Bonzini 105*44c7ca5eSPaolo Bonzini def compare_images(self, img1, img2): 106*44c7ca5eSPaolo Bonzini try: 107*44c7ca5eSPaolo Bonzini qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img1, img1 + '.raw') 108*44c7ca5eSPaolo Bonzini qemu_img('convert', '-f', iotests.imgfmt, '-O', 'raw', img2, img2 + '.raw') 109*44c7ca5eSPaolo Bonzini file1 = open(img1 + '.raw', 'r') 110*44c7ca5eSPaolo Bonzini file2 = open(img2 + '.raw', 'r') 111*44c7ca5eSPaolo Bonzini return file1.read() == file2.read() 112*44c7ca5eSPaolo Bonzini finally: 113*44c7ca5eSPaolo Bonzini if file1 is not None: 114*44c7ca5eSPaolo Bonzini file1.close() 115*44c7ca5eSPaolo Bonzini if file2 is not None: 116*44c7ca5eSPaolo Bonzini file2.close() 117*44c7ca5eSPaolo Bonzini try: 118*44c7ca5eSPaolo Bonzini os.remove(img1 + '.raw') 119*44c7ca5eSPaolo Bonzini except OSError: 120*44c7ca5eSPaolo Bonzini pass 121*44c7ca5eSPaolo Bonzini try: 122*44c7ca5eSPaolo Bonzini os.remove(img2 + '.raw') 123*44c7ca5eSPaolo Bonzini except OSError: 124*44c7ca5eSPaolo Bonzini pass 125*44c7ca5eSPaolo Bonzini 126*44c7ca5eSPaolo Bonziniclass TestSingleDrive(ImageMirroringTestCase): 127*44c7ca5eSPaolo Bonzini image_len = 1 * 1024 * 1024 # MB 128*44c7ca5eSPaolo Bonzini 129*44c7ca5eSPaolo Bonzini def setUp(self): 130*44c7ca5eSPaolo Bonzini self.create_image(backing_img, TestSingleDrive.image_len) 131*44c7ca5eSPaolo Bonzini qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) 132*44c7ca5eSPaolo Bonzini self.vm = iotests.VM().add_drive(test_img) 133*44c7ca5eSPaolo Bonzini self.vm.launch() 134*44c7ca5eSPaolo Bonzini 135*44c7ca5eSPaolo Bonzini def tearDown(self): 136*44c7ca5eSPaolo Bonzini self.vm.shutdown() 137*44c7ca5eSPaolo Bonzini os.remove(test_img) 138*44c7ca5eSPaolo Bonzini os.remove(backing_img) 139*44c7ca5eSPaolo Bonzini try: 140*44c7ca5eSPaolo Bonzini os.remove(target_img) 141*44c7ca5eSPaolo Bonzini except OSError: 142*44c7ca5eSPaolo Bonzini pass 143*44c7ca5eSPaolo Bonzini 144*44c7ca5eSPaolo Bonzini def test_complete(self): 145*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 146*44c7ca5eSPaolo Bonzini 147*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 148*44c7ca5eSPaolo Bonzini target=target_img) 149*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 150*44c7ca5eSPaolo Bonzini 151*44c7ca5eSPaolo Bonzini self.complete_and_wait() 152*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block') 153*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/inserted/file', target_img) 154*44c7ca5eSPaolo Bonzini self.vm.shutdown() 155*44c7ca5eSPaolo Bonzini self.assertTrue(self.compare_images(test_img, target_img), 156*44c7ca5eSPaolo Bonzini 'target image does not match source after mirroring') 157*44c7ca5eSPaolo Bonzini 158*44c7ca5eSPaolo Bonzini def test_cancel(self): 159*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 160*44c7ca5eSPaolo Bonzini 161*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 162*44c7ca5eSPaolo Bonzini target=target_img) 163*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 164*44c7ca5eSPaolo Bonzini 165*44c7ca5eSPaolo Bonzini self.cancel_and_wait(wait_ready=False) 166*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block') 167*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/inserted/file', test_img) 168*44c7ca5eSPaolo Bonzini self.vm.shutdown() 169*44c7ca5eSPaolo Bonzini 170*44c7ca5eSPaolo Bonzini def test_cancel_after_ready(self): 171*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 172*44c7ca5eSPaolo Bonzini 173*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 174*44c7ca5eSPaolo Bonzini target=target_img) 175*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 176*44c7ca5eSPaolo Bonzini 177*44c7ca5eSPaolo Bonzini self.cancel_and_wait() 178*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block') 179*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/inserted/file', test_img) 180*44c7ca5eSPaolo Bonzini self.vm.shutdown() 181*44c7ca5eSPaolo Bonzini self.assertTrue(self.compare_images(test_img, target_img), 182*44c7ca5eSPaolo Bonzini 'target image does not match source after mirroring') 183*44c7ca5eSPaolo Bonzini 184*44c7ca5eSPaolo Bonzini def test_pause(self): 185*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 186*44c7ca5eSPaolo Bonzini 187*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 188*44c7ca5eSPaolo Bonzini target=target_img) 189*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 190*44c7ca5eSPaolo Bonzini 191*44c7ca5eSPaolo Bonzini result = self.vm.qmp('block-job-pause', device='drive0') 192*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 193*44c7ca5eSPaolo Bonzini 194*44c7ca5eSPaolo Bonzini time.sleep(1) 195*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block-jobs') 196*44c7ca5eSPaolo Bonzini offset = self.dictpath(result, 'return[0]/offset') 197*44c7ca5eSPaolo Bonzini 198*44c7ca5eSPaolo Bonzini time.sleep(1) 199*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block-jobs') 200*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/offset', offset) 201*44c7ca5eSPaolo Bonzini 202*44c7ca5eSPaolo Bonzini result = self.vm.qmp('block-job-resume', device='drive0') 203*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 204*44c7ca5eSPaolo Bonzini 205*44c7ca5eSPaolo Bonzini self.complete_and_wait() 206*44c7ca5eSPaolo Bonzini self.vm.shutdown() 207*44c7ca5eSPaolo Bonzini self.assertTrue(self.compare_images(test_img, target_img), 208*44c7ca5eSPaolo Bonzini 'target image does not match source after mirroring') 209*44c7ca5eSPaolo Bonzini 210*44c7ca5eSPaolo Bonzini def test_large_cluster(self): 211*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 212*44c7ca5eSPaolo Bonzini 213*44c7ca5eSPaolo Bonzini qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s' 214*44c7ca5eSPaolo Bonzini % (TestSingleDrive.image_len, backing_img), target_img) 215*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 216*44c7ca5eSPaolo Bonzini mode='existing', target=target_img) 217*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 218*44c7ca5eSPaolo Bonzini 219*44c7ca5eSPaolo Bonzini self.complete_and_wait() 220*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block') 221*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/inserted/file', target_img) 222*44c7ca5eSPaolo Bonzini self.vm.shutdown() 223*44c7ca5eSPaolo Bonzini self.assertTrue(self.compare_images(test_img, target_img), 224*44c7ca5eSPaolo Bonzini 'target image does not match source after mirroring') 225*44c7ca5eSPaolo Bonzini 226*44c7ca5eSPaolo Bonzini def test_medium_not_found(self): 227*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='ide1-cd0', sync='full', 228*44c7ca5eSPaolo Bonzini target=target_img) 229*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'error/class', 'GenericError') 230*44c7ca5eSPaolo Bonzini 231*44c7ca5eSPaolo Bonzini def test_image_not_found(self): 232*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 233*44c7ca5eSPaolo Bonzini mode='existing', target=target_img) 234*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'error/class', 'GenericError') 235*44c7ca5eSPaolo Bonzini 236*44c7ca5eSPaolo Bonzini def test_device_not_found(self): 237*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='nonexistent', sync='full', 238*44c7ca5eSPaolo Bonzini target=target_img) 239*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'error/class', 'DeviceNotFound') 240*44c7ca5eSPaolo Bonzini 241*44c7ca5eSPaolo Bonziniclass TestMirrorNoBacking(ImageMirroringTestCase): 242*44c7ca5eSPaolo Bonzini image_len = 2 * 1024 * 1024 # MB 243*44c7ca5eSPaolo Bonzini 244*44c7ca5eSPaolo Bonzini def complete_and_wait(self, drive='drive0', wait_ready=True): 245*44c7ca5eSPaolo Bonzini self.create_image(target_backing_img, TestMirrorNoBacking.image_len) 246*44c7ca5eSPaolo Bonzini return ImageMirroringTestCase.complete_and_wait(self, drive, wait_ready) 247*44c7ca5eSPaolo Bonzini 248*44c7ca5eSPaolo Bonzini def compare_images(self, img1, img2): 249*44c7ca5eSPaolo Bonzini self.create_image(target_backing_img, TestMirrorNoBacking.image_len) 250*44c7ca5eSPaolo Bonzini return ImageMirroringTestCase.compare_images(self, img1, img2) 251*44c7ca5eSPaolo Bonzini 252*44c7ca5eSPaolo Bonzini def setUp(self): 253*44c7ca5eSPaolo Bonzini self.create_image(backing_img, TestMirrorNoBacking.image_len) 254*44c7ca5eSPaolo Bonzini qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) 255*44c7ca5eSPaolo Bonzini self.vm = iotests.VM().add_drive(test_img) 256*44c7ca5eSPaolo Bonzini self.vm.launch() 257*44c7ca5eSPaolo Bonzini 258*44c7ca5eSPaolo Bonzini def tearDown(self): 259*44c7ca5eSPaolo Bonzini self.vm.shutdown() 260*44c7ca5eSPaolo Bonzini os.remove(test_img) 261*44c7ca5eSPaolo Bonzini os.remove(backing_img) 262*44c7ca5eSPaolo Bonzini os.remove(target_backing_img) 263*44c7ca5eSPaolo Bonzini os.remove(target_img) 264*44c7ca5eSPaolo Bonzini 265*44c7ca5eSPaolo Bonzini def test_complete(self): 266*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 267*44c7ca5eSPaolo Bonzini 268*44c7ca5eSPaolo Bonzini qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img) 269*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 270*44c7ca5eSPaolo Bonzini mode='existing', target=target_img) 271*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 272*44c7ca5eSPaolo Bonzini 273*44c7ca5eSPaolo Bonzini self.complete_and_wait() 274*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block') 275*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/inserted/file', target_img) 276*44c7ca5eSPaolo Bonzini self.vm.shutdown() 277*44c7ca5eSPaolo Bonzini self.assertTrue(self.compare_images(test_img, target_img), 278*44c7ca5eSPaolo Bonzini 'target image does not match source after mirroring') 279*44c7ca5eSPaolo Bonzini 280*44c7ca5eSPaolo Bonzini def test_cancel(self): 281*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 282*44c7ca5eSPaolo Bonzini 283*44c7ca5eSPaolo Bonzini qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img) 284*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 285*44c7ca5eSPaolo Bonzini mode='existing', target=target_img) 286*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 287*44c7ca5eSPaolo Bonzini 288*44c7ca5eSPaolo Bonzini self.cancel_and_wait() 289*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block') 290*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/inserted/file', test_img) 291*44c7ca5eSPaolo Bonzini self.vm.shutdown() 292*44c7ca5eSPaolo Bonzini self.assertTrue(self.compare_images(test_img, target_img), 293*44c7ca5eSPaolo Bonzini 'target image does not match source after mirroring') 294*44c7ca5eSPaolo Bonzini 295*44c7ca5eSPaolo Bonziniclass TestSetSpeed(ImageMirroringTestCase): 296*44c7ca5eSPaolo Bonzini image_len = 80 * 1024 * 1024 # MB 297*44c7ca5eSPaolo Bonzini 298*44c7ca5eSPaolo Bonzini def setUp(self): 299*44c7ca5eSPaolo Bonzini qemu_img('create', backing_img, str(TestSetSpeed.image_len)) 300*44c7ca5eSPaolo Bonzini qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) 301*44c7ca5eSPaolo Bonzini self.vm = iotests.VM().add_drive(test_img) 302*44c7ca5eSPaolo Bonzini self.vm.launch() 303*44c7ca5eSPaolo Bonzini 304*44c7ca5eSPaolo Bonzini def tearDown(self): 305*44c7ca5eSPaolo Bonzini self.vm.shutdown() 306*44c7ca5eSPaolo Bonzini os.remove(test_img) 307*44c7ca5eSPaolo Bonzini os.remove(backing_img) 308*44c7ca5eSPaolo Bonzini os.remove(target_img) 309*44c7ca5eSPaolo Bonzini 310*44c7ca5eSPaolo Bonzini def test_set_speed(self): 311*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 312*44c7ca5eSPaolo Bonzini 313*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 314*44c7ca5eSPaolo Bonzini target=target_img) 315*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 316*44c7ca5eSPaolo Bonzini 317*44c7ca5eSPaolo Bonzini # Default speed is 0 318*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block-jobs') 319*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/device', 'drive0') 320*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/speed', 0) 321*44c7ca5eSPaolo Bonzini 322*44c7ca5eSPaolo Bonzini result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) 323*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 324*44c7ca5eSPaolo Bonzini 325*44c7ca5eSPaolo Bonzini # Ensure the speed we set was accepted 326*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block-jobs') 327*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/device', 'drive0') 328*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024) 329*44c7ca5eSPaolo Bonzini 330*44c7ca5eSPaolo Bonzini self.cancel_and_wait() 331*44c7ca5eSPaolo Bonzini 332*44c7ca5eSPaolo Bonzini # Check setting speed in drive-mirror works 333*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 334*44c7ca5eSPaolo Bonzini target=target_img, speed=4*1024*1024) 335*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 336*44c7ca5eSPaolo Bonzini 337*44c7ca5eSPaolo Bonzini result = self.vm.qmp('query-block-jobs') 338*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/device', 'drive0') 339*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024) 340*44c7ca5eSPaolo Bonzini 341*44c7ca5eSPaolo Bonzini self.cancel_and_wait() 342*44c7ca5eSPaolo Bonzini 343*44c7ca5eSPaolo Bonzini def test_set_speed_invalid(self): 344*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 345*44c7ca5eSPaolo Bonzini 346*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 347*44c7ca5eSPaolo Bonzini target=target_img, speed=-1) 348*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'error/class', 'GenericError') 349*44c7ca5eSPaolo Bonzini 350*44c7ca5eSPaolo Bonzini self.assert_no_active_mirrors() 351*44c7ca5eSPaolo Bonzini 352*44c7ca5eSPaolo Bonzini result = self.vm.qmp('drive-mirror', device='drive0', sync='full', 353*44c7ca5eSPaolo Bonzini target=target_img) 354*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'return', {}) 355*44c7ca5eSPaolo Bonzini 356*44c7ca5eSPaolo Bonzini result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1) 357*44c7ca5eSPaolo Bonzini self.assert_qmp(result, 'error/class', 'GenericError') 358*44c7ca5eSPaolo Bonzini 359*44c7ca5eSPaolo Bonzini self.cancel_and_wait() 360*44c7ca5eSPaolo Bonzini 361*44c7ca5eSPaolo Bonziniif __name__ == '__main__': 362*44c7ca5eSPaolo Bonzini iotests.main(supported_fmts=['qcow2', 'qed']) 363