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