1adfe2030SMax Reitz#!/usr/bin/env python 2adfe2030SMax Reitz# 3adfe2030SMax Reitz# Test case for the QMP 'change' command and all other associated 4adfe2030SMax Reitz# commands 5adfe2030SMax Reitz# 6adfe2030SMax Reitz# Copyright (C) 2015 Red Hat, Inc. 7adfe2030SMax Reitz# 8adfe2030SMax Reitz# This program is free software; you can redistribute it and/or modify 9adfe2030SMax Reitz# it under the terms of the GNU General Public License as published by 10adfe2030SMax Reitz# the Free Software Foundation; either version 2 of the License, or 11adfe2030SMax Reitz# (at your option) any later version. 12adfe2030SMax Reitz# 13adfe2030SMax Reitz# This program is distributed in the hope that it will be useful, 14adfe2030SMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of 15adfe2030SMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16adfe2030SMax Reitz# GNU General Public License for more details. 17adfe2030SMax Reitz# 18adfe2030SMax Reitz# You should have received a copy of the GNU General Public License 19adfe2030SMax Reitz# along with this program. If not, see <http://www.gnu.org/licenses/>. 20adfe2030SMax Reitz# 21adfe2030SMax Reitz 22adfe2030SMax Reitzimport os 23adfe2030SMax Reitzimport stat 24adfe2030SMax Reitzimport time 25adfe2030SMax Reitzimport iotests 26adfe2030SMax Reitzfrom iotests import qemu_img 27adfe2030SMax Reitz 28adfe2030SMax Reitzold_img = os.path.join(iotests.test_dir, 'test0.img') 29adfe2030SMax Reitznew_img = os.path.join(iotests.test_dir, 'test1.img') 30adfe2030SMax Reitz 311d701e0eSMax Reitzdef interface_to_device_name(interface): 321d701e0eSMax Reitz if interface == 'ide': 331d701e0eSMax Reitz return 'ide-cd' 341d701e0eSMax Reitz elif interface == 'floppy': 351d701e0eSMax Reitz return 'floppy' 361d701e0eSMax Reitz else: 371d701e0eSMax Reitz return None 381d701e0eSMax Reitz 39adfe2030SMax Reitzclass ChangeBaseClass(iotests.QMPTestCase): 40adfe2030SMax Reitz has_opened = False 41adfe2030SMax Reitz has_closed = False 42adfe2030SMax Reitz 43adfe2030SMax Reitz def process_events(self): 44adfe2030SMax Reitz for event in self.vm.get_qmp_events(wait=False): 45adfe2030SMax Reitz if (event['event'] == 'DEVICE_TRAY_MOVED' and 46adfe2030SMax Reitz event['data']['device'] == 'drive0'): 47adfe2030SMax Reitz if event['data']['tray-open'] == False: 48adfe2030SMax Reitz self.has_closed = True 49adfe2030SMax Reitz else: 50adfe2030SMax Reitz self.has_opened = True 51adfe2030SMax Reitz 52adfe2030SMax Reitz def wait_for_open(self): 53abb3e55bSMax Reitz if not self.has_real_tray: 54abb3e55bSMax Reitz return 55abb3e55bSMax Reitz 56*d8336c6bSKevin Wolf with iotests.Timeout(3, 'Timeout while waiting for the tray to open'): 57*d8336c6bSKevin Wolf while not self.has_opened: 58adfe2030SMax Reitz self.process_events() 59adfe2030SMax Reitz 60adfe2030SMax Reitz def wait_for_close(self): 61abb3e55bSMax Reitz if not self.has_real_tray: 62abb3e55bSMax Reitz return 63abb3e55bSMax Reitz 64*d8336c6bSKevin Wolf with iotests.Timeout(3, 'Timeout while waiting for the tray to close'): 65*d8336c6bSKevin Wolf while not self.has_closed: 66adfe2030SMax Reitz self.process_events() 67adfe2030SMax Reitz 68adfe2030SMax Reitzclass GeneralChangeTestsBaseClass(ChangeBaseClass): 69486b88bdSKevin Wolf 701d701e0eSMax Reitz device_name = 'qdev0' 71486b88bdSKevin Wolf 72adfe2030SMax Reitz def test_change(self): 73adfe2030SMax Reitz result = self.vm.qmp('change', device='drive0', target=new_img, 74adfe2030SMax Reitz arg=iotests.imgfmt) 75adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 76adfe2030SMax Reitz 77adfe2030SMax Reitz self.wait_for_open() 78adfe2030SMax Reitz self.wait_for_close() 79adfe2030SMax Reitz 80adfe2030SMax Reitz result = self.vm.qmp('query-block') 81abb3e55bSMax Reitz if self.has_real_tray: 82adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 83adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 84adfe2030SMax Reitz 85adfe2030SMax Reitz def test_blockdev_change_medium(self): 86486b88bdSKevin Wolf result = self.vm.qmp('blockdev-change-medium', 87486b88bdSKevin Wolf id=self.device_name, filename=new_img, 88adfe2030SMax Reitz format=iotests.imgfmt) 89486b88bdSKevin Wolf 90adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 91adfe2030SMax Reitz 92adfe2030SMax Reitz self.wait_for_open() 93adfe2030SMax Reitz self.wait_for_close() 94adfe2030SMax Reitz 95adfe2030SMax Reitz result = self.vm.qmp('query-block') 96abb3e55bSMax Reitz if self.has_real_tray: 97adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 98adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 99adfe2030SMax Reitz 100adfe2030SMax Reitz def test_eject(self): 101486b88bdSKevin Wolf result = self.vm.qmp('eject', id=self.device_name, force=True) 102adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 103adfe2030SMax Reitz 104adfe2030SMax Reitz self.wait_for_open() 105adfe2030SMax Reitz 106adfe2030SMax Reitz result = self.vm.qmp('query-block') 107abb3e55bSMax Reitz if self.has_real_tray: 108adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 109adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 110adfe2030SMax Reitz 111adfe2030SMax Reitz def test_tray_eject_change(self): 112486b88bdSKevin Wolf result = self.vm.qmp('eject', id=self.device_name, force=True) 113adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 114adfe2030SMax Reitz 115adfe2030SMax Reitz self.wait_for_open() 116adfe2030SMax Reitz 117adfe2030SMax Reitz result = self.vm.qmp('query-block') 118abb3e55bSMax Reitz if self.has_real_tray: 119adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 120adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 121adfe2030SMax Reitz 122486b88bdSKevin Wolf result = self.vm.qmp('blockdev-change-medium', id=self.device_name, 123486b88bdSKevin Wolf filename=new_img, format=iotests.imgfmt) 124adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 125adfe2030SMax Reitz 126adfe2030SMax Reitz self.wait_for_close() 127adfe2030SMax Reitz 128adfe2030SMax Reitz result = self.vm.qmp('query-block') 129abb3e55bSMax Reitz if self.has_real_tray: 130adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 131adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 132adfe2030SMax Reitz 133adfe2030SMax Reitz def test_tray_open_close(self): 134486b88bdSKevin Wolf result = self.vm.qmp('blockdev-open-tray', 135486b88bdSKevin Wolf id=self.device_name, force=True) 136adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 137adfe2030SMax Reitz 138adfe2030SMax Reitz self.wait_for_open() 139adfe2030SMax Reitz 140adfe2030SMax Reitz result = self.vm.qmp('query-block') 141abb3e55bSMax Reitz if self.has_real_tray: 142adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 143adfe2030SMax Reitz if self.was_empty == True: 144adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 145adfe2030SMax Reitz else: 146adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 147adfe2030SMax Reitz 148486b88bdSKevin Wolf result = self.vm.qmp('blockdev-close-tray', id=self.device_name) 149adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 150adfe2030SMax Reitz 151adfe2030SMax Reitz if self.has_real_tray or not self.was_empty: 152adfe2030SMax Reitz self.wait_for_close() 153adfe2030SMax Reitz 154adfe2030SMax Reitz result = self.vm.qmp('query-block') 155abb3e55bSMax Reitz if self.has_real_tray: 156adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 157adfe2030SMax Reitz if self.was_empty == True: 158adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 159adfe2030SMax Reitz else: 160adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 161adfe2030SMax Reitz 162adfe2030SMax Reitz def test_tray_eject_close(self): 1631d701e0eSMax Reitz result = self.vm.qmp('eject', id=self.device_name, force=True) 164adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 165adfe2030SMax Reitz 166adfe2030SMax Reitz self.wait_for_open() 167adfe2030SMax Reitz 168adfe2030SMax Reitz result = self.vm.qmp('query-block') 169abb3e55bSMax Reitz if self.has_real_tray: 170adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 171adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 172adfe2030SMax Reitz 173486b88bdSKevin Wolf result = self.vm.qmp('blockdev-close-tray', id=self.device_name) 174adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 175adfe2030SMax Reitz 176adfe2030SMax Reitz self.wait_for_close() 177adfe2030SMax Reitz 178adfe2030SMax Reitz result = self.vm.qmp('query-block') 179adfe2030SMax Reitz if self.has_real_tray: 180adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 181adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 182adfe2030SMax Reitz 183adfe2030SMax Reitz def test_tray_open_change(self): 1841d701e0eSMax Reitz result = self.vm.qmp('blockdev-open-tray', id=self.device_name, 1851d701e0eSMax Reitz force=True) 186adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 187adfe2030SMax Reitz 188adfe2030SMax Reitz self.wait_for_open() 189adfe2030SMax Reitz 190adfe2030SMax Reitz result = self.vm.qmp('query-block') 191abb3e55bSMax Reitz if self.has_real_tray: 192adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 193adfe2030SMax Reitz if self.was_empty == True: 194adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 195adfe2030SMax Reitz else: 196adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 197adfe2030SMax Reitz 1981d701e0eSMax Reitz result = self.vm.qmp('blockdev-change-medium', id=self.device_name, 199adfe2030SMax Reitz filename=new_img, 200adfe2030SMax Reitz format=iotests.imgfmt) 201adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 202adfe2030SMax Reitz 203adfe2030SMax Reitz self.wait_for_close() 204adfe2030SMax Reitz 205adfe2030SMax Reitz result = self.vm.qmp('query-block') 206abb3e55bSMax Reitz if self.has_real_tray: 207adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 208adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 209adfe2030SMax Reitz 210adfe2030SMax Reitz def test_cycle(self): 211adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 2120153d2f5SKevin Wolf node_name='new', 2130153d2f5SKevin Wolf driver=iotests.imgfmt, 2140153d2f5SKevin Wolf file={'filename': new_img, 2150153d2f5SKevin Wolf 'driver': 'file'}) 216adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 217adfe2030SMax Reitz 218486b88bdSKevin Wolf result = self.vm.qmp('blockdev-open-tray', 219486b88bdSKevin Wolf id=self.device_name, force=True) 220adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 221adfe2030SMax Reitz 222adfe2030SMax Reitz self.wait_for_open() 223adfe2030SMax Reitz 224adfe2030SMax Reitz result = self.vm.qmp('query-block') 225abb3e55bSMax Reitz if self.has_real_tray: 226adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 227adfe2030SMax Reitz if self.was_empty == True: 228adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 229adfe2030SMax Reitz else: 230adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 231adfe2030SMax Reitz 23234ce1111SMax Reitz result = self.vm.qmp('blockdev-remove-medium', 233486b88bdSKevin Wolf id=self.device_name) 234adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 235adfe2030SMax Reitz 236adfe2030SMax Reitz result = self.vm.qmp('query-block') 237abb3e55bSMax Reitz if self.has_real_tray: 238adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 239adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 240adfe2030SMax Reitz 24134ce1111SMax Reitz result = self.vm.qmp('blockdev-insert-medium', 242486b88bdSKevin Wolf id=self.device_name, node_name='new') 243adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 244adfe2030SMax Reitz 245adfe2030SMax Reitz result = self.vm.qmp('query-block') 246abb3e55bSMax Reitz if self.has_real_tray: 247adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 248adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 249adfe2030SMax Reitz 250486b88bdSKevin Wolf result = self.vm.qmp('blockdev-close-tray', id=self.device_name) 251adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 252adfe2030SMax Reitz 253adfe2030SMax Reitz self.wait_for_close() 254adfe2030SMax Reitz 255adfe2030SMax Reitz result = self.vm.qmp('query-block') 256abb3e55bSMax Reitz if self.has_real_tray: 257adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 258adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 259adfe2030SMax Reitz 260adfe2030SMax Reitz def test_close_on_closed(self): 2611d701e0eSMax Reitz result = self.vm.qmp('blockdev-close-tray', id=self.device_name) 262adfe2030SMax Reitz # Should be a no-op 263adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 264adfe2030SMax Reitz self.assertEquals(self.vm.get_qmp_events(wait=False), []) 265adfe2030SMax Reitz 266adfe2030SMax Reitz def test_remove_on_closed(self): 267abb3e55bSMax Reitz if not self.has_real_tray: 268adfe2030SMax Reitz return 269adfe2030SMax Reitz 27034ce1111SMax Reitz result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) 271adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 272adfe2030SMax Reitz 273adfe2030SMax Reitz def test_insert_on_closed(self): 274abb3e55bSMax Reitz if not self.has_real_tray: 275adfe2030SMax Reitz return 276adfe2030SMax Reitz 277adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 2780153d2f5SKevin Wolf node_name='new', 2790153d2f5SKevin Wolf driver=iotests.imgfmt, 2800153d2f5SKevin Wolf file={'filename': new_img, 2810153d2f5SKevin Wolf 'driver': 'file'}) 282adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 283adfe2030SMax Reitz 28434ce1111SMax Reitz result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, 285adfe2030SMax Reitz node_name='new') 286adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 287adfe2030SMax Reitz 288adfe2030SMax Reitzclass TestInitiallyFilled(GeneralChangeTestsBaseClass): 289adfe2030SMax Reitz was_empty = False 290adfe2030SMax Reitz 291adfe2030SMax Reitz def setUp(self, media, interface): 292adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') 293adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') 294486b88bdSKevin Wolf self.vm = iotests.VM() 295486b88bdSKevin Wolf self.vm.add_drive(old_img, 'media=%s' % media, 'none') 2961d701e0eSMax Reitz self.vm.add_device('%s,drive=drive0,id=%s' % 2971d701e0eSMax Reitz (interface_to_device_name(interface), 2981d701e0eSMax Reitz self.device_name)) 299adfe2030SMax Reitz self.vm.launch() 300adfe2030SMax Reitz 301adfe2030SMax Reitz def tearDown(self): 302adfe2030SMax Reitz self.vm.shutdown() 303adfe2030SMax Reitz os.remove(old_img) 304adfe2030SMax Reitz os.remove(new_img) 305adfe2030SMax Reitz 306adfe2030SMax Reitz def test_insert_on_filled(self): 307adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 3080153d2f5SKevin Wolf node_name='new', 3090153d2f5SKevin Wolf driver=iotests.imgfmt, 3100153d2f5SKevin Wolf file={'filename': new_img, 3110153d2f5SKevin Wolf 'driver': 'file'}) 312adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 313adfe2030SMax Reitz 3141d701e0eSMax Reitz result = self.vm.qmp('blockdev-open-tray', id=self.device_name) 315adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 316adfe2030SMax Reitz 317adfe2030SMax Reitz self.wait_for_open() 318adfe2030SMax Reitz 31934ce1111SMax Reitz result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, 320adfe2030SMax Reitz node_name='new') 321adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 322adfe2030SMax Reitz 323adfe2030SMax Reitzclass TestInitiallyEmpty(GeneralChangeTestsBaseClass): 324adfe2030SMax Reitz was_empty = True 325adfe2030SMax Reitz 326adfe2030SMax Reitz def setUp(self, media, interface): 327adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') 3281d701e0eSMax Reitz self.vm = iotests.VM().add_drive(None, 'media=%s' % media, 'none') 3291d701e0eSMax Reitz self.vm.add_device('%s,drive=drive0,id=%s' % 3301d701e0eSMax Reitz (interface_to_device_name(interface), 3311d701e0eSMax Reitz self.device_name)) 332adfe2030SMax Reitz self.vm.launch() 333adfe2030SMax Reitz 334adfe2030SMax Reitz def tearDown(self): 335adfe2030SMax Reitz self.vm.shutdown() 336adfe2030SMax Reitz os.remove(new_img) 337adfe2030SMax Reitz 338adfe2030SMax Reitz def test_remove_on_empty(self): 3391d701e0eSMax Reitz result = self.vm.qmp('blockdev-open-tray', id=self.device_name) 340adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 341adfe2030SMax Reitz 342adfe2030SMax Reitz self.wait_for_open() 343adfe2030SMax Reitz 34434ce1111SMax Reitz result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) 345adfe2030SMax Reitz # Should be a no-op 346adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 347adfe2030SMax Reitz 348adfe2030SMax Reitzclass TestCDInitiallyFilled(TestInitiallyFilled): 349adfe2030SMax Reitz TestInitiallyFilled = TestInitiallyFilled 350adfe2030SMax Reitz has_real_tray = True 351adfe2030SMax Reitz 352adfe2030SMax Reitz def setUp(self): 353adfe2030SMax Reitz self.TestInitiallyFilled.setUp(self, 'cdrom', 'ide') 354adfe2030SMax Reitz 355adfe2030SMax Reitzclass TestCDInitiallyEmpty(TestInitiallyEmpty): 356adfe2030SMax Reitz TestInitiallyEmpty = TestInitiallyEmpty 357adfe2030SMax Reitz has_real_tray = True 358adfe2030SMax Reitz 359adfe2030SMax Reitz def setUp(self): 360adfe2030SMax Reitz self.TestInitiallyEmpty.setUp(self, 'cdrom', 'ide') 361adfe2030SMax Reitz 362adfe2030SMax Reitzclass TestFloppyInitiallyFilled(TestInitiallyFilled): 363adfe2030SMax Reitz TestInitiallyFilled = TestInitiallyFilled 364adfe2030SMax Reitz has_real_tray = False 365adfe2030SMax Reitz 366adfe2030SMax Reitz def setUp(self): 367adfe2030SMax Reitz self.TestInitiallyFilled.setUp(self, 'disk', 'floppy') 368adfe2030SMax Reitz 369adfe2030SMax Reitzclass TestFloppyInitiallyEmpty(TestInitiallyEmpty): 370adfe2030SMax Reitz TestInitiallyEmpty = TestInitiallyEmpty 371adfe2030SMax Reitz has_real_tray = False 372adfe2030SMax Reitz 373adfe2030SMax Reitz def setUp(self): 374adfe2030SMax Reitz self.TestInitiallyEmpty.setUp(self, 'disk', 'floppy') 375adfe2030SMax Reitz # FDDs not having a real tray and there not being a medium inside the 376adfe2030SMax Reitz # tray at startup means the tray will be considered open 377adfe2030SMax Reitz self.has_opened = True 378adfe2030SMax Reitz 379adfe2030SMax Reitzclass TestChangeReadOnly(ChangeBaseClass): 3801d701e0eSMax Reitz device_name = 'qdev0' 3811d701e0eSMax Reitz 382adfe2030SMax Reitz def setUp(self): 383adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') 384adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') 385adfe2030SMax Reitz self.vm = iotests.VM() 386adfe2030SMax Reitz 387adfe2030SMax Reitz def tearDown(self): 388adfe2030SMax Reitz self.vm.shutdown() 3894803c5cdSEduardo Habkost os.chmod(old_img, 0o666) 3904803c5cdSEduardo Habkost os.chmod(new_img, 0o666) 391adfe2030SMax Reitz os.remove(old_img) 392adfe2030SMax Reitz os.remove(new_img) 393adfe2030SMax Reitz 394adfe2030SMax Reitz def test_ro_ro_retain(self): 3954803c5cdSEduardo Habkost os.chmod(old_img, 0o444) 3964803c5cdSEduardo Habkost os.chmod(new_img, 0o444) 3971d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') 3981d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 399adfe2030SMax Reitz self.vm.launch() 400adfe2030SMax Reitz 401adfe2030SMax Reitz result = self.vm.qmp('query-block') 402adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 403adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 404adfe2030SMax Reitz 4051d701e0eSMax Reitz result = self.vm.qmp('blockdev-change-medium', id=self.device_name, 406adfe2030SMax Reitz filename=new_img, 407adfe2030SMax Reitz format=iotests.imgfmt, 408adfe2030SMax Reitz read_only_mode='retain') 409adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 410adfe2030SMax Reitz 411adfe2030SMax Reitz result = self.vm.qmp('query-block') 412adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 413adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 414adfe2030SMax Reitz 415adfe2030SMax Reitz def test_ro_rw_retain(self): 4164803c5cdSEduardo Habkost os.chmod(old_img, 0o444) 4171d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') 4181d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 419adfe2030SMax Reitz self.vm.launch() 420adfe2030SMax Reitz 421adfe2030SMax Reitz result = self.vm.qmp('query-block') 422adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 423adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 424adfe2030SMax Reitz 4251d701e0eSMax Reitz result = self.vm.qmp('blockdev-change-medium', id=self.device_name, 426adfe2030SMax Reitz filename=new_img, 427adfe2030SMax Reitz format=iotests.imgfmt, 428adfe2030SMax Reitz read_only_mode='retain') 429adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 430adfe2030SMax Reitz 431adfe2030SMax Reitz result = self.vm.qmp('query-block') 432adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 433adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 434adfe2030SMax Reitz 435adfe2030SMax Reitz def test_rw_ro_retain(self): 4364803c5cdSEduardo Habkost os.chmod(new_img, 0o444) 4371d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk', 'none') 4381d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 439adfe2030SMax Reitz self.vm.launch() 440adfe2030SMax Reitz 441adfe2030SMax Reitz result = self.vm.qmp('query-block') 442adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 443adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 444adfe2030SMax Reitz 4451d701e0eSMax Reitz result = self.vm.qmp('blockdev-change-medium', id=self.device_name, 446adfe2030SMax Reitz filename=new_img, 447adfe2030SMax Reitz format=iotests.imgfmt, 448adfe2030SMax Reitz read_only_mode='retain') 449adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 450adfe2030SMax Reitz 451adfe2030SMax Reitz self.assertEquals(self.vm.get_qmp_events(wait=False), []) 452adfe2030SMax Reitz 453adfe2030SMax Reitz result = self.vm.qmp('query-block') 454adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 455adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 456adfe2030SMax Reitz 457adfe2030SMax Reitz def test_ro_rw(self): 4584803c5cdSEduardo Habkost os.chmod(old_img, 0o444) 4591d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') 4601d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 461adfe2030SMax Reitz self.vm.launch() 462adfe2030SMax Reitz 463adfe2030SMax Reitz result = self.vm.qmp('query-block') 464adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 465adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 466adfe2030SMax Reitz 467adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 4681d701e0eSMax Reitz id=self.device_name, 469adfe2030SMax Reitz filename=new_img, 470adfe2030SMax Reitz format=iotests.imgfmt, 471adfe2030SMax Reitz read_only_mode='read-write') 472adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 473adfe2030SMax Reitz 474adfe2030SMax Reitz result = self.vm.qmp('query-block') 475adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 476adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 477adfe2030SMax Reitz 478adfe2030SMax Reitz def test_rw_ro(self): 4794803c5cdSEduardo Habkost os.chmod(new_img, 0o444) 4801d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk', 'none') 4811d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 482adfe2030SMax Reitz self.vm.launch() 483adfe2030SMax Reitz 484adfe2030SMax Reitz result = self.vm.qmp('query-block') 485adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 486adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 487adfe2030SMax Reitz 488adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 4891d701e0eSMax Reitz id=self.device_name, 490adfe2030SMax Reitz filename=new_img, 491adfe2030SMax Reitz format=iotests.imgfmt, 492adfe2030SMax Reitz read_only_mode='read-only') 493adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 494adfe2030SMax Reitz 495adfe2030SMax Reitz result = self.vm.qmp('query-block') 496adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 497adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 498adfe2030SMax Reitz 499adfe2030SMax Reitz def test_make_rw_ro(self): 5001d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk', 'none') 5011d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 502adfe2030SMax Reitz self.vm.launch() 503adfe2030SMax Reitz 504adfe2030SMax Reitz result = self.vm.qmp('query-block') 505adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 506adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 507adfe2030SMax Reitz 508adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 5091d701e0eSMax Reitz id=self.device_name, 510adfe2030SMax Reitz filename=new_img, 511adfe2030SMax Reitz format=iotests.imgfmt, 512adfe2030SMax Reitz read_only_mode='read-only') 513adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 514adfe2030SMax Reitz 515adfe2030SMax Reitz result = self.vm.qmp('query-block') 516adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 517adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 518adfe2030SMax Reitz 519adfe2030SMax Reitz def test_make_ro_rw(self): 5204803c5cdSEduardo Habkost os.chmod(new_img, 0o444) 5211d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk', 'none') 5221d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 523adfe2030SMax Reitz self.vm.launch() 524adfe2030SMax Reitz 525adfe2030SMax Reitz result = self.vm.qmp('query-block') 526adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 527adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 528adfe2030SMax Reitz 529adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 5301d701e0eSMax Reitz id=self.device_name, 531adfe2030SMax Reitz filename=new_img, 532adfe2030SMax Reitz format=iotests.imgfmt, 533adfe2030SMax Reitz read_only_mode='read-write') 534adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 535adfe2030SMax Reitz 536adfe2030SMax Reitz result = self.vm.qmp('query-block') 537adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 538adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 539adfe2030SMax Reitz 540adfe2030SMax Reitz def test_make_rw_ro_by_retain(self): 5414803c5cdSEduardo Habkost os.chmod(old_img, 0o444) 5421d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') 5431d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 544adfe2030SMax Reitz self.vm.launch() 545adfe2030SMax Reitz 546adfe2030SMax Reitz result = self.vm.qmp('query-block') 547adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 548adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 549adfe2030SMax Reitz 5501d701e0eSMax Reitz result = self.vm.qmp('blockdev-change-medium', id=self.device_name, 551adfe2030SMax Reitz filename=new_img, 552adfe2030SMax Reitz format=iotests.imgfmt, 553adfe2030SMax Reitz read_only_mode='retain') 554adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 555adfe2030SMax Reitz 556adfe2030SMax Reitz result = self.vm.qmp('query-block') 557adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 558adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 559adfe2030SMax Reitz 560adfe2030SMax Reitz def test_make_ro_rw_by_retain(self): 5614803c5cdSEduardo Habkost os.chmod(new_img, 0o444) 5621d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk', 'none') 5631d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 564adfe2030SMax Reitz self.vm.launch() 565adfe2030SMax Reitz 566adfe2030SMax Reitz result = self.vm.qmp('query-block') 567adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 568adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 569adfe2030SMax Reitz 5701d701e0eSMax Reitz result = self.vm.qmp('blockdev-change-medium', id=self.device_name, 571adfe2030SMax Reitz filename=new_img, 572adfe2030SMax Reitz format=iotests.imgfmt, 573adfe2030SMax Reitz read_only_mode='retain') 574adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 575adfe2030SMax Reitz 576adfe2030SMax Reitz result = self.vm.qmp('query-block') 577adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 578adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 579adfe2030SMax Reitz 580adfe2030SMax Reitz def test_rw_ro_cycle(self): 5814803c5cdSEduardo Habkost os.chmod(new_img, 0o444) 5821d701e0eSMax Reitz self.vm.add_drive(old_img, 'media=disk', 'none') 5831d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 584adfe2030SMax Reitz self.vm.launch() 585adfe2030SMax Reitz 586adfe2030SMax Reitz result = self.vm.qmp('query-block') 587adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 588adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 589adfe2030SMax Reitz 590adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 5910153d2f5SKevin Wolf node_name='new', 5920153d2f5SKevin Wolf driver=iotests.imgfmt, 5930153d2f5SKevin Wolf read_only=True, 5940153d2f5SKevin Wolf file={'filename': new_img, 5950153d2f5SKevin Wolf 'driver': 'file'}) 596adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 597adfe2030SMax Reitz 598adfe2030SMax Reitz result = self.vm.qmp('query-block') 599adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 600adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 601adfe2030SMax Reitz 60234ce1111SMax Reitz result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) 603adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 604adfe2030SMax Reitz 605adfe2030SMax Reitz result = self.vm.qmp('query-block') 606adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 607adfe2030SMax Reitz 60834ce1111SMax Reitz result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, 609adfe2030SMax Reitz node_name='new') 610adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 611adfe2030SMax Reitz 612adfe2030SMax Reitz result = self.vm.qmp('query-block') 613adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 614adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 615adfe2030SMax Reitz 616adfe2030SMax Reitz result = self.vm.qmp('query-block') 617adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 618adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 619adfe2030SMax Reitz 620adfe2030SMax ReitzGeneralChangeTestsBaseClass = None 621adfe2030SMax ReitzTestInitiallyFilled = None 622adfe2030SMax ReitzTestInitiallyEmpty = None 623adfe2030SMax Reitz 624adfe2030SMax Reitz 625adfe2030SMax Reitzclass TestBlockJobsAfterCycle(ChangeBaseClass): 6261d701e0eSMax Reitz device_name = 'qdev0' 6271d701e0eSMax Reitz 628adfe2030SMax Reitz def setUp(self): 6291d701e0eSMax Reitz qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K') 630adfe2030SMax Reitz 631adfe2030SMax Reitz self.vm = iotests.VM() 632e4fd2e9dSKevin Wolf self.vm.add_drive_raw("id=drive0,driver=null-co,if=none") 6331d701e0eSMax Reitz self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) 634adfe2030SMax Reitz self.vm.launch() 635adfe2030SMax Reitz 636adfe2030SMax Reitz result = self.vm.qmp('query-block') 637adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co') 638adfe2030SMax Reitz 639adfe2030SMax Reitz # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray 640adfe2030SMax Reitz # is not necessary 64134ce1111SMax Reitz result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) 642adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 643adfe2030SMax Reitz 644adfe2030SMax Reitz result = self.vm.qmp('query-block') 645adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 646adfe2030SMax Reitz 647adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 6480153d2f5SKevin Wolf node_name='node0', 6490153d2f5SKevin Wolf driver=iotests.imgfmt, 6500153d2f5SKevin Wolf file={'filename': old_img, 6510153d2f5SKevin Wolf 'driver': 'file'}) 652adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 653adfe2030SMax Reitz 65434ce1111SMax Reitz result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, 655adfe2030SMax Reitz node_name='node0') 656adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 657adfe2030SMax Reitz 658adfe2030SMax Reitz result = self.vm.qmp('query-block') 659adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 660adfe2030SMax Reitz 661adfe2030SMax Reitz def tearDown(self): 662adfe2030SMax Reitz self.vm.shutdown() 663adfe2030SMax Reitz os.remove(old_img) 664adfe2030SMax Reitz try: 665adfe2030SMax Reitz os.remove(new_img) 666adfe2030SMax Reitz except OSError: 667adfe2030SMax Reitz pass 668adfe2030SMax Reitz 669adfe2030SMax Reitz def test_snapshot_and_commit(self): 670adfe2030SMax Reitz # We need backing file support 671adfe2030SMax Reitz if iotests.imgfmt != 'qcow2' and iotests.imgfmt != 'qed': 672adfe2030SMax Reitz return 673adfe2030SMax Reitz 674adfe2030SMax Reitz result = self.vm.qmp('blockdev-snapshot-sync', device='drive0', 675adfe2030SMax Reitz snapshot_file=new_img, 676adfe2030SMax Reitz format=iotests.imgfmt) 677adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 678adfe2030SMax Reitz 679adfe2030SMax Reitz result = self.vm.qmp('query-block') 680adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 681adfe2030SMax Reitz self.assert_qmp(result, 682adfe2030SMax Reitz 'return[0]/inserted/image/backing-image/filename', 683adfe2030SMax Reitz old_img) 684adfe2030SMax Reitz 685adfe2030SMax Reitz result = self.vm.qmp('block-commit', device='drive0') 686adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 687adfe2030SMax Reitz 688adfe2030SMax Reitz self.vm.event_wait(name='BLOCK_JOB_READY') 689adfe2030SMax Reitz 690adfe2030SMax Reitz result = self.vm.qmp('query-block-jobs') 691adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/device', 'drive0') 692adfe2030SMax Reitz 693adfe2030SMax Reitz result = self.vm.qmp('block-job-complete', device='drive0') 694adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 695adfe2030SMax Reitz 696adfe2030SMax Reitz self.vm.event_wait(name='BLOCK_JOB_COMPLETED') 697adfe2030SMax Reitz 698adfe2030SMax Reitz 699adfe2030SMax Reitzif __name__ == '__main__': 700adfe2030SMax Reitz if iotests.qemu_default_machine != 'pc': 701adfe2030SMax Reitz # We need floppy and IDE CD-ROM 702adfe2030SMax Reitz iotests.notrun('not suitable for this machine type: %s' % 703adfe2030SMax Reitz iotests.qemu_default_machine) 704cc8c46b7SMax Reitz # Need to support image creation 705cc8c46b7SMax Reitz iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2', 706cc8c46b7SMax Reitz 'vmdk', 'raw', 'vhdx', 'qed']) 707