3 # Test case for the QMP 'change' command and all other associated
6 # Copyright (C) 2015 Red Hat, Inc.
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.
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.
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/>.
26 from iotests
import qemu_img
28 old_img
= os
.path
.join(iotests
.test_dir
, 'test0.img')
29 new_img
= os
.path
.join(iotests
.test_dir
, 'test1.img')
31 def interface_to_device_name(interface
):
32 if interface
== 'ide':
34 elif interface
== 'floppy':
36 elif interface
== 'scsi':
41 class ChangeBaseClass(iotests
.QMPTestCase
):
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
56 self
.has_opened
= True
58 def wait_for_open(self
):
59 if not self
.has_real_tray
:
62 with iotests
.Timeout(3, 'Timeout while waiting for the tray to open'):
63 while not self
.has_opened
:
66 def wait_for_close(self
):
67 if not self
.has_real_tray
:
70 with iotests
.Timeout(3, 'Timeout while waiting for the tray to close'):
71 while not self
.has_closed
:
74 class GeneralChangeTestsBaseClass(ChangeBaseClass
):
76 def test_change(self
):
77 # 'change' requires a drive name, so skip the test for blockdev
78 if not self
.use_drive
:
81 result
= self
.vm
.qmp('change', device
='drive0', target
=new_img
,
83 self
.assert_qmp(result
, 'return', {})
88 result
= self
.vm
.qmp('query-block')
89 if self
.has_real_tray
:
90 self
.assert_qmp(result
, 'return[0]/tray_open', False)
91 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
93 def test_blockdev_change_medium(self
):
94 result
= self
.vm
.qmp('blockdev-change-medium',
95 id=self
.device_name
, filename
=new_img
,
96 format
=iotests
.imgfmt
)
98 self
.assert_qmp(result
, 'return', {})
101 self
.wait_for_close()
103 result
= self
.vm
.qmp('query-block')
104 if self
.has_real_tray
:
105 self
.assert_qmp(result
, 'return[0]/tray_open', False)
106 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
108 def test_eject(self
):
109 result
= self
.vm
.qmp('eject', id=self
.device_name
, force
=True)
110 self
.assert_qmp(result
, 'return', {})
114 result
= self
.vm
.qmp('query-block')
115 if self
.has_real_tray
:
116 self
.assert_qmp(result
, 'return[0]/tray_open', True)
117 self
.assert_qmp_absent(result
, 'return[0]/inserted')
119 def test_tray_eject_change(self
):
120 result
= self
.vm
.qmp('eject', id=self
.device_name
, force
=True)
121 self
.assert_qmp(result
, 'return', {})
125 result
= self
.vm
.qmp('query-block')
126 if self
.has_real_tray
:
127 self
.assert_qmp(result
, 'return[0]/tray_open', True)
128 self
.assert_qmp_absent(result
, 'return[0]/inserted')
130 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
131 filename
=new_img
, format
=iotests
.imgfmt
)
132 self
.assert_qmp(result
, 'return', {})
134 self
.wait_for_close()
136 result
= self
.vm
.qmp('query-block')
137 if self
.has_real_tray
:
138 self
.assert_qmp(result
, 'return[0]/tray_open', False)
139 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
141 def test_tray_open_close(self
):
142 result
= self
.vm
.qmp('blockdev-open-tray',
143 id=self
.device_name
, force
=True)
144 self
.assert_qmp(result
, 'return', {})
148 result
= self
.vm
.qmp('query-block')
149 if self
.has_real_tray
:
150 self
.assert_qmp(result
, 'return[0]/tray_open', True)
151 if self
.was_empty
== True:
152 self
.assert_qmp_absent(result
, 'return[0]/inserted')
154 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
156 result
= self
.vm
.qmp('blockdev-close-tray', id=self
.device_name
)
157 self
.assert_qmp(result
, 'return', {})
159 if self
.has_real_tray
or not self
.was_empty
:
160 self
.wait_for_close()
162 result
= self
.vm
.qmp('query-block')
163 if self
.has_real_tray
:
164 self
.assert_qmp(result
, 'return[0]/tray_open', False)
165 if self
.was_empty
== True:
166 self
.assert_qmp_absent(result
, 'return[0]/inserted')
168 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
170 def test_tray_eject_close(self
):
171 result
= self
.vm
.qmp('eject', id=self
.device_name
, force
=True)
172 self
.assert_qmp(result
, 'return', {})
176 result
= self
.vm
.qmp('query-block')
177 if self
.has_real_tray
:
178 self
.assert_qmp(result
, 'return[0]/tray_open', True)
179 self
.assert_qmp_absent(result
, 'return[0]/inserted')
181 result
= self
.vm
.qmp('blockdev-close-tray', id=self
.device_name
)
182 self
.assert_qmp(result
, 'return', {})
184 self
.wait_for_close()
186 result
= self
.vm
.qmp('query-block')
187 if self
.has_real_tray
:
188 self
.assert_qmp(result
, 'return[0]/tray_open', False)
189 self
.assert_qmp_absent(result
, 'return[0]/inserted')
191 def test_tray_open_change(self
):
192 result
= self
.vm
.qmp('blockdev-open-tray', id=self
.device_name
,
194 self
.assert_qmp(result
, 'return', {})
198 result
= self
.vm
.qmp('query-block')
199 if self
.has_real_tray
:
200 self
.assert_qmp(result
, 'return[0]/tray_open', True)
201 if self
.was_empty
== True:
202 self
.assert_qmp_absent(result
, 'return[0]/inserted')
204 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
206 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
208 format
=iotests
.imgfmt
)
209 self
.assert_qmp(result
, 'return', {})
211 self
.wait_for_close()
213 result
= self
.vm
.qmp('query-block')
214 if self
.has_real_tray
:
215 self
.assert_qmp(result
, 'return[0]/tray_open', False)
216 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
218 def test_cycle(self
, read_only_node
=False):
219 result
= self
.vm
.qmp('blockdev-add',
221 driver
=iotests
.imgfmt
,
222 read_only
=read_only_node
,
223 file={'filename': new_img
,
225 self
.assert_qmp(result
, 'return', {})
227 result
= self
.vm
.qmp('blockdev-open-tray',
228 id=self
.device_name
, force
=True)
229 self
.assert_qmp(result
, 'return', {})
233 result
= self
.vm
.qmp('query-block')
234 if self
.has_real_tray
:
235 self
.assert_qmp(result
, 'return[0]/tray_open', True)
236 if self
.was_empty
== True:
237 self
.assert_qmp_absent(result
, 'return[0]/inserted')
239 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
241 result
= self
.vm
.qmp('blockdev-remove-medium',
243 self
.assert_qmp(result
, 'return', {})
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_absent(result
, 'return[0]/inserted')
250 result
= self
.vm
.qmp('blockdev-insert-medium',
251 id=self
.device_name
, node_name
='new')
252 self
.assert_qmp(result
, 'return', {})
254 result
= self
.vm
.qmp('query-block')
255 if self
.has_real_tray
:
256 self
.assert_qmp(result
, 'return[0]/tray_open', True)
257 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
259 result
= self
.vm
.qmp('blockdev-close-tray', id=self
.device_name
)
260 self
.assert_qmp(result
, 'return', {})
262 self
.wait_for_close()
264 result
= self
.vm
.qmp('query-block')
265 if self
.has_real_tray
:
266 self
.assert_qmp(result
, 'return[0]/tray_open', False)
267 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
269 def test_cycle_read_only_media(self
):
270 self
.test_cycle(True)
272 def test_close_on_closed(self
):
273 result
= self
.vm
.qmp('blockdev-close-tray', id=self
.device_name
)
275 self
.assert_qmp(result
, 'return', {})
276 self
.assertEqual(self
.vm
.get_qmp_events(wait
=False), [])
278 def test_remove_on_closed(self
):
279 if not self
.has_real_tray
:
282 result
= self
.vm
.qmp('blockdev-remove-medium', id=self
.device_name
)
283 self
.assert_qmp(result
, 'error/class', 'GenericError')
285 def test_insert_on_closed(self
):
286 if not self
.has_real_tray
:
289 result
= self
.vm
.qmp('blockdev-add',
291 driver
=iotests
.imgfmt
,
292 file={'filename': new_img
,
294 self
.assert_qmp(result
, 'return', {})
296 result
= self
.vm
.qmp('blockdev-insert-medium', id=self
.device_name
,
298 self
.assert_qmp(result
, 'error/class', 'GenericError')
300 class TestInitiallyFilled(GeneralChangeTestsBaseClass
):
304 qemu_img('create', '-f', iotests
.imgfmt
, old_img
, '1440k')
305 qemu_img('create', '-f', iotests
.imgfmt
, new_img
, '1440k')
306 self
.vm
= iotests
.VM()
308 self
.vm
.add_drive(old_img
, 'media=%s' % self
.media
, 'none')
310 self
.vm
.add_blockdev([ 'node-name=drive0',
311 'driver=%s' % iotests
.imgfmt
,
313 'file.filename=%s' % old_img
])
314 if self
.interface
== 'scsi':
315 self
.vm
.add_device('virtio-scsi-pci')
316 self
.vm
.add_device('%s,drive=drive0,id=%s' %
317 (interface_to_device_name(self
.interface
),
326 def test_insert_on_filled(self
):
327 result
= self
.vm
.qmp('blockdev-add',
329 driver
=iotests
.imgfmt
,
330 file={'filename': new_img
,
332 self
.assert_qmp(result
, 'return', {})
334 result
= self
.vm
.qmp('blockdev-open-tray', id=self
.device_name
)
335 self
.assert_qmp(result
, 'return', {})
339 result
= self
.vm
.qmp('blockdev-insert-medium', id=self
.device_name
,
341 self
.assert_qmp(result
, 'error/class', 'GenericError')
343 class TestInitiallyEmpty(GeneralChangeTestsBaseClass
):
347 qemu_img('create', '-f', iotests
.imgfmt
, new_img
, '1440k')
348 self
.vm
= iotests
.VM()
350 self
.vm
.add_drive(None, 'media=%s' % self
.media
, 'none')
351 if self
.interface
== 'scsi':
352 self
.vm
.add_device('virtio-scsi-pci')
353 self
.vm
.add_device('%s,%sid=%s' %
354 (interface_to_device_name(self
.interface
),
355 'drive=drive0,' if self
.use_drive
else '',
363 def test_remove_on_empty(self
):
364 result
= self
.vm
.qmp('blockdev-open-tray', id=self
.device_name
)
365 self
.assert_qmp(result
, 'return', {})
369 result
= self
.vm
.qmp('blockdev-remove-medium', id=self
.device_name
)
371 self
.assert_qmp(result
, 'return', {})
373 # Do this in a function to avoid leaking variables like case into the global
374 # name space (otherwise tests would be run for the abstract base classes)
375 def create_basic_test_classes():
376 for (media
, interface
, has_real_tray
) in [ ('cdrom', 'ide', True),
377 ('cdrom', 'scsi', True),
378 ('disk', 'floppy', False) ]:
380 for case
in [ TestInitiallyFilled
, TestInitiallyEmpty
]:
381 for use_drive
in [ True, False ]:
382 attr
= { 'media': media
,
383 'interface': interface
,
384 'has_real_tray': has_real_tray
,
385 'use_drive': use_drive
}
387 name
= '%s_%s_%s_%s' % (case
.__name
__, media
, interface
,
388 'drive' if use_drive
else 'blockdev')
389 globals()[name
] = type(name
, (case
, ), attr
)
391 create_basic_test_classes()
393 class TestChangeReadOnly(ChangeBaseClass
):
394 device_name
= 'qdev0'
397 qemu_img('create', '-f', iotests
.imgfmt
, old_img
, '1440k')
398 qemu_img('create', '-f', iotests
.imgfmt
, new_img
, '1440k')
399 self
.vm
= iotests
.VM()
403 os
.chmod(old_img
, 0o666)
404 os
.chmod(new_img
, 0o666)
408 def test_ro_ro_retain(self
):
409 os
.chmod(old_img
, 0o444)
410 os
.chmod(new_img
, 0o444)
411 self
.vm
.add_drive(old_img
, 'media=disk,read-only=on', 'none')
412 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
415 result
= self
.vm
.qmp('query-block')
416 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
417 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
419 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
421 format
=iotests
.imgfmt
,
422 read_only_mode
='retain')
423 self
.assert_qmp(result
, 'return', {})
425 result
= self
.vm
.qmp('query-block')
426 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
427 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
429 def test_ro_rw_retain(self
):
430 os
.chmod(old_img
, 0o444)
431 self
.vm
.add_drive(old_img
, 'media=disk,read-only=on', 'none')
432 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
435 result
= self
.vm
.qmp('query-block')
436 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
437 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
439 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
441 format
=iotests
.imgfmt
,
442 read_only_mode
='retain')
443 self
.assert_qmp(result
, 'return', {})
445 result
= self
.vm
.qmp('query-block')
446 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
447 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
449 @iotests.skip_if_user_is_root
450 def test_rw_ro_retain(self
):
451 os
.chmod(new_img
, 0o444)
452 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
453 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
456 result
= self
.vm
.qmp('query-block')
457 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
458 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
460 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
462 format
=iotests
.imgfmt
,
463 read_only_mode
='retain')
464 self
.assert_qmp(result
, 'error/class', 'GenericError')
466 self
.assertEqual(self
.vm
.get_qmp_events(wait
=False), [])
468 result
= self
.vm
.qmp('query-block')
469 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
470 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
472 def test_ro_rw(self
):
473 os
.chmod(old_img
, 0o444)
474 self
.vm
.add_drive(old_img
, 'media=disk,read-only=on', 'none')
475 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
478 result
= self
.vm
.qmp('query-block')
479 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
480 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
482 result
= self
.vm
.qmp('blockdev-change-medium',
485 format
=iotests
.imgfmt
,
486 read_only_mode
='read-write')
487 self
.assert_qmp(result
, 'return', {})
489 result
= self
.vm
.qmp('query-block')
490 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
491 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
493 def test_rw_ro(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
)
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
)
503 result
= self
.vm
.qmp('blockdev-change-medium',
506 format
=iotests
.imgfmt
,
507 read_only_mode
='read-only')
508 self
.assert_qmp(result
, 'return', {})
510 result
= self
.vm
.qmp('query-block')
511 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
512 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
514 def test_make_rw_ro(self
):
515 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
516 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
519 result
= self
.vm
.qmp('query-block')
520 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
521 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
523 result
= self
.vm
.qmp('blockdev-change-medium',
526 format
=iotests
.imgfmt
,
527 read_only_mode
='read-only')
528 self
.assert_qmp(result
, 'return', {})
530 result
= self
.vm
.qmp('query-block')
531 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
532 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
534 @iotests.skip_if_user_is_root
535 def test_make_ro_rw(self
):
536 os
.chmod(new_img
, 0o444)
537 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
538 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
541 result
= self
.vm
.qmp('query-block')
542 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
543 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
545 result
= self
.vm
.qmp('blockdev-change-medium',
548 format
=iotests
.imgfmt
,
549 read_only_mode
='read-write')
550 self
.assert_qmp(result
, 'error/class', 'GenericError')
552 result
= self
.vm
.qmp('query-block')
553 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
554 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
556 def test_make_rw_ro_by_retain(self
):
557 os
.chmod(old_img
, 0o444)
558 self
.vm
.add_drive(old_img
, 'media=disk,read-only=on', 'none')
559 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
562 result
= self
.vm
.qmp('query-block')
563 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
564 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
566 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
568 format
=iotests
.imgfmt
,
569 read_only_mode
='retain')
570 self
.assert_qmp(result
, 'return', {})
572 result
= self
.vm
.qmp('query-block')
573 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
574 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
576 @iotests.skip_if_user_is_root
577 def test_make_ro_rw_by_retain(self
):
578 os
.chmod(new_img
, 0o444)
579 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
580 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
583 result
= self
.vm
.qmp('query-block')
584 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
585 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
587 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
589 format
=iotests
.imgfmt
,
590 read_only_mode
='retain')
591 self
.assert_qmp(result
, 'error/class', 'GenericError')
593 result
= self
.vm
.qmp('query-block')
594 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
595 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
597 def test_rw_ro_cycle(self
):
598 os
.chmod(new_img
, 0o444)
599 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
600 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
603 result
= self
.vm
.qmp('query-block')
604 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
605 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
607 result
= self
.vm
.qmp('blockdev-add',
609 driver
=iotests
.imgfmt
,
611 file={'filename': new_img
,
613 self
.assert_qmp(result
, 'return', {})
615 result
= self
.vm
.qmp('query-block')
616 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
617 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
619 result
= self
.vm
.qmp('blockdev-remove-medium', id=self
.device_name
)
620 self
.assert_qmp(result
, 'return', {})
622 result
= self
.vm
.qmp('query-block')
623 self
.assert_qmp_absent(result
, 'return[0]/inserted')
625 result
= self
.vm
.qmp('blockdev-insert-medium', id=self
.device_name
,
627 self
.assert_qmp(result
, 'return', {})
629 result
= self
.vm
.qmp('query-block')
630 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
631 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
633 result
= self
.vm
.qmp('query-block')
634 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
635 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
637 GeneralChangeTestsBaseClass
= None
638 TestInitiallyFilled
= None
639 TestInitiallyEmpty
= None
642 class TestBlockJobsAfterCycle(ChangeBaseClass
):
643 device_name
= 'qdev0'
646 qemu_img('create', '-f', iotests
.imgfmt
, old_img
, '1440K')
648 self
.vm
= iotests
.VM()
649 self
.vm
.add_drive_raw("id=drive0,driver=null-co,if=none")
650 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
653 result
= self
.vm
.qmp('query-block')
654 self
.assert_qmp(result
, 'return[0]/inserted/image/format', 'null-co')
656 # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
658 result
= self
.vm
.qmp('blockdev-remove-medium', id=self
.device_name
)
659 self
.assert_qmp(result
, 'return', {})
661 result
= self
.vm
.qmp('query-block')
662 self
.assert_qmp_absent(result
, 'return[0]/inserted')
664 result
= self
.vm
.qmp('blockdev-add',
666 driver
=iotests
.imgfmt
,
667 file={'filename': old_img
,
669 self
.assert_qmp(result
, 'return', {})
671 result
= self
.vm
.qmp('blockdev-insert-medium', id=self
.device_name
,
673 self
.assert_qmp(result
, 'return', {})
675 result
= self
.vm
.qmp('query-block')
676 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
686 def test_snapshot_and_commit(self
):
687 # We need backing file support
688 if iotests
.imgfmt
!= 'qcow2' and iotests
.imgfmt
!= 'qed':
691 result
= self
.vm
.qmp('blockdev-snapshot-sync', device
='drive0',
692 snapshot_file
=new_img
,
693 format
=iotests
.imgfmt
)
694 self
.assert_qmp(result
, 'return', {})
696 result
= self
.vm
.qmp('query-block')
697 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
698 self
.assert_qmp(result
,
699 'return[0]/inserted/image/backing-image/filename',
702 result
= self
.vm
.qmp('block-commit', device
='drive0')
703 self
.assert_qmp(result
, 'return', {})
705 self
.vm
.event_wait(name
='BLOCK_JOB_READY')
707 result
= self
.vm
.qmp('query-block-jobs')
708 self
.assert_qmp(result
, 'return[0]/device', 'drive0')
710 result
= self
.vm
.qmp('block-job-complete', device
='drive0')
711 self
.assert_qmp(result
, 'return', {})
713 self
.vm
.event_wait(name
='BLOCK_JOB_COMPLETED')
716 if __name__
== '__main__':
717 if iotests
.qemu_default_machine
!= 'pc':
718 # We need floppy and IDE CD-ROM
719 iotests
.notrun('not suitable for this machine type: %s' %
720 iotests
.qemu_default_machine
)
721 # Need to support image creation
722 iotests
.main(supported_fmts
=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
723 'vmdk', 'raw', 'vhdx', 'qed'],
724 supported_protocols
=['file'])