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 def test_rw_ro_retain(self
):
450 os
.chmod(new_img
, 0o444)
451 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
452 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
455 result
= self
.vm
.qmp('query-block')
456 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
457 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
459 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
461 format
=iotests
.imgfmt
,
462 read_only_mode
='retain')
463 self
.assert_qmp(result
, 'error/class', 'GenericError')
465 self
.assertEqual(self
.vm
.get_qmp_events(wait
=False), [])
467 result
= self
.vm
.qmp('query-block')
468 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
469 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
471 def test_ro_rw(self
):
472 os
.chmod(old_img
, 0o444)
473 self
.vm
.add_drive(old_img
, 'media=disk,read-only=on', 'none')
474 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
477 result
= self
.vm
.qmp('query-block')
478 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
479 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
481 result
= self
.vm
.qmp('blockdev-change-medium',
484 format
=iotests
.imgfmt
,
485 read_only_mode
='read-write')
486 self
.assert_qmp(result
, 'return', {})
488 result
= self
.vm
.qmp('query-block')
489 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
490 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
492 def test_rw_ro(self
):
493 os
.chmod(new_img
, 0o444)
494 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
495 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
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
)
502 result
= self
.vm
.qmp('blockdev-change-medium',
505 format
=iotests
.imgfmt
,
506 read_only_mode
='read-only')
507 self
.assert_qmp(result
, 'return', {})
509 result
= self
.vm
.qmp('query-block')
510 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
511 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
513 def test_make_rw_ro(self
):
514 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
515 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
518 result
= self
.vm
.qmp('query-block')
519 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
520 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
522 result
= self
.vm
.qmp('blockdev-change-medium',
525 format
=iotests
.imgfmt
,
526 read_only_mode
='read-only')
527 self
.assert_qmp(result
, 'return', {})
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
)
533 def test_make_ro_rw(self
):
534 os
.chmod(new_img
, 0o444)
535 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
536 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
539 result
= self
.vm
.qmp('query-block')
540 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
541 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
543 result
= self
.vm
.qmp('blockdev-change-medium',
546 format
=iotests
.imgfmt
,
547 read_only_mode
='read-write')
548 self
.assert_qmp(result
, 'error/class', 'GenericError')
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
)
554 def test_make_rw_ro_by_retain(self
):
555 os
.chmod(old_img
, 0o444)
556 self
.vm
.add_drive(old_img
, 'media=disk,read-only=on', 'none')
557 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
560 result
= self
.vm
.qmp('query-block')
561 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
562 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
564 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
566 format
=iotests
.imgfmt
,
567 read_only_mode
='retain')
568 self
.assert_qmp(result
, 'return', {})
570 result
= self
.vm
.qmp('query-block')
571 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
572 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
574 def test_make_ro_rw_by_retain(self
):
575 os
.chmod(new_img
, 0o444)
576 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
577 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
580 result
= self
.vm
.qmp('query-block')
581 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
582 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
584 result
= self
.vm
.qmp('blockdev-change-medium', id=self
.device_name
,
586 format
=iotests
.imgfmt
,
587 read_only_mode
='retain')
588 self
.assert_qmp(result
, 'error/class', 'GenericError')
590 result
= self
.vm
.qmp('query-block')
591 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
592 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
594 def test_rw_ro_cycle(self
):
595 os
.chmod(new_img
, 0o444)
596 self
.vm
.add_drive(old_img
, 'media=disk', 'none')
597 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
600 result
= self
.vm
.qmp('query-block')
601 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
602 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
604 result
= self
.vm
.qmp('blockdev-add',
606 driver
=iotests
.imgfmt
,
608 file={'filename': new_img
,
610 self
.assert_qmp(result
, 'return', {})
612 result
= self
.vm
.qmp('query-block')
613 self
.assert_qmp(result
, 'return[0]/inserted/ro', False)
614 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
616 result
= self
.vm
.qmp('blockdev-remove-medium', id=self
.device_name
)
617 self
.assert_qmp(result
, 'return', {})
619 result
= self
.vm
.qmp('query-block')
620 self
.assert_qmp_absent(result
, 'return[0]/inserted')
622 result
= self
.vm
.qmp('blockdev-insert-medium', id=self
.device_name
,
624 self
.assert_qmp(result
, 'return', {})
626 result
= self
.vm
.qmp('query-block')
627 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
628 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
630 result
= self
.vm
.qmp('query-block')
631 self
.assert_qmp(result
, 'return[0]/inserted/ro', True)
632 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
634 GeneralChangeTestsBaseClass
= None
635 TestInitiallyFilled
= None
636 TestInitiallyEmpty
= None
639 class TestBlockJobsAfterCycle(ChangeBaseClass
):
640 device_name
= 'qdev0'
643 qemu_img('create', '-f', iotests
.imgfmt
, old_img
, '1440K')
645 self
.vm
= iotests
.VM()
646 self
.vm
.add_drive_raw("id=drive0,driver=null-co,if=none")
647 self
.vm
.add_device('floppy,drive=drive0,id=%s' % self
.device_name
)
650 result
= self
.vm
.qmp('query-block')
651 self
.assert_qmp(result
, 'return[0]/inserted/image/format', 'null-co')
653 # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
655 result
= self
.vm
.qmp('blockdev-remove-medium', id=self
.device_name
)
656 self
.assert_qmp(result
, 'return', {})
658 result
= self
.vm
.qmp('query-block')
659 self
.assert_qmp_absent(result
, 'return[0]/inserted')
661 result
= self
.vm
.qmp('blockdev-add',
663 driver
=iotests
.imgfmt
,
664 file={'filename': old_img
,
666 self
.assert_qmp(result
, 'return', {})
668 result
= self
.vm
.qmp('blockdev-insert-medium', id=self
.device_name
,
670 self
.assert_qmp(result
, 'return', {})
672 result
= self
.vm
.qmp('query-block')
673 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', old_img
)
683 def test_snapshot_and_commit(self
):
684 # We need backing file support
685 if iotests
.imgfmt
!= 'qcow2' and iotests
.imgfmt
!= 'qed':
688 result
= self
.vm
.qmp('blockdev-snapshot-sync', device
='drive0',
689 snapshot_file
=new_img
,
690 format
=iotests
.imgfmt
)
691 self
.assert_qmp(result
, 'return', {})
693 result
= self
.vm
.qmp('query-block')
694 self
.assert_qmp(result
, 'return[0]/inserted/image/filename', new_img
)
695 self
.assert_qmp(result
,
696 'return[0]/inserted/image/backing-image/filename',
699 result
= self
.vm
.qmp('block-commit', device
='drive0')
700 self
.assert_qmp(result
, 'return', {})
702 self
.vm
.event_wait(name
='BLOCK_JOB_READY')
704 result
= self
.vm
.qmp('query-block-jobs')
705 self
.assert_qmp(result
, 'return[0]/device', 'drive0')
707 result
= self
.vm
.qmp('block-job-complete', device
='drive0')
708 self
.assert_qmp(result
, 'return', {})
710 self
.vm
.event_wait(name
='BLOCK_JOB_COMPLETED')
713 if __name__
== '__main__':
714 if iotests
.qemu_default_machine
!= 'pc':
715 # We need floppy and IDE CD-ROM
716 iotests
.notrun('not suitable for this machine type: %s' %
717 iotests
.qemu_default_machine
)
718 # Need to support image creation
719 iotests
.main(supported_fmts
=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
720 'vmdk', 'raw', 'vhdx', 'qed'],
721 supported_protocols
=['file'])