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