1903cb1bfSPhilippe Mathieu-Daudé#!/usr/bin/env python3 2*9dd003a9SVladimir Sementsov-Ogievskiy# group: rw 3e5ca8fddSStefan Hajnoczi# 47c6a4ab8SFam Zheng# Tests for drive-backup and blockdev-backup 5e5ca8fddSStefan Hajnoczi# 67c6a4ab8SFam Zheng# Copyright (C) 2013, 2014 Red Hat, Inc. 7e5ca8fddSStefan Hajnoczi# 8e5ca8fddSStefan Hajnoczi# Based on 041. 9e5ca8fddSStefan Hajnoczi# 10e5ca8fddSStefan Hajnoczi# This program is free software; you can redistribute it and/or modify 11e5ca8fddSStefan Hajnoczi# it under the terms of the GNU General Public License as published by 12e5ca8fddSStefan Hajnoczi# the Free Software Foundation; either version 2 of the License, or 13e5ca8fddSStefan Hajnoczi# (at your option) any later version. 14e5ca8fddSStefan Hajnoczi# 15e5ca8fddSStefan Hajnoczi# This program is distributed in the hope that it will be useful, 16e5ca8fddSStefan Hajnoczi# but WITHOUT ANY WARRANTY; without even the implied warranty of 17e5ca8fddSStefan Hajnoczi# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18e5ca8fddSStefan Hajnoczi# GNU General Public License for more details. 19e5ca8fddSStefan Hajnoczi# 20e5ca8fddSStefan Hajnoczi# You should have received a copy of the GNU General Public License 21e5ca8fddSStefan Hajnoczi# along with this program. If not, see <http://www.gnu.org/licenses/>. 22e5ca8fddSStefan Hajnoczi# 23e5ca8fddSStefan Hajnoczi 24e5ca8fddSStefan Hajnocziimport time 25e5ca8fddSStefan Hajnocziimport os 26e5ca8fddSStefan Hajnocziimport iotests 27e5ca8fddSStefan Hajnoczifrom iotests import qemu_img, qemu_io 28e5ca8fddSStefan Hajnoczi 29e5ca8fddSStefan Hajnoczitest_img = os.path.join(iotests.test_dir, 'test.img') 30e5ca8fddSStefan Hajnoczitarget_img = os.path.join(iotests.test_dir, 'target.img') 317c6a4ab8SFam Zhengblockdev_target_img = os.path.join(iotests.test_dir, 'blockdev-target.img') 32e5ca8fddSStefan Hajnoczi 33e5ca8fddSStefan Hajnocziimage_len = 64 * 1024 * 1024 # MB 34e5ca8fddSStefan Hajnoczi 35819cec01SVladimir Sementsov-Ogievskiydef setUpModule(): 36819cec01SVladimir Sementsov-Ogievskiy qemu_img('create', '-f', iotests.imgfmt, test_img, str(image_len)) 37819cec01SVladimir Sementsov-Ogievskiy qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x11 0 64k', test_img) 38819cec01SVladimir Sementsov-Ogievskiy qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x00 64k 128k', test_img) 39819cec01SVladimir Sementsov-Ogievskiy qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x22 162k 32k', test_img) 4090c9b167SKevin Wolf qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img) 4190c9b167SKevin Wolf qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img) 42819cec01SVladimir Sementsov-Ogievskiy qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x33 67043328 64k', test_img) 43819cec01SVladimir Sementsov-Ogievskiy 44819cec01SVladimir Sementsov-Ogievskiydef tearDownModule(): 45819cec01SVladimir Sementsov-Ogievskiy os.remove(test_img) 46819cec01SVladimir Sementsov-Ogievskiy 47819cec01SVladimir Sementsov-Ogievskiy 48819cec01SVladimir Sementsov-Ogievskiyclass TestSingleDrive(iotests.QMPTestCase): 49819cec01SVladimir Sementsov-Ogievskiy def setUp(self): 50819cec01SVladimir Sementsov-Ogievskiy qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len)) 51e5ca8fddSStefan Hajnoczi 520a82a927SKevin Wolf self.vm = iotests.VM() 530a82a927SKevin Wolf self.vm.add_drive('blkdebug::' + test_img, 'node-name=source') 540a82a927SKevin Wolf self.vm.add_drive(blockdev_target_img, 'node-name=target', 550a82a927SKevin Wolf interface="none") 560ed82f7aSMax Reitz if iotests.qemu_default_machine == 'pc': 570ed82f7aSMax Reitz self.vm.add_drive(None, 'media=cdrom', 'ide') 58e5ca8fddSStefan Hajnoczi self.vm.launch() 59e5ca8fddSStefan Hajnoczi 60e5ca8fddSStefan Hajnoczi def tearDown(self): 61e5ca8fddSStefan Hajnoczi self.vm.shutdown() 627c6a4ab8SFam Zheng os.remove(blockdev_target_img) 63e5ca8fddSStefan Hajnoczi try: 64e5ca8fddSStefan Hajnoczi os.remove(target_img) 65e5ca8fddSStefan Hajnoczi except OSError: 66e5ca8fddSStefan Hajnoczi pass 67e5ca8fddSStefan Hajnoczi 687c6a4ab8SFam Zheng def do_test_cancel(self, cmd, target): 69e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 70e5ca8fddSStefan Hajnoczi 71bc11aee2SMax Reitz self.vm.pause_drive('drive0') 727c6a4ab8SFam Zheng result = self.vm.qmp(cmd, device='drive0', target=target, sync='full') 73e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 74e5ca8fddSStefan Hajnoczi 75bc11aee2SMax Reitz event = self.cancel_and_wait(resume=True) 76e5ca8fddSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'backup') 77e5ca8fddSStefan Hajnoczi 787c6a4ab8SFam Zheng def test_cancel_drive_backup(self): 797c6a4ab8SFam Zheng self.do_test_cancel('drive-backup', target_img) 807c6a4ab8SFam Zheng 817c6a4ab8SFam Zheng def test_cancel_blockdev_backup(self): 827c6a4ab8SFam Zheng self.do_test_cancel('blockdev-backup', 'drive1') 837c6a4ab8SFam Zheng 847c6a4ab8SFam Zheng def do_test_pause(self, cmd, target, image): 85e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 86e5ca8fddSStefan Hajnoczi 87b59b3d57SFam Zheng self.vm.pause_drive('drive0') 887c6a4ab8SFam Zheng result = self.vm.qmp(cmd, device='drive0', 897c6a4ab8SFam Zheng target=target, sync='full') 90e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 91e5ca8fddSStefan Hajnoczi 92f03d9d24SJohn Snow self.pause_job('drive0', wait=False) 93b59b3d57SFam Zheng self.vm.resume_drive('drive0') 94f03d9d24SJohn Snow self.pause_wait('drive0') 952c93c5cbSKevin Wolf 96e5ca8fddSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 97e5ca8fddSStefan Hajnoczi offset = self.dictpath(result, 'return[0]/offset') 98e5ca8fddSStefan Hajnoczi 992c93c5cbSKevin Wolf time.sleep(0.5) 100e5ca8fddSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 101e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/offset', offset) 102e5ca8fddSStefan Hajnoczi 103e5ca8fddSStefan Hajnoczi result = self.vm.qmp('block-job-resume', device='drive0') 104e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 105e5ca8fddSStefan Hajnoczi 106e5ca8fddSStefan Hajnoczi self.wait_until_completed() 107e5ca8fddSStefan Hajnoczi 108e5ca8fddSStefan Hajnoczi self.vm.shutdown() 1097c6a4ab8SFam Zheng self.assertTrue(iotests.compare_images(test_img, image), 110e5ca8fddSStefan Hajnoczi 'target image does not match source after backup') 111e5ca8fddSStefan Hajnoczi 1127c6a4ab8SFam Zheng def test_pause_drive_backup(self): 1137c6a4ab8SFam Zheng self.do_test_pause('drive-backup', target_img, target_img) 1147c6a4ab8SFam Zheng 1157c6a4ab8SFam Zheng def test_pause_blockdev_backup(self): 1167c6a4ab8SFam Zheng self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img) 1177c6a4ab8SFam Zheng 1180a82a927SKevin Wolf def do_test_resize_blockdev_backup(self, device, node): 1190a82a927SKevin Wolf def pre_finalize(): 1200a82a927SKevin Wolf result = self.vm.qmp('block_resize', device=device, size=65536) 1210a82a927SKevin Wolf self.assert_qmp(result, 'error/class', 'GenericError') 1220a82a927SKevin Wolf 1230a82a927SKevin Wolf result = self.vm.qmp('block_resize', node_name=node, size=65536) 1240a82a927SKevin Wolf self.assert_qmp(result, 'error/class', 'GenericError') 1250a82a927SKevin Wolf 1260a82a927SKevin Wolf result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0', 1270a82a927SKevin Wolf target='drive1', sync='full', auto_finalize=False, 1280a82a927SKevin Wolf auto_dismiss=False) 1290a82a927SKevin Wolf self.assert_qmp(result, 'return', {}) 1300a82a927SKevin Wolf 1310a82a927SKevin Wolf self.vm.run_job('job0', auto_finalize=False, pre_finalize=pre_finalize) 1320a82a927SKevin Wolf 1330a82a927SKevin Wolf def test_source_resize_blockdev_backup(self): 1340a82a927SKevin Wolf self.do_test_resize_blockdev_backup('drive0', 'source') 1350a82a927SKevin Wolf 1360a82a927SKevin Wolf def test_target_resize_blockdev_backup(self): 1370a82a927SKevin Wolf self.do_test_resize_blockdev_backup('drive1', 'target') 1380a82a927SKevin Wolf 1390a82a927SKevin Wolf def do_test_target_size(self, size): 1400a82a927SKevin Wolf result = self.vm.qmp('block_resize', device='drive1', size=size) 1410a82a927SKevin Wolf self.assert_qmp(result, 'return', {}) 1420a82a927SKevin Wolf 1430a82a927SKevin Wolf result = self.vm.qmp('blockdev-backup', job_id='job0', device='drive0', 1440a82a927SKevin Wolf target='drive1', sync='full') 1450a82a927SKevin Wolf self.assert_qmp(result, 'error/class', 'GenericError') 1460a82a927SKevin Wolf 1470a82a927SKevin Wolf def test_small_target(self): 1480a82a927SKevin Wolf self.do_test_target_size(image_len // 2) 1490a82a927SKevin Wolf 1500a82a927SKevin Wolf def test_large_target(self): 1510a82a927SKevin Wolf self.do_test_target_size(image_len * 2) 1520a82a927SKevin Wolf 153e5ca8fddSStefan Hajnoczi def test_medium_not_found(self): 154d8683155SBo Tu if iotests.qemu_default_machine != 'pc': 155d8683155SBo Tu return 156d8683155SBo Tu 1570ed82f7aSMax Reitz result = self.vm.qmp('drive-backup', device='drive2', # CD-ROM 158b53169eaSStefan Hajnoczi target=target_img, sync='full') 159e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'GenericError') 160e5ca8fddSStefan Hajnoczi 1617c6a4ab8SFam Zheng def test_medium_not_found_blockdev_backup(self): 162d8683155SBo Tu if iotests.qemu_default_machine != 'pc': 163d8683155SBo Tu return 164d8683155SBo Tu 1650ed82f7aSMax Reitz result = self.vm.qmp('blockdev-backup', device='drive2', # CD-ROM 1667c6a4ab8SFam Zheng target='drive1', sync='full') 1677c6a4ab8SFam Zheng self.assert_qmp(result, 'error/class', 'GenericError') 1687c6a4ab8SFam Zheng 169e5ca8fddSStefan Hajnoczi def test_image_not_found(self): 170e5ca8fddSStefan Hajnoczi result = self.vm.qmp('drive-backup', device='drive0', 171b53169eaSStefan Hajnoczi target=target_img, sync='full', mode='existing') 172e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'GenericError') 173e5ca8fddSStefan Hajnoczi 174e3409362SIan Main def test_invalid_format(self): 175e3409362SIan Main result = self.vm.qmp('drive-backup', device='drive0', 176e3409362SIan Main target=target_img, sync='full', 177e3409362SIan Main format='spaghetti-noodles') 178e3409362SIan Main self.assert_qmp(result, 'error/class', 'GenericError') 179e3409362SIan Main 1807c6a4ab8SFam Zheng def do_test_device_not_found(self, cmd, **args): 1817c6a4ab8SFam Zheng result = self.vm.qmp(cmd, **args) 1825b347c54SMarkus Armbruster self.assert_qmp(result, 'error/class', 'GenericError') 183e5ca8fddSStefan Hajnoczi 1847c6a4ab8SFam Zheng def test_device_not_found(self): 1857c6a4ab8SFam Zheng self.do_test_device_not_found('drive-backup', device='nonexistent', 1867c6a4ab8SFam Zheng target=target_img, sync='full') 1877c6a4ab8SFam Zheng 1887c6a4ab8SFam Zheng self.do_test_device_not_found('blockdev-backup', device='nonexistent', 1897c6a4ab8SFam Zheng target='drive0', sync='full') 1907c6a4ab8SFam Zheng 1917c6a4ab8SFam Zheng self.do_test_device_not_found('blockdev-backup', device='drive0', 1927c6a4ab8SFam Zheng target='nonexistent', sync='full') 1937c6a4ab8SFam Zheng 1947c6a4ab8SFam Zheng self.do_test_device_not_found('blockdev-backup', device='nonexistent', 1957c6a4ab8SFam Zheng target='nonexistent', sync='full') 1967c6a4ab8SFam Zheng 1977c6a4ab8SFam Zheng def test_target_is_source(self): 1987c6a4ab8SFam Zheng result = self.vm.qmp('blockdev-backup', device='drive0', 1997c6a4ab8SFam Zheng target='drive0', sync='full') 2007c6a4ab8SFam Zheng self.assert_qmp(result, 'error/class', 'GenericError') 2017c6a4ab8SFam Zheng 202e5ca8fddSStefan Hajnocziclass TestSetSpeed(iotests.QMPTestCase): 203e5ca8fddSStefan Hajnoczi def setUp(self): 204819cec01SVladimir Sementsov-Ogievskiy qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len)) 2057c6a4ab8SFam Zheng 206bc11aee2SMax Reitz self.vm = iotests.VM().add_drive('blkdebug::' + test_img) 2074e9e4323SKevin Wolf self.vm.add_drive(blockdev_target_img, interface="none") 208e5ca8fddSStefan Hajnoczi self.vm.launch() 209e5ca8fddSStefan Hajnoczi 210e5ca8fddSStefan Hajnoczi def tearDown(self): 211e5ca8fddSStefan Hajnoczi self.vm.shutdown() 2127c6a4ab8SFam Zheng os.remove(blockdev_target_img) 2137c6a4ab8SFam Zheng try: 214e5ca8fddSStefan Hajnoczi os.remove(target_img) 2157c6a4ab8SFam Zheng except OSError: 2167c6a4ab8SFam Zheng pass 217e5ca8fddSStefan Hajnoczi 2187c6a4ab8SFam Zheng def do_test_set_speed(self, cmd, target): 219e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 220e5ca8fddSStefan Hajnoczi 221b59b3d57SFam Zheng self.vm.pause_drive('drive0') 2227c6a4ab8SFam Zheng result = self.vm.qmp(cmd, device='drive0', target=target, sync='full') 223e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 224e5ca8fddSStefan Hajnoczi 225e5ca8fddSStefan Hajnoczi # Default speed is 0 226e5ca8fddSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 227e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/device', 'drive0') 228e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/speed', 0) 229e5ca8fddSStefan Hajnoczi 230e5ca8fddSStefan Hajnoczi result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024) 231e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 232e5ca8fddSStefan Hajnoczi 233e5ca8fddSStefan Hajnoczi # Ensure the speed we set was accepted 234e5ca8fddSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 235e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/device', 'drive0') 236e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024) 237e5ca8fddSStefan Hajnoczi 238b59b3d57SFam Zheng event = self.cancel_and_wait(resume=True) 239e5ca8fddSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'backup') 240e5ca8fddSStefan Hajnoczi 2417c6a4ab8SFam Zheng # Check setting speed option works 242b59b3d57SFam Zheng self.vm.pause_drive('drive0') 2437c6a4ab8SFam Zheng result = self.vm.qmp(cmd, device='drive0', 2447c6a4ab8SFam Zheng target=target, sync='full', speed=4*1024*1024) 245e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 246e5ca8fddSStefan Hajnoczi 247e5ca8fddSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 248e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/device', 'drive0') 249e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024) 250e5ca8fddSStefan Hajnoczi 251b59b3d57SFam Zheng event = self.cancel_and_wait(resume=True) 252e5ca8fddSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'backup') 253e5ca8fddSStefan Hajnoczi 2547c6a4ab8SFam Zheng def test_set_speed_drive_backup(self): 2557c6a4ab8SFam Zheng self.do_test_set_speed('drive-backup', target_img) 2567c6a4ab8SFam Zheng 2577c6a4ab8SFam Zheng def test_set_speed_blockdev_backup(self): 2587c6a4ab8SFam Zheng self.do_test_set_speed('blockdev-backup', 'drive1') 2597c6a4ab8SFam Zheng 2607c6a4ab8SFam Zheng def do_test_set_speed_invalid(self, cmd, target): 261e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 262e5ca8fddSStefan Hajnoczi 2637c6a4ab8SFam Zheng result = self.vm.qmp(cmd, device='drive0', 2647c6a4ab8SFam Zheng target=target, sync='full', speed=-1) 265e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'GenericError') 266e5ca8fddSStefan Hajnoczi 267e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 268e5ca8fddSStefan Hajnoczi 269b59b3d57SFam Zheng self.vm.pause_drive('drive0') 2707c6a4ab8SFam Zheng result = self.vm.qmp(cmd, device='drive0', 2717c6a4ab8SFam Zheng target=target, sync='full') 272e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 273e5ca8fddSStefan Hajnoczi 274e5ca8fddSStefan Hajnoczi result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1) 275e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'GenericError') 276e5ca8fddSStefan Hajnoczi 277b59b3d57SFam Zheng event = self.cancel_and_wait(resume=True) 278e5ca8fddSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'backup') 279e5ca8fddSStefan Hajnoczi 2807c6a4ab8SFam Zheng def test_set_speed_invalid_drive_backup(self): 2817c6a4ab8SFam Zheng self.do_test_set_speed_invalid('drive-backup', target_img) 2827c6a4ab8SFam Zheng 2837c6a4ab8SFam Zheng def test_set_speed_invalid_blockdev_backup(self): 2847c6a4ab8SFam Zheng self.do_test_set_speed_invalid('blockdev-backup', 'drive1') 2857c6a4ab8SFam Zheng 286bc11aee2SMax Reitz# Note: We cannot use pause_drive() here, or the transaction command 287bc11aee2SMax Reitz# would stall. Instead, we limit the block job speed here. 288e5ca8fddSStefan Hajnocziclass TestSingleTransaction(iotests.QMPTestCase): 289e5ca8fddSStefan Hajnoczi def setUp(self): 290819cec01SVladimir Sementsov-Ogievskiy qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(image_len)) 291e5ca8fddSStefan Hajnoczi 2924e9e4323SKevin Wolf self.vm = iotests.VM().add_drive(test_img) 2934e9e4323SKevin Wolf self.vm.add_drive(blockdev_target_img, interface="none") 2940ed82f7aSMax Reitz if iotests.qemu_default_machine == 'pc': 2950ed82f7aSMax Reitz self.vm.add_drive(None, 'media=cdrom', 'ide') 296e5ca8fddSStefan Hajnoczi self.vm.launch() 297e5ca8fddSStefan Hajnoczi 298e5ca8fddSStefan Hajnoczi def tearDown(self): 299e5ca8fddSStefan Hajnoczi self.vm.shutdown() 3007c6a4ab8SFam Zheng os.remove(blockdev_target_img) 301e5ca8fddSStefan Hajnoczi try: 302e5ca8fddSStefan Hajnoczi os.remove(target_img) 303e5ca8fddSStefan Hajnoczi except OSError: 304e5ca8fddSStefan Hajnoczi pass 305e5ca8fddSStefan Hajnoczi 3067c6a4ab8SFam Zheng def do_test_cancel(self, cmd, target): 307e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 308e5ca8fddSStefan Hajnoczi 309e5ca8fddSStefan Hajnoczi result = self.vm.qmp('transaction', actions=[{ 3107c6a4ab8SFam Zheng 'type': cmd, 311e5ca8fddSStefan Hajnoczi 'data': { 'device': 'drive0', 3127c6a4ab8SFam Zheng 'target': target, 313bc11aee2SMax Reitz 'sync': 'full', 314bc11aee2SMax Reitz 'speed': 64 * 1024 }, 315e5ca8fddSStefan Hajnoczi } 316e5ca8fddSStefan Hajnoczi ]) 3177c6a4ab8SFam Zheng 318e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 319e5ca8fddSStefan Hajnoczi 320e5ca8fddSStefan Hajnoczi event = self.cancel_and_wait() 321e5ca8fddSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'backup') 322e5ca8fddSStefan Hajnoczi 3237c6a4ab8SFam Zheng def test_cancel_drive_backup(self): 3247c6a4ab8SFam Zheng self.do_test_cancel('drive-backup', target_img) 3257c6a4ab8SFam Zheng 3267c6a4ab8SFam Zheng def test_cancel_blockdev_backup(self): 3277c6a4ab8SFam Zheng self.do_test_cancel('blockdev-backup', 'drive1') 3287c6a4ab8SFam Zheng 3297c6a4ab8SFam Zheng def do_test_pause(self, cmd, target, image): 330e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 331e5ca8fddSStefan Hajnoczi 332e5ca8fddSStefan Hajnoczi result = self.vm.qmp('transaction', actions=[{ 3337c6a4ab8SFam Zheng 'type': cmd, 334e5ca8fddSStefan Hajnoczi 'data': { 'device': 'drive0', 3357c6a4ab8SFam Zheng 'target': target, 336bc11aee2SMax Reitz 'sync': 'full', 337bc11aee2SMax Reitz 'speed': 64 * 1024 }, 338e5ca8fddSStefan Hajnoczi } 339e5ca8fddSStefan Hajnoczi ]) 340e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 341e5ca8fddSStefan Hajnoczi 342f03d9d24SJohn Snow self.pause_job('drive0', wait=False) 343e5ca8fddSStefan Hajnoczi 344bc11aee2SMax Reitz result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) 345bc11aee2SMax Reitz self.assert_qmp(result, 'return', {}) 346bc11aee2SMax Reitz 347f03d9d24SJohn Snow self.pause_wait('drive0') 3482c93c5cbSKevin Wolf 349e5ca8fddSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 350e5ca8fddSStefan Hajnoczi offset = self.dictpath(result, 'return[0]/offset') 351e5ca8fddSStefan Hajnoczi 3522c93c5cbSKevin Wolf time.sleep(0.5) 353e5ca8fddSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 354e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return[0]/offset', offset) 355e5ca8fddSStefan Hajnoczi 356e5ca8fddSStefan Hajnoczi result = self.vm.qmp('block-job-resume', device='drive0') 357e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 358e5ca8fddSStefan Hajnoczi 359e5ca8fddSStefan Hajnoczi self.wait_until_completed() 360e5ca8fddSStefan Hajnoczi 361e5ca8fddSStefan Hajnoczi self.vm.shutdown() 3627c6a4ab8SFam Zheng self.assertTrue(iotests.compare_images(test_img, image), 363e5ca8fddSStefan Hajnoczi 'target image does not match source after backup') 364e5ca8fddSStefan Hajnoczi 3657c6a4ab8SFam Zheng def test_pause_drive_backup(self): 3667c6a4ab8SFam Zheng self.do_test_pause('drive-backup', target_img, target_img) 3677c6a4ab8SFam Zheng 3687c6a4ab8SFam Zheng def test_pause_blockdev_backup(self): 3697c6a4ab8SFam Zheng self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img) 3707c6a4ab8SFam Zheng 3717c6a4ab8SFam Zheng def do_test_medium_not_found(self, cmd, target): 372d8683155SBo Tu if iotests.qemu_default_machine != 'pc': 373d8683155SBo Tu return 374d8683155SBo Tu 375e5ca8fddSStefan Hajnoczi result = self.vm.qmp('transaction', actions=[{ 3767c6a4ab8SFam Zheng 'type': cmd, 3770ed82f7aSMax Reitz 'data': { 'device': 'drive2', # CD-ROM 3787c6a4ab8SFam Zheng 'target': target, 379b53169eaSStefan Hajnoczi 'sync': 'full' }, 380e5ca8fddSStefan Hajnoczi } 381e5ca8fddSStefan Hajnoczi ]) 382e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'GenericError') 383e5ca8fddSStefan Hajnoczi 3847c6a4ab8SFam Zheng def test_medium_not_found_drive_backup(self): 3857c6a4ab8SFam Zheng self.do_test_medium_not_found('drive-backup', target_img) 3867c6a4ab8SFam Zheng 3877c6a4ab8SFam Zheng def test_medium_not_found_blockdev_backup(self): 3887c6a4ab8SFam Zheng self.do_test_medium_not_found('blockdev-backup', 'drive1') 3897c6a4ab8SFam Zheng 390e5ca8fddSStefan Hajnoczi def test_image_not_found(self): 391e5ca8fddSStefan Hajnoczi result = self.vm.qmp('transaction', actions=[{ 392e5ca8fddSStefan Hajnoczi 'type': 'drive-backup', 393e5ca8fddSStefan Hajnoczi 'data': { 'device': 'drive0', 394e5ca8fddSStefan Hajnoczi 'mode': 'existing', 395b53169eaSStefan Hajnoczi 'target': target_img, 396b53169eaSStefan Hajnoczi 'sync': 'full' }, 397e5ca8fddSStefan Hajnoczi } 398e5ca8fddSStefan Hajnoczi ]) 399e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'GenericError') 400e5ca8fddSStefan Hajnoczi 401e5ca8fddSStefan Hajnoczi def test_device_not_found(self): 402e5ca8fddSStefan Hajnoczi result = self.vm.qmp('transaction', actions=[{ 403e5ca8fddSStefan Hajnoczi 'type': 'drive-backup', 404e5ca8fddSStefan Hajnoczi 'data': { 'device': 'nonexistent', 405e5ca8fddSStefan Hajnoczi 'mode': 'existing', 406b53169eaSStefan Hajnoczi 'target': target_img, 407b53169eaSStefan Hajnoczi 'sync': 'full' }, 408e5ca8fddSStefan Hajnoczi } 409e5ca8fddSStefan Hajnoczi ]) 410b7e4fa22SKevin Wolf self.assert_qmp(result, 'error/class', 'GenericError') 411e5ca8fddSStefan Hajnoczi 4127c6a4ab8SFam Zheng result = self.vm.qmp('transaction', actions=[{ 4137c6a4ab8SFam Zheng 'type': 'blockdev-backup', 4147c6a4ab8SFam Zheng 'data': { 'device': 'nonexistent', 4157c6a4ab8SFam Zheng 'target': 'drive1', 4167c6a4ab8SFam Zheng 'sync': 'full' }, 4177c6a4ab8SFam Zheng } 4187c6a4ab8SFam Zheng ]) 4195b347c54SMarkus Armbruster self.assert_qmp(result, 'error/class', 'GenericError') 4207c6a4ab8SFam Zheng 4217c6a4ab8SFam Zheng result = self.vm.qmp('transaction', actions=[{ 4227c6a4ab8SFam Zheng 'type': 'blockdev-backup', 4237c6a4ab8SFam Zheng 'data': { 'device': 'drive0', 4247c6a4ab8SFam Zheng 'target': 'nonexistent', 4257c6a4ab8SFam Zheng 'sync': 'full' }, 4267c6a4ab8SFam Zheng } 4277c6a4ab8SFam Zheng ]) 4285b347c54SMarkus Armbruster self.assert_qmp(result, 'error/class', 'GenericError') 4297c6a4ab8SFam Zheng 4307c6a4ab8SFam Zheng result = self.vm.qmp('transaction', actions=[{ 4317c6a4ab8SFam Zheng 'type': 'blockdev-backup', 4327c6a4ab8SFam Zheng 'data': { 'device': 'nonexistent', 4337c6a4ab8SFam Zheng 'target': 'nonexistent', 4347c6a4ab8SFam Zheng 'sync': 'full' }, 4357c6a4ab8SFam Zheng } 4367c6a4ab8SFam Zheng ]) 4375b347c54SMarkus Armbruster self.assert_qmp(result, 'error/class', 'GenericError') 4387c6a4ab8SFam Zheng 4397c6a4ab8SFam Zheng def test_target_is_source(self): 4407c6a4ab8SFam Zheng result = self.vm.qmp('transaction', actions=[{ 4417c6a4ab8SFam Zheng 'type': 'blockdev-backup', 4427c6a4ab8SFam Zheng 'data': { 'device': 'drive0', 4437c6a4ab8SFam Zheng 'target': 'drive0', 4447c6a4ab8SFam Zheng 'sync': 'full' }, 4457c6a4ab8SFam Zheng } 4467c6a4ab8SFam Zheng ]) 4477c6a4ab8SFam Zheng self.assert_qmp(result, 'error/class', 'GenericError') 4487c6a4ab8SFam Zheng 449e5ca8fddSStefan Hajnoczi def test_abort(self): 450e5ca8fddSStefan Hajnoczi result = self.vm.qmp('transaction', actions=[{ 451e5ca8fddSStefan Hajnoczi 'type': 'drive-backup', 452e5ca8fddSStefan Hajnoczi 'data': { 'device': 'nonexistent', 453e5ca8fddSStefan Hajnoczi 'mode': 'existing', 454b53169eaSStefan Hajnoczi 'target': target_img, 455b53169eaSStefan Hajnoczi 'sync': 'full' }, 456e5ca8fddSStefan Hajnoczi }, { 457e5ca8fddSStefan Hajnoczi 'type': 'Abort', 458e5ca8fddSStefan Hajnoczi 'data': {}, 459e5ca8fddSStefan Hajnoczi } 460e5ca8fddSStefan Hajnoczi ]) 461e5ca8fddSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'GenericError') 462e5ca8fddSStefan Hajnoczi self.assert_no_active_block_jobs() 463e5ca8fddSStefan Hajnoczi 4647c6a4ab8SFam Zheng result = self.vm.qmp('transaction', actions=[{ 4657c6a4ab8SFam Zheng 'type': 'blockdev-backup', 4667c6a4ab8SFam Zheng 'data': { 'device': 'nonexistent', 4677c6a4ab8SFam Zheng 'target': 'drive1', 4687c6a4ab8SFam Zheng 'sync': 'full' }, 4697c6a4ab8SFam Zheng }, { 4707c6a4ab8SFam Zheng 'type': 'Abort', 4717c6a4ab8SFam Zheng 'data': {}, 4727c6a4ab8SFam Zheng } 4737c6a4ab8SFam Zheng ]) 4747c6a4ab8SFam Zheng self.assert_qmp(result, 'error/class', 'GenericError') 4757c6a4ab8SFam Zheng self.assert_no_active_block_jobs() 4767c6a4ab8SFam Zheng 4777c6a4ab8SFam Zheng result = self.vm.qmp('transaction', actions=[{ 4787c6a4ab8SFam Zheng 'type': 'blockdev-backup', 4797c6a4ab8SFam Zheng 'data': { 'device': 'drive0', 4807c6a4ab8SFam Zheng 'target': 'nonexistent', 4817c6a4ab8SFam Zheng 'sync': 'full' }, 4827c6a4ab8SFam Zheng }, { 4837c6a4ab8SFam Zheng 'type': 'Abort', 4847c6a4ab8SFam Zheng 'data': {}, 4857c6a4ab8SFam Zheng } 4867c6a4ab8SFam Zheng ]) 4877c6a4ab8SFam Zheng self.assert_qmp(result, 'error/class', 'GenericError') 4887c6a4ab8SFam Zheng self.assert_no_active_block_jobs() 4897c6a4ab8SFam Zheng 490e1b5c51fSPavel Butsykin 4918e837294SVladimir Sementsov-Ogievskiyclass TestCompressedToQcow2(iotests.QMPTestCase): 492e1b5c51fSPavel Butsykin image_len = 64 * 1024 * 1024 # MB 4936a9d73bdSKevin Wolf target_fmt = {'type': 'qcow2', 'args': (), 'drive-opts': ''} 494e1b5c51fSPavel Butsykin 495e1b5c51fSPavel Butsykin def tearDown(self): 496e1b5c51fSPavel Butsykin self.vm.shutdown() 497e1b5c51fSPavel Butsykin os.remove(blockdev_target_img) 498e1b5c51fSPavel Butsykin try: 499e1b5c51fSPavel Butsykin os.remove(target_img) 500e1b5c51fSPavel Butsykin except OSError: 501e1b5c51fSPavel Butsykin pass 502e1b5c51fSPavel Butsykin 5038e837294SVladimir Sementsov-Ogievskiy def do_prepare_drives(self, attach_target): 5046a9d73bdSKevin Wolf self.vm = iotests.VM().add_drive('blkdebug::' + test_img, 5056a9d73bdSKevin Wolf opts=self.target_fmt['drive-opts']) 50600198eccSPavel Butsykin 5078e837294SVladimir Sementsov-Ogievskiy qemu_img('create', '-f', self.target_fmt['type'], blockdev_target_img, 5088e837294SVladimir Sementsov-Ogievskiy str(self.image_len), *self.target_fmt['args']) 5094797aeabSFam Zheng if attach_target: 5101d3d4b63SJohn Snow self.vm.add_drive(blockdev_target_img, 5118e837294SVladimir Sementsov-Ogievskiy img_format=self.target_fmt['type'], 5126a9d73bdSKevin Wolf interface="none", 5136a9d73bdSKevin Wolf opts=self.target_fmt['drive-opts']) 51400198eccSPavel Butsykin 51500198eccSPavel Butsykin self.vm.launch() 51600198eccSPavel Butsykin 5178e837294SVladimir Sementsov-Ogievskiy def do_test_compress_complete(self, cmd, attach_target, **args): 5188e837294SVladimir Sementsov-Ogievskiy self.do_prepare_drives(attach_target) 51900198eccSPavel Butsykin 520e1b5c51fSPavel Butsykin self.assert_no_active_block_jobs() 521e1b5c51fSPavel Butsykin 522e1b5c51fSPavel Butsykin result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args) 523e1b5c51fSPavel Butsykin self.assert_qmp(result, 'return', {}) 524e1b5c51fSPavel Butsykin 525e1b5c51fSPavel Butsykin self.wait_until_completed() 526e1b5c51fSPavel Butsykin 527e1b5c51fSPavel Butsykin self.vm.shutdown() 528e1b5c51fSPavel Butsykin self.assertTrue(iotests.compare_images(test_img, blockdev_target_img, 5298e837294SVladimir Sementsov-Ogievskiy iotests.imgfmt, 5308e837294SVladimir Sementsov-Ogievskiy self.target_fmt['type']), 531e1b5c51fSPavel Butsykin 'target image does not match source after backup') 532e1b5c51fSPavel Butsykin 533e1b5c51fSPavel Butsykin def test_complete_compress_drive_backup(self): 5348e837294SVladimir Sementsov-Ogievskiy self.do_test_compress_complete('drive-backup', False, 5358e837294SVladimir Sementsov-Ogievskiy target=blockdev_target_img, 5368e837294SVladimir Sementsov-Ogievskiy mode='existing') 537e1b5c51fSPavel Butsykin 538e1b5c51fSPavel Butsykin def test_complete_compress_blockdev_backup(self): 5398e837294SVladimir Sementsov-Ogievskiy self.do_test_compress_complete('blockdev-backup', 5408e837294SVladimir Sementsov-Ogievskiy True, target='drive1') 541e1b5c51fSPavel Butsykin 5428e837294SVladimir Sementsov-Ogievskiy def do_test_compress_cancel(self, cmd, attach_target, **args): 5438e837294SVladimir Sementsov-Ogievskiy self.do_prepare_drives(attach_target) 54400198eccSPavel Butsykin 545e1b5c51fSPavel Butsykin self.assert_no_active_block_jobs() 546e1b5c51fSPavel Butsykin 547bc11aee2SMax Reitz self.vm.pause_drive('drive0') 548e1b5c51fSPavel Butsykin result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args) 549e1b5c51fSPavel Butsykin self.assert_qmp(result, 'return', {}) 550e1b5c51fSPavel Butsykin 551bc11aee2SMax Reitz event = self.cancel_and_wait(resume=True) 552e1b5c51fSPavel Butsykin self.assert_qmp(event, 'data/type', 'backup') 553e1b5c51fSPavel Butsykin 55400198eccSPavel Butsykin self.vm.shutdown() 55500198eccSPavel Butsykin 556e1b5c51fSPavel Butsykin def test_compress_cancel_drive_backup(self): 5578e837294SVladimir Sementsov-Ogievskiy self.do_test_compress_cancel('drive-backup', False, 5588e837294SVladimir Sementsov-Ogievskiy target=blockdev_target_img, 5598e837294SVladimir Sementsov-Ogievskiy mode='existing') 560e1b5c51fSPavel Butsykin 561e1b5c51fSPavel Butsykin def test_compress_cancel_blockdev_backup(self): 5628e837294SVladimir Sementsov-Ogievskiy self.do_test_compress_cancel('blockdev-backup', True, 5634797aeabSFam Zheng target='drive1') 564e1b5c51fSPavel Butsykin 5658e837294SVladimir Sementsov-Ogievskiy def do_test_compress_pause(self, cmd, attach_target, **args): 5668e837294SVladimir Sementsov-Ogievskiy self.do_prepare_drives(attach_target) 56700198eccSPavel Butsykin 568e1b5c51fSPavel Butsykin self.assert_no_active_block_jobs() 569e1b5c51fSPavel Butsykin 570e1b5c51fSPavel Butsykin self.vm.pause_drive('drive0') 571e1b5c51fSPavel Butsykin result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args) 572e1b5c51fSPavel Butsykin self.assert_qmp(result, 'return', {}) 573e1b5c51fSPavel Butsykin 574f03d9d24SJohn Snow self.pause_job('drive0', wait=False) 575e1b5c51fSPavel Butsykin self.vm.resume_drive('drive0') 576f03d9d24SJohn Snow self.pause_wait('drive0') 5772c93c5cbSKevin Wolf 578e1b5c51fSPavel Butsykin result = self.vm.qmp('query-block-jobs') 579e1b5c51fSPavel Butsykin offset = self.dictpath(result, 'return[0]/offset') 580e1b5c51fSPavel Butsykin 5812c93c5cbSKevin Wolf time.sleep(0.5) 582e1b5c51fSPavel Butsykin result = self.vm.qmp('query-block-jobs') 583e1b5c51fSPavel Butsykin self.assert_qmp(result, 'return[0]/offset', offset) 584e1b5c51fSPavel Butsykin 585e1b5c51fSPavel Butsykin result = self.vm.qmp('block-job-resume', device='drive0') 586e1b5c51fSPavel Butsykin self.assert_qmp(result, 'return', {}) 587e1b5c51fSPavel Butsykin 588e1b5c51fSPavel Butsykin self.wait_until_completed() 589e1b5c51fSPavel Butsykin 590e1b5c51fSPavel Butsykin self.vm.shutdown() 591e1b5c51fSPavel Butsykin self.assertTrue(iotests.compare_images(test_img, blockdev_target_img, 5928e837294SVladimir Sementsov-Ogievskiy iotests.imgfmt, 5938e837294SVladimir Sementsov-Ogievskiy self.target_fmt['type']), 594e1b5c51fSPavel Butsykin 'target image does not match source after backup') 595e1b5c51fSPavel Butsykin 596e1b5c51fSPavel Butsykin def test_compress_pause_drive_backup(self): 5978e837294SVladimir Sementsov-Ogievskiy self.do_test_compress_pause('drive-backup', False, 5988e837294SVladimir Sementsov-Ogievskiy target=blockdev_target_img, 5998e837294SVladimir Sementsov-Ogievskiy mode='existing') 600e1b5c51fSPavel Butsykin 601e1b5c51fSPavel Butsykin def test_compress_pause_blockdev_backup(self): 6028e837294SVladimir Sementsov-Ogievskiy self.do_test_compress_pause('blockdev-backup', True, 6034797aeabSFam Zheng target='drive1') 604e1b5c51fSPavel Butsykin 6058e837294SVladimir Sementsov-Ogievskiy 6068e837294SVladimir Sementsov-Ogievskiyclass TestCompressedToVmdk(TestCompressedToQcow2): 6076a9d73bdSKevin Wolf target_fmt = {'type': 'vmdk', 'args': ('-o', 'subformat=streamOptimized'), 6086a9d73bdSKevin Wolf 'drive-opts': 'cache.no-flush=on'} 6098e837294SVladimir Sementsov-Ogievskiy 610761cd2e7SVladimir Sementsov-Ogievskiy @iotests.skip_if_unsupported(['vmdk']) 611761cd2e7SVladimir Sementsov-Ogievskiy def setUp(self): 612761cd2e7SVladimir Sementsov-Ogievskiy pass 613761cd2e7SVladimir Sementsov-Ogievskiy 6148e837294SVladimir Sementsov-Ogievskiy 615e5ca8fddSStefan Hajnocziif __name__ == '__main__': 616103cbc77SMax Reitz iotests.main(supported_fmts=['raw', 'qcow2'], 617103cbc77SMax Reitz supported_protocols=['file']) 618