libqos: add MSI-X callbacks to QVirtioPCIDevice
[qemu/ar7.git] / tests / qemu-iotests / 118
blobea0b326ae033387db98e6b1f8e7737de31aa82ae
1 #!/usr/bin/env python
3 # Test case for the QMP 'change' command and all other associated
4 # commands
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/>.
22 import os
23 import stat
24 import time
25 import iotests
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':
33 return 'ide-cd'
34 elif interface == 'floppy':
35 return 'floppy'
36 elif interface == 'scsi':
37 return 'scsi-cd'
38 else:
39 return None
41 class ChangeBaseClass(iotests.QMPTestCase):
42 has_opened = False
43 has_closed = False
45 device_name = 'qdev0'
46 use_drive = False
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
58 def wait_for_open(self):
59 if not self.has_real_tray:
60 return
62 with iotests.Timeout(3, 'Timeout while waiting for the tray to open'):
63 while not self.has_opened:
64 self.process_events()
66 def wait_for_close(self):
67 if not self.has_real_tray:
68 return
70 with iotests.Timeout(3, 'Timeout while waiting for the tray to close'):
71 while not self.has_closed:
72 self.process_events()
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:
79 return
81 result = self.vm.qmp('change', device='drive0', target=new_img,
82 arg=iotests.imgfmt)
83 self.assert_qmp(result, 'return', {})
85 self.wait_for_open()
86 self.wait_for_close()
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', {})
100 self.wait_for_open()
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', {})
112 self.wait_for_open()
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', {})
123 self.wait_for_open()
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', {})
146 self.wait_for_open()
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')
153 else:
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')
167 else:
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', {})
174 self.wait_for_open()
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,
193 force=True)
194 self.assert_qmp(result, 'return', {})
196 self.wait_for_open()
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')
203 else:
204 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
206 result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
207 filename=new_img,
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',
220 node_name='new',
221 driver=iotests.imgfmt,
222 read_only=read_only_node,
223 file={'filename': new_img,
224 'driver': 'file'})
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', {})
231 self.wait_for_open()
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')
238 else:
239 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
241 result = self.vm.qmp('blockdev-remove-medium',
242 id=self.device_name)
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)
274 # Should be a no-op
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:
280 return
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:
287 return
289 result = self.vm.qmp('blockdev-add',
290 node_name='new',
291 driver=iotests.imgfmt,
292 file={'filename': new_img,
293 'driver': 'file'})
294 self.assert_qmp(result, 'return', {})
296 result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
297 node_name='new')
298 self.assert_qmp(result, 'error/class', 'GenericError')
300 class TestInitiallyFilled(GeneralChangeTestsBaseClass):
301 was_empty = False
303 def setUp(self):
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()
307 if self.use_drive:
308 self.vm.add_drive(old_img, 'media=%s' % self.media, 'none')
309 else:
310 self.vm.add_blockdev([ 'node-name=drive0',
311 'driver=%s' % iotests.imgfmt,
312 'file.driver=file',
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),
318 self.device_name))
319 self.vm.launch()
321 def tearDown(self):
322 self.vm.shutdown()
323 os.remove(old_img)
324 os.remove(new_img)
326 def test_insert_on_filled(self):
327 result = self.vm.qmp('blockdev-add',
328 node_name='new',
329 driver=iotests.imgfmt,
330 file={'filename': new_img,
331 'driver': 'file'})
332 self.assert_qmp(result, 'return', {})
334 result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
335 self.assert_qmp(result, 'return', {})
337 self.wait_for_open()
339 result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
340 node_name='new')
341 self.assert_qmp(result, 'error/class', 'GenericError')
343 class TestInitiallyEmpty(GeneralChangeTestsBaseClass):
344 was_empty = True
346 def setUp(self):
347 qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
348 self.vm = iotests.VM()
349 if self.use_drive:
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 '',
356 self.device_name))
357 self.vm.launch()
359 def tearDown(self):
360 self.vm.shutdown()
361 os.remove(new_img)
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', {})
367 self.wait_for_open()
369 result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
370 # Should be a no-op
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'
396 def setUp(self):
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()
401 def tearDown(self):
402 self.vm.shutdown()
403 os.chmod(old_img, 0o666)
404 os.chmod(new_img, 0o666)
405 os.remove(old_img)
406 os.remove(new_img)
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)
413 self.vm.launch()
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,
420 filename=new_img,
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)
433 self.vm.launch()
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,
440 filename=new_img,
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)
453 self.vm.launch()
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,
460 filename=new_img,
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)
475 self.vm.launch()
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',
482 id=self.device_name,
483 filename=new_img,
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)
496 self.vm.launch()
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',
503 id=self.device_name,
504 filename=new_img,
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)
516 self.vm.launch()
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',
523 id=self.device_name,
524 filename=new_img,
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)
537 self.vm.launch()
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',
544 id=self.device_name,
545 filename=new_img,
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)
558 self.vm.launch()
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,
565 filename=new_img,
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)
578 self.vm.launch()
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,
585 filename=new_img,
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)
598 self.vm.launch()
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',
605 node_name='new',
606 driver=iotests.imgfmt,
607 read_only=True,
608 file={'filename': new_img,
609 'driver': 'file'})
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,
623 node_name='new')
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'
642 def setUp(self):
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)
648 self.vm.launch()
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
654 # is not necessary
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',
662 node_name='node0',
663 driver=iotests.imgfmt,
664 file={'filename': old_img,
665 'driver': 'file'})
666 self.assert_qmp(result, 'return', {})
668 result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
669 node_name='node0')
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)
675 def tearDown(self):
676 self.vm.shutdown()
677 os.remove(old_img)
678 try:
679 os.remove(new_img)
680 except OSError:
681 pass
683 def test_snapshot_and_commit(self):
684 # We need backing file support
685 if iotests.imgfmt != 'qcow2' and iotests.imgfmt != 'qed':
686 return
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',
697 old_img)
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'])