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