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