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 31adfe2030SMax Reitzclass ChangeBaseClass(iotests.QMPTestCase): 32adfe2030SMax Reitz has_opened = False 33adfe2030SMax Reitz has_closed = False 34adfe2030SMax Reitz 35adfe2030SMax Reitz def process_events(self): 36adfe2030SMax Reitz for event in self.vm.get_qmp_events(wait=False): 37adfe2030SMax Reitz if (event['event'] == 'DEVICE_TRAY_MOVED' and 38adfe2030SMax Reitz event['data']['device'] == 'drive0'): 39adfe2030SMax Reitz if event['data']['tray-open'] == False: 40adfe2030SMax Reitz self.has_closed = True 41adfe2030SMax Reitz else: 42adfe2030SMax Reitz self.has_opened = True 43adfe2030SMax Reitz 44adfe2030SMax Reitz def wait_for_open(self): 45adfe2030SMax Reitz timeout = time.clock() + 3 46adfe2030SMax Reitz while not self.has_opened and time.clock() < timeout: 47adfe2030SMax Reitz self.process_events() 48adfe2030SMax Reitz if not self.has_opened: 49adfe2030SMax Reitz self.fail('Timeout while waiting for the tray to open') 50adfe2030SMax Reitz 51adfe2030SMax Reitz def wait_for_close(self): 52adfe2030SMax Reitz timeout = time.clock() + 3 53adfe2030SMax Reitz while not self.has_closed and time.clock() < timeout: 54adfe2030SMax Reitz self.process_events() 55adfe2030SMax Reitz if not self.has_opened: 56adfe2030SMax Reitz self.fail('Timeout while waiting for the tray to close') 57adfe2030SMax Reitz 58adfe2030SMax Reitzclass GeneralChangeTestsBaseClass(ChangeBaseClass): 59adfe2030SMax Reitz def test_change(self): 60adfe2030SMax Reitz result = self.vm.qmp('change', device='drive0', target=new_img, 61adfe2030SMax Reitz arg=iotests.imgfmt) 62adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 63adfe2030SMax Reitz 64adfe2030SMax Reitz self.wait_for_open() 65adfe2030SMax Reitz self.wait_for_close() 66adfe2030SMax Reitz 67adfe2030SMax Reitz result = self.vm.qmp('query-block') 68adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 69adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 70adfe2030SMax Reitz 71adfe2030SMax Reitz def test_blockdev_change_medium(self): 72adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 73adfe2030SMax Reitz filename=new_img, 74adfe2030SMax Reitz format=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') 81adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 82adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 83adfe2030SMax Reitz 84adfe2030SMax Reitz def test_eject(self): 85adfe2030SMax Reitz result = self.vm.qmp('eject', device='drive0', force=True) 86adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 87adfe2030SMax Reitz 88adfe2030SMax Reitz self.wait_for_open() 89adfe2030SMax Reitz 90adfe2030SMax Reitz result = self.vm.qmp('query-block') 91adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 92adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 93adfe2030SMax Reitz 94adfe2030SMax Reitz def test_tray_eject_change(self): 95adfe2030SMax Reitz result = self.vm.qmp('eject', device='drive0', force=True) 96adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 97adfe2030SMax Reitz 98adfe2030SMax Reitz self.wait_for_open() 99adfe2030SMax Reitz 100adfe2030SMax Reitz result = self.vm.qmp('query-block') 101adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 102adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 103adfe2030SMax Reitz 104adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 105adfe2030SMax Reitz filename=new_img, 106adfe2030SMax Reitz format=iotests.imgfmt) 107adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 108adfe2030SMax Reitz 109adfe2030SMax Reitz self.wait_for_close() 110adfe2030SMax Reitz 111adfe2030SMax Reitz result = self.vm.qmp('query-block') 112adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 113adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 114adfe2030SMax Reitz 115adfe2030SMax Reitz def test_tray_open_close(self): 116adfe2030SMax Reitz result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True) 117adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 118adfe2030SMax Reitz 119adfe2030SMax Reitz self.wait_for_open() 120adfe2030SMax Reitz 121adfe2030SMax Reitz result = self.vm.qmp('query-block') 122adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 123adfe2030SMax Reitz if self.was_empty == True: 124adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 125adfe2030SMax Reitz else: 126adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 127adfe2030SMax Reitz 128adfe2030SMax Reitz result = self.vm.qmp('blockdev-close-tray', device='drive0') 129adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 130adfe2030SMax Reitz 131adfe2030SMax Reitz if self.has_real_tray or not self.was_empty: 132adfe2030SMax Reitz self.wait_for_close() 133adfe2030SMax Reitz 134adfe2030SMax Reitz result = self.vm.qmp('query-block') 135adfe2030SMax Reitz if self.has_real_tray or not self.was_empty: 136adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 137adfe2030SMax Reitz else: 138adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 139adfe2030SMax Reitz if self.was_empty == True: 140adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 141adfe2030SMax Reitz else: 142adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 143adfe2030SMax Reitz 144adfe2030SMax Reitz def test_tray_eject_close(self): 145adfe2030SMax Reitz result = self.vm.qmp('eject', device='drive0', force=True) 146adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 147adfe2030SMax Reitz 148adfe2030SMax Reitz self.wait_for_open() 149adfe2030SMax Reitz 150adfe2030SMax Reitz result = self.vm.qmp('query-block') 151adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 152adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 153adfe2030SMax Reitz 154adfe2030SMax Reitz result = self.vm.qmp('blockdev-close-tray', device='drive0') 155adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 156adfe2030SMax Reitz 157adfe2030SMax Reitz if self.has_real_tray: 158adfe2030SMax Reitz self.wait_for_close() 159adfe2030SMax Reitz 160adfe2030SMax Reitz result = self.vm.qmp('query-block') 161adfe2030SMax Reitz if self.has_real_tray: 162adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 163adfe2030SMax Reitz else: 164adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 165adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 166adfe2030SMax Reitz 167adfe2030SMax Reitz def test_tray_open_change(self): 168adfe2030SMax Reitz result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True) 169adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 170adfe2030SMax Reitz 171adfe2030SMax Reitz self.wait_for_open() 172adfe2030SMax Reitz 173adfe2030SMax Reitz result = self.vm.qmp('query-block') 174adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 175adfe2030SMax Reitz if self.was_empty == True: 176adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 177adfe2030SMax Reitz else: 178adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 179adfe2030SMax Reitz 180adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 181adfe2030SMax Reitz filename=new_img, 182adfe2030SMax Reitz format=iotests.imgfmt) 183adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 184adfe2030SMax Reitz 185adfe2030SMax Reitz self.wait_for_close() 186adfe2030SMax Reitz 187adfe2030SMax Reitz result = self.vm.qmp('query-block') 188adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 189adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 190adfe2030SMax Reitz 191adfe2030SMax Reitz def test_cycle(self): 192adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 193adfe2030SMax Reitz options={'node-name': 'new', 194adfe2030SMax Reitz 'driver': iotests.imgfmt, 195adfe2030SMax Reitz 'file': {'filename': new_img, 196adfe2030SMax Reitz 'driver': 'file'}}) 197adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 198adfe2030SMax Reitz 199adfe2030SMax Reitz result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True) 200adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 201adfe2030SMax Reitz 202adfe2030SMax Reitz self.wait_for_open() 203adfe2030SMax Reitz 204adfe2030SMax Reitz result = self.vm.qmp('query-block') 205adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 206adfe2030SMax Reitz if self.was_empty == True: 207adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 208adfe2030SMax Reitz else: 209adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 210adfe2030SMax Reitz 211*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') 212adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 213adfe2030SMax Reitz 214adfe2030SMax Reitz result = self.vm.qmp('query-block') 215adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 216adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 217adfe2030SMax Reitz 218*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', 219adfe2030SMax Reitz node_name='new') 220adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 221adfe2030SMax Reitz 222adfe2030SMax Reitz result = self.vm.qmp('query-block') 223adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 224adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 225adfe2030SMax Reitz 226adfe2030SMax Reitz result = self.vm.qmp('blockdev-close-tray', device='drive0') 227adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 228adfe2030SMax Reitz 229adfe2030SMax Reitz self.wait_for_close() 230adfe2030SMax Reitz 231adfe2030SMax Reitz result = self.vm.qmp('query-block') 232adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 233adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 234adfe2030SMax Reitz 235adfe2030SMax Reitz def test_close_on_closed(self): 236adfe2030SMax Reitz result = self.vm.qmp('blockdev-close-tray', device='drive0') 237adfe2030SMax Reitz # Should be a no-op 238adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 239adfe2030SMax Reitz self.assertEquals(self.vm.get_qmp_events(wait=False), []) 240adfe2030SMax Reitz 241adfe2030SMax Reitz def test_remove_on_closed(self): 242adfe2030SMax Reitz if self.has_opened: 243adfe2030SMax Reitz # Empty floppy drive 244adfe2030SMax Reitz return 245adfe2030SMax Reitz 246*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') 247adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 248adfe2030SMax Reitz 249adfe2030SMax Reitz def test_insert_on_closed(self): 250adfe2030SMax Reitz if self.has_opened: 251adfe2030SMax Reitz # Empty floppy drive 252adfe2030SMax Reitz return 253adfe2030SMax Reitz 254adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 255adfe2030SMax Reitz options={'node-name': 'new', 256adfe2030SMax Reitz 'driver': iotests.imgfmt, 257adfe2030SMax Reitz 'file': {'filename': new_img, 258adfe2030SMax Reitz 'driver': 'file'}}) 259adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 260adfe2030SMax Reitz 261*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', 262adfe2030SMax Reitz node_name='new') 263adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 264adfe2030SMax Reitz 265adfe2030SMax Reitzclass TestInitiallyFilled(GeneralChangeTestsBaseClass): 266adfe2030SMax Reitz was_empty = False 267adfe2030SMax Reitz 268adfe2030SMax Reitz def setUp(self, media, interface): 269adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') 270adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') 271adfe2030SMax Reitz self.vm = iotests.VM().add_drive(old_img, 'media=%s' % media, interface) 272adfe2030SMax Reitz self.vm.launch() 273adfe2030SMax Reitz 274adfe2030SMax Reitz def tearDown(self): 275adfe2030SMax Reitz self.vm.shutdown() 276adfe2030SMax Reitz os.remove(old_img) 277adfe2030SMax Reitz os.remove(new_img) 278adfe2030SMax Reitz 279adfe2030SMax Reitz def test_insert_on_filled(self): 280adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 281adfe2030SMax Reitz options={'node-name': 'new', 282adfe2030SMax Reitz 'driver': iotests.imgfmt, 283adfe2030SMax Reitz 'file': {'filename': new_img, 284adfe2030SMax Reitz 'driver': 'file'}}) 285adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 286adfe2030SMax Reitz 287adfe2030SMax Reitz result = self.vm.qmp('blockdev-open-tray', device='drive0') 288adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 289adfe2030SMax Reitz 290adfe2030SMax Reitz self.wait_for_open() 291adfe2030SMax Reitz 292*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', 293adfe2030SMax Reitz node_name='new') 294adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 295adfe2030SMax Reitz 296adfe2030SMax Reitzclass TestInitiallyEmpty(GeneralChangeTestsBaseClass): 297adfe2030SMax Reitz was_empty = True 298adfe2030SMax Reitz 299adfe2030SMax Reitz def setUp(self, media, interface): 300adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') 301adfe2030SMax Reitz self.vm = iotests.VM().add_drive(None, 'media=%s' % media, interface) 302adfe2030SMax Reitz self.vm.launch() 303adfe2030SMax Reitz 304adfe2030SMax Reitz def tearDown(self): 305adfe2030SMax Reitz self.vm.shutdown() 306adfe2030SMax Reitz os.remove(new_img) 307adfe2030SMax Reitz 308adfe2030SMax Reitz def test_remove_on_empty(self): 309adfe2030SMax Reitz result = self.vm.qmp('blockdev-open-tray', device='drive0') 310adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 311adfe2030SMax Reitz 312adfe2030SMax Reitz self.wait_for_open() 313adfe2030SMax Reitz 314*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') 315adfe2030SMax Reitz # Should be a no-op 316adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 317adfe2030SMax Reitz 318adfe2030SMax Reitzclass TestCDInitiallyFilled(TestInitiallyFilled): 319adfe2030SMax Reitz TestInitiallyFilled = TestInitiallyFilled 320adfe2030SMax Reitz has_real_tray = True 321adfe2030SMax Reitz 322adfe2030SMax Reitz def setUp(self): 323adfe2030SMax Reitz self.TestInitiallyFilled.setUp(self, 'cdrom', 'ide') 324adfe2030SMax Reitz 325adfe2030SMax Reitzclass TestCDInitiallyEmpty(TestInitiallyEmpty): 326adfe2030SMax Reitz TestInitiallyEmpty = TestInitiallyEmpty 327adfe2030SMax Reitz has_real_tray = True 328adfe2030SMax Reitz 329adfe2030SMax Reitz def setUp(self): 330adfe2030SMax Reitz self.TestInitiallyEmpty.setUp(self, 'cdrom', 'ide') 331adfe2030SMax Reitz 332adfe2030SMax Reitzclass TestFloppyInitiallyFilled(TestInitiallyFilled): 333adfe2030SMax Reitz TestInitiallyFilled = TestInitiallyFilled 334adfe2030SMax Reitz has_real_tray = False 335adfe2030SMax Reitz 336adfe2030SMax Reitz def setUp(self): 337adfe2030SMax Reitz self.TestInitiallyFilled.setUp(self, 'disk', 'floppy') 338adfe2030SMax Reitz 339adfe2030SMax Reitzclass TestFloppyInitiallyEmpty(TestInitiallyEmpty): 340adfe2030SMax Reitz TestInitiallyEmpty = TestInitiallyEmpty 341adfe2030SMax Reitz has_real_tray = False 342adfe2030SMax Reitz 343adfe2030SMax Reitz def setUp(self): 344adfe2030SMax Reitz self.TestInitiallyEmpty.setUp(self, 'disk', 'floppy') 345adfe2030SMax Reitz # FDDs not having a real tray and there not being a medium inside the 346adfe2030SMax Reitz # tray at startup means the tray will be considered open 347adfe2030SMax Reitz self.has_opened = True 348adfe2030SMax Reitz 349adfe2030SMax Reitzclass TestChangeReadOnly(ChangeBaseClass): 350adfe2030SMax Reitz def setUp(self): 351adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') 352adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') 353adfe2030SMax Reitz self.vm = iotests.VM() 354adfe2030SMax Reitz 355adfe2030SMax Reitz def tearDown(self): 356adfe2030SMax Reitz self.vm.shutdown() 357adfe2030SMax Reitz os.chmod(old_img, 0666) 358adfe2030SMax Reitz os.chmod(new_img, 0666) 359adfe2030SMax Reitz os.remove(old_img) 360adfe2030SMax Reitz os.remove(new_img) 361adfe2030SMax Reitz 362adfe2030SMax Reitz def test_ro_ro_retain(self): 363adfe2030SMax Reitz os.chmod(old_img, 0444) 364adfe2030SMax Reitz os.chmod(new_img, 0444) 365adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') 366adfe2030SMax Reitz self.vm.launch() 367adfe2030SMax Reitz 368adfe2030SMax Reitz result = self.vm.qmp('query-block') 369adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 370adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 371adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 372adfe2030SMax Reitz 373adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 374adfe2030SMax Reitz filename=new_img, 375adfe2030SMax Reitz format=iotests.imgfmt, 376adfe2030SMax Reitz read_only_mode='retain') 377adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 378adfe2030SMax Reitz 379adfe2030SMax Reitz self.wait_for_open() 380adfe2030SMax Reitz self.wait_for_close() 381adfe2030SMax Reitz 382adfe2030SMax Reitz result = self.vm.qmp('query-block') 383adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 384adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 385adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 386adfe2030SMax Reitz 387adfe2030SMax Reitz def test_ro_rw_retain(self): 388adfe2030SMax Reitz os.chmod(old_img, 0444) 389adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') 390adfe2030SMax Reitz self.vm.launch() 391adfe2030SMax Reitz 392adfe2030SMax Reitz result = self.vm.qmp('query-block') 393adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 394adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 395adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 396adfe2030SMax Reitz 397adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 398adfe2030SMax Reitz filename=new_img, 399adfe2030SMax Reitz format=iotests.imgfmt, 400adfe2030SMax Reitz read_only_mode='retain') 401adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 402adfe2030SMax Reitz 403adfe2030SMax Reitz self.wait_for_open() 404adfe2030SMax Reitz self.wait_for_close() 405adfe2030SMax Reitz 406adfe2030SMax Reitz result = self.vm.qmp('query-block') 407adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 408adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 409adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 410adfe2030SMax Reitz 411adfe2030SMax Reitz def test_rw_ro_retain(self): 412adfe2030SMax Reitz os.chmod(new_img, 0444) 413adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk', 'floppy') 414adfe2030SMax Reitz self.vm.launch() 415adfe2030SMax Reitz 416adfe2030SMax Reitz result = self.vm.qmp('query-block') 417adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 418adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 419adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 420adfe2030SMax Reitz 421adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 422adfe2030SMax Reitz filename=new_img, 423adfe2030SMax Reitz format=iotests.imgfmt, 424adfe2030SMax Reitz read_only_mode='retain') 425adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 426adfe2030SMax Reitz 427adfe2030SMax Reitz self.assertEquals(self.vm.get_qmp_events(wait=False), []) 428adfe2030SMax Reitz 429adfe2030SMax Reitz result = self.vm.qmp('query-block') 430adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 431adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 432adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 433adfe2030SMax Reitz 434adfe2030SMax Reitz def test_ro_rw(self): 435adfe2030SMax Reitz os.chmod(old_img, 0444) 436adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') 437adfe2030SMax Reitz self.vm.launch() 438adfe2030SMax Reitz 439adfe2030SMax Reitz result = self.vm.qmp('query-block') 440adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 441adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 442adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 443adfe2030SMax Reitz 444adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 445adfe2030SMax Reitz device='drive0', 446adfe2030SMax Reitz filename=new_img, 447adfe2030SMax Reitz format=iotests.imgfmt, 448adfe2030SMax Reitz read_only_mode='read-write') 449adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 450adfe2030SMax Reitz 451adfe2030SMax Reitz self.wait_for_open() 452adfe2030SMax Reitz self.wait_for_close() 453adfe2030SMax Reitz 454adfe2030SMax Reitz result = self.vm.qmp('query-block') 455adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 456adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 457adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 458adfe2030SMax Reitz 459adfe2030SMax Reitz def test_rw_ro(self): 460adfe2030SMax Reitz os.chmod(new_img, 0444) 461adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk', 'floppy') 462adfe2030SMax Reitz self.vm.launch() 463adfe2030SMax Reitz 464adfe2030SMax Reitz result = self.vm.qmp('query-block') 465adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 466adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 467adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 468adfe2030SMax Reitz 469adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 470adfe2030SMax Reitz device='drive0', 471adfe2030SMax Reitz filename=new_img, 472adfe2030SMax Reitz format=iotests.imgfmt, 473adfe2030SMax Reitz read_only_mode='read-only') 474adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 475adfe2030SMax Reitz 476adfe2030SMax Reitz self.wait_for_open() 477adfe2030SMax Reitz self.wait_for_close() 478adfe2030SMax Reitz 479adfe2030SMax Reitz result = self.vm.qmp('query-block') 480adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 481adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 482adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 483adfe2030SMax Reitz 484adfe2030SMax Reitz def test_make_rw_ro(self): 485adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk', 'floppy') 486adfe2030SMax Reitz self.vm.launch() 487adfe2030SMax Reitz 488adfe2030SMax Reitz result = self.vm.qmp('query-block') 489adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 490adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 491adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 492adfe2030SMax Reitz 493adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 494adfe2030SMax Reitz device='drive0', 495adfe2030SMax Reitz filename=new_img, 496adfe2030SMax Reitz format=iotests.imgfmt, 497adfe2030SMax Reitz read_only_mode='read-only') 498adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 499adfe2030SMax Reitz 500adfe2030SMax Reitz self.wait_for_open() 501adfe2030SMax Reitz self.wait_for_close() 502adfe2030SMax Reitz 503adfe2030SMax Reitz result = self.vm.qmp('query-block') 504adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 505adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 506adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 507adfe2030SMax Reitz 508adfe2030SMax Reitz def test_make_ro_rw(self): 509adfe2030SMax Reitz os.chmod(new_img, 0444) 510adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk', 'floppy') 511adfe2030SMax Reitz self.vm.launch() 512adfe2030SMax Reitz 513adfe2030SMax Reitz result = self.vm.qmp('query-block') 514adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 515adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 516adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 517adfe2030SMax Reitz 518adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', 519adfe2030SMax Reitz device='drive0', 520adfe2030SMax Reitz filename=new_img, 521adfe2030SMax Reitz format=iotests.imgfmt, 522adfe2030SMax Reitz read_only_mode='read-write') 523adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 524adfe2030SMax Reitz 525adfe2030SMax Reitz self.assertEquals(self.vm.get_qmp_events(wait=False), []) 526adfe2030SMax Reitz 527adfe2030SMax Reitz result = self.vm.qmp('query-block') 528adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 529adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 530adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 531adfe2030SMax Reitz 532adfe2030SMax Reitz def test_make_rw_ro_by_retain(self): 533adfe2030SMax Reitz os.chmod(old_img, 0444) 534adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy') 535adfe2030SMax Reitz self.vm.launch() 536adfe2030SMax Reitz 537adfe2030SMax Reitz result = self.vm.qmp('query-block') 538adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 539adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 540adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 541adfe2030SMax Reitz 542adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 543adfe2030SMax Reitz filename=new_img, 544adfe2030SMax Reitz format=iotests.imgfmt, 545adfe2030SMax Reitz read_only_mode='retain') 546adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 547adfe2030SMax Reitz 548adfe2030SMax Reitz self.wait_for_open() 549adfe2030SMax Reitz self.wait_for_close() 550adfe2030SMax Reitz 551adfe2030SMax Reitz result = self.vm.qmp('query-block') 552adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 553adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 554adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 555adfe2030SMax Reitz 556adfe2030SMax Reitz def test_make_ro_rw_by_retain(self): 557adfe2030SMax Reitz os.chmod(new_img, 0444) 558adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk', 'floppy') 559adfe2030SMax Reitz self.vm.launch() 560adfe2030SMax Reitz 561adfe2030SMax Reitz result = self.vm.qmp('query-block') 562adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 563adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 564adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 565adfe2030SMax Reitz 566adfe2030SMax Reitz result = self.vm.qmp('blockdev-change-medium', device='drive0', 567adfe2030SMax Reitz filename=new_img, 568adfe2030SMax Reitz format=iotests.imgfmt, 569adfe2030SMax Reitz read_only_mode='retain') 570adfe2030SMax Reitz self.assert_qmp(result, 'error/class', 'GenericError') 571adfe2030SMax Reitz 572adfe2030SMax Reitz self.assertEquals(self.vm.get_qmp_events(wait=False), []) 573adfe2030SMax Reitz 574adfe2030SMax Reitz result = self.vm.qmp('query-block') 575adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 576adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 577adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 578adfe2030SMax Reitz 579adfe2030SMax Reitz def test_rw_ro_cycle(self): 580adfe2030SMax Reitz os.chmod(new_img, 0444) 581adfe2030SMax Reitz self.vm.add_drive(old_img, 'media=disk', 'floppy') 582adfe2030SMax Reitz self.vm.launch() 583adfe2030SMax Reitz 584adfe2030SMax Reitz result = self.vm.qmp('query-block') 585adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 586adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 587adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 588adfe2030SMax Reitz 589adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 590adfe2030SMax Reitz options={'node-name': 'new', 591adfe2030SMax Reitz 'driver': iotests.imgfmt, 592adfe2030SMax Reitz 'read-only': True, 593adfe2030SMax Reitz 'file': {'filename': new_img, 594adfe2030SMax Reitz 'driver': 'file'}}) 595adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 596adfe2030SMax Reitz 597adfe2030SMax Reitz result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True) 598adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 599adfe2030SMax Reitz 600adfe2030SMax Reitz self.wait_for_open() 601adfe2030SMax Reitz 602adfe2030SMax Reitz result = self.vm.qmp('query-block') 603adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 604adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', False) 605adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 606adfe2030SMax Reitz 607*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') 608adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 609adfe2030SMax Reitz 610adfe2030SMax Reitz result = self.vm.qmp('query-block') 611adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 612adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 613adfe2030SMax Reitz 614*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', 615adfe2030SMax Reitz node_name='new') 616adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 617adfe2030SMax Reitz 618adfe2030SMax Reitz result = self.vm.qmp('query-block') 619adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', True) 620adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 621adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 622adfe2030SMax Reitz 623adfe2030SMax Reitz result = self.vm.qmp('blockdev-close-tray', device='drive0') 624adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 625adfe2030SMax Reitz 626adfe2030SMax Reitz self.wait_for_close() 627adfe2030SMax Reitz 628adfe2030SMax Reitz result = self.vm.qmp('query-block') 629adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 630adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/ro', True) 631adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 632adfe2030SMax Reitz 633adfe2030SMax ReitzGeneralChangeTestsBaseClass = None 634adfe2030SMax ReitzTestInitiallyFilled = None 635adfe2030SMax ReitzTestInitiallyEmpty = None 636adfe2030SMax Reitz 637adfe2030SMax Reitz 638adfe2030SMax Reitzclass TestBlockJobsAfterCycle(ChangeBaseClass): 639adfe2030SMax Reitz def setUp(self): 640adfe2030SMax Reitz qemu_img('create', '-f', iotests.imgfmt, old_img, '1M') 641adfe2030SMax Reitz 642adfe2030SMax Reitz self.vm = iotests.VM() 643adfe2030SMax Reitz self.vm.launch() 644adfe2030SMax Reitz 645adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 646adfe2030SMax Reitz options={'id': 'drive0', 647adfe2030SMax Reitz 'driver': 'null-co'}) 648adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 649adfe2030SMax Reitz 650adfe2030SMax Reitz result = self.vm.qmp('query-block') 651adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 652adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co') 653adfe2030SMax Reitz 654adfe2030SMax Reitz # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray 655adfe2030SMax Reitz # is not necessary 656*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-remove-medium', device='drive0') 657adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 658adfe2030SMax Reitz 659adfe2030SMax Reitz result = self.vm.qmp('query-block') 660adfe2030SMax Reitz self.assert_qmp_absent(result, 'return[0]/inserted') 661adfe2030SMax Reitz 662adfe2030SMax Reitz result = self.vm.qmp('blockdev-add', 663adfe2030SMax Reitz options={'node-name': 'node0', 664adfe2030SMax Reitz 'driver': iotests.imgfmt, 665adfe2030SMax Reitz 'file': {'filename': old_img, 666adfe2030SMax Reitz 'driver': 'file'}}) 667adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 668adfe2030SMax Reitz 669*6e0abc25SMax Reitz result = self.vm.qmp('x-blockdev-insert-medium', device='drive0', 670adfe2030SMax Reitz node_name='node0') 671adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 672adfe2030SMax Reitz 673adfe2030SMax Reitz result = self.vm.qmp('query-block') 674adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/tray_open', False) 675adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) 676adfe2030SMax Reitz 677adfe2030SMax Reitz def tearDown(self): 678adfe2030SMax Reitz self.vm.shutdown() 679adfe2030SMax Reitz os.remove(old_img) 680adfe2030SMax Reitz try: 681adfe2030SMax Reitz os.remove(new_img) 682adfe2030SMax Reitz except OSError: 683adfe2030SMax Reitz pass 684adfe2030SMax Reitz 685adfe2030SMax Reitz def test_snapshot_and_commit(self): 686adfe2030SMax Reitz # We need backing file support 687adfe2030SMax Reitz if iotests.imgfmt != 'qcow2' and iotests.imgfmt != 'qed': 688adfe2030SMax Reitz return 689adfe2030SMax Reitz 690adfe2030SMax Reitz result = self.vm.qmp('blockdev-snapshot-sync', device='drive0', 691adfe2030SMax Reitz snapshot_file=new_img, 692adfe2030SMax Reitz format=iotests.imgfmt) 693adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 694adfe2030SMax Reitz 695adfe2030SMax Reitz result = self.vm.qmp('query-block') 696adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) 697adfe2030SMax Reitz self.assert_qmp(result, 698adfe2030SMax Reitz 'return[0]/inserted/image/backing-image/filename', 699adfe2030SMax Reitz old_img) 700adfe2030SMax Reitz 701adfe2030SMax Reitz result = self.vm.qmp('block-commit', device='drive0') 702adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 703adfe2030SMax Reitz 704adfe2030SMax Reitz self.vm.event_wait(name='BLOCK_JOB_READY') 705adfe2030SMax Reitz 706adfe2030SMax Reitz result = self.vm.qmp('query-block-jobs') 707adfe2030SMax Reitz self.assert_qmp(result, 'return[0]/device', 'drive0') 708adfe2030SMax Reitz 709adfe2030SMax Reitz result = self.vm.qmp('block-job-complete', device='drive0') 710adfe2030SMax Reitz self.assert_qmp(result, 'return', {}) 711adfe2030SMax Reitz 712adfe2030SMax Reitz self.vm.event_wait(name='BLOCK_JOB_COMPLETED') 713adfe2030SMax Reitz 714adfe2030SMax Reitz 715adfe2030SMax Reitzif __name__ == '__main__': 716adfe2030SMax Reitz if iotests.qemu_default_machine != 'pc': 717adfe2030SMax Reitz # We need floppy and IDE CD-ROM 718adfe2030SMax Reitz iotests.notrun('not suitable for this machine type: %s' % 719adfe2030SMax Reitz iotests.qemu_default_machine) 720adfe2030SMax Reitz iotests.main() 721