Merge remote-tracking branch 'remotes/nvme/tags/nvme-fixes-20210407-pull-request...
[qemu/ar7.git] / tests / qemu-iotests / 118
blobcae52ffa5eabb07b2c717097ea63a7c6eaa0eea4
1 #!/usr/bin/env python3
2 # group: rw
4 # Test case for media change monitor 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_blockdev_change_medium(self):
77         result = self.vm.qmp('blockdev-change-medium',
78                              id=self.device_name, filename=new_img,
79                              format=iotests.imgfmt)
81         self.assert_qmp(result, 'return', {})
83         self.wait_for_open()
84         self.wait_for_close()
86         result = self.vm.qmp('query-block')
87         if self.has_real_tray:
88             self.assert_qmp(result, 'return[0]/tray_open', False)
89         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
91     def test_eject(self):
92         result = self.vm.qmp('eject', id=self.device_name, force=True)
93         self.assert_qmp(result, 'return', {})
95         self.wait_for_open()
97         result = self.vm.qmp('query-block')
98         if self.has_real_tray:
99             self.assert_qmp(result, 'return[0]/tray_open', True)
100         self.assert_qmp_absent(result, 'return[0]/inserted')
102     def test_tray_eject_change(self):
103         result = self.vm.qmp('eject', id=self.device_name, force=True)
104         self.assert_qmp(result, 'return', {})
106         self.wait_for_open()
108         result = self.vm.qmp('query-block')
109         if self.has_real_tray:
110             self.assert_qmp(result, 'return[0]/tray_open', True)
111         self.assert_qmp_absent(result, 'return[0]/inserted')
113         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
114                              filename=new_img, format=iotests.imgfmt)
115         self.assert_qmp(result, 'return', {})
117         self.wait_for_close()
119         result = self.vm.qmp('query-block')
120         if self.has_real_tray:
121             self.assert_qmp(result, 'return[0]/tray_open', False)
122         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
124     def test_tray_open_close(self):
125         result = self.vm.qmp('blockdev-open-tray',
126                              id=self.device_name, force=True)
127         self.assert_qmp(result, 'return', {})
129         self.wait_for_open()
131         result = self.vm.qmp('query-block')
132         if self.has_real_tray:
133             self.assert_qmp(result, 'return[0]/tray_open', True)
134         if self.was_empty == True:
135             self.assert_qmp_absent(result, 'return[0]/inserted')
136         else:
137             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
139         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
140         self.assert_qmp(result, 'return', {})
142         if self.has_real_tray or not self.was_empty:
143             self.wait_for_close()
145         result = self.vm.qmp('query-block')
146         if self.has_real_tray:
147             self.assert_qmp(result, 'return[0]/tray_open', False)
148         if self.was_empty == True:
149             self.assert_qmp_absent(result, 'return[0]/inserted')
150         else:
151             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
153     def test_tray_eject_close(self):
154         result = self.vm.qmp('eject', id=self.device_name, force=True)
155         self.assert_qmp(result, 'return', {})
157         self.wait_for_open()
159         result = self.vm.qmp('query-block')
160         if self.has_real_tray:
161             self.assert_qmp(result, 'return[0]/tray_open', True)
162         self.assert_qmp_absent(result, 'return[0]/inserted')
164         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
165         self.assert_qmp(result, 'return', {})
167         self.wait_for_close()
169         result = self.vm.qmp('query-block')
170         if self.has_real_tray:
171             self.assert_qmp(result, 'return[0]/tray_open', False)
172         self.assert_qmp_absent(result, 'return[0]/inserted')
174     def test_tray_open_change(self):
175         result = self.vm.qmp('blockdev-open-tray', id=self.device_name,
176                                                    force=True)
177         self.assert_qmp(result, 'return', {})
179         self.wait_for_open()
181         result = self.vm.qmp('query-block')
182         if self.has_real_tray:
183             self.assert_qmp(result, 'return[0]/tray_open', True)
184         if self.was_empty == True:
185             self.assert_qmp_absent(result, 'return[0]/inserted')
186         else:
187             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
189         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
190                                                        filename=new_img,
191                                                        format=iotests.imgfmt)
192         self.assert_qmp(result, 'return', {})
194         self.wait_for_close()
196         result = self.vm.qmp('query-block')
197         if self.has_real_tray:
198             self.assert_qmp(result, 'return[0]/tray_open', False)
199         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
201     def test_cycle(self, read_only_node=False):
202         result = self.vm.qmp('blockdev-add',
203                              node_name='new',
204                              driver=iotests.imgfmt,
205                              read_only=read_only_node,
206                              file={'filename': new_img,
207                                     'driver': 'file'})
208         self.assert_qmp(result, 'return', {})
210         result = self.vm.qmp('blockdev-open-tray',
211                              id=self.device_name, force=True)
212         self.assert_qmp(result, 'return', {})
214         self.wait_for_open()
216         result = self.vm.qmp('query-block')
217         if self.has_real_tray:
218             self.assert_qmp(result, 'return[0]/tray_open', True)
219         if self.was_empty == True:
220             self.assert_qmp_absent(result, 'return[0]/inserted')
221         else:
222             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
224         result = self.vm.qmp('blockdev-remove-medium',
225                              id=self.device_name)
226         self.assert_qmp(result, 'return', {})
228         result = self.vm.qmp('query-block')
229         if self.has_real_tray:
230             self.assert_qmp(result, 'return[0]/tray_open', True)
231         self.assert_qmp_absent(result, 'return[0]/inserted')
233         result = self.vm.qmp('blockdev-insert-medium',
234                              id=self.device_name, node_name='new')
235         self.assert_qmp(result, 'return', {})
237         result = self.vm.qmp('query-block')
238         if self.has_real_tray:
239             self.assert_qmp(result, 'return[0]/tray_open', True)
240         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
242         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
243         self.assert_qmp(result, 'return', {})
245         self.wait_for_close()
247         result = self.vm.qmp('query-block')
248         if self.has_real_tray:
249             self.assert_qmp(result, 'return[0]/tray_open', False)
250         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
252     def test_cycle_read_only_media(self):
253         self.test_cycle(True)
255     def test_close_on_closed(self):
256         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
257         # Should be a no-op
258         self.assert_qmp(result, 'return', {})
259         self.assertEqual(self.vm.get_qmp_events(wait=False), [])
261     def test_remove_on_closed(self):
262         if not self.has_real_tray:
263             return
265         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
266         self.assert_qmp(result, 'error/class', 'GenericError')
268     def test_insert_on_closed(self):
269         if not self.has_real_tray:
270             return
272         result = self.vm.qmp('blockdev-add',
273                              node_name='new',
274                              driver=iotests.imgfmt,
275                              file={'filename': new_img,
276                                    'driver': 'file'})
277         self.assert_qmp(result, 'return', {})
279         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
280                                                        node_name='new')
281         self.assert_qmp(result, 'error/class', 'GenericError')
283 class TestInitiallyFilled(GeneralChangeTestsBaseClass):
284     was_empty = False
286     def setUp(self):
287         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
288         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
289         self.vm = iotests.VM()
290         if self.use_drive:
291             self.vm.add_drive(old_img, 'media=%s' % self.media, 'none')
292         else:
293             self.vm.add_blockdev([ 'node-name=drive0',
294                                    'driver=%s' % iotests.imgfmt,
295                                    'file.driver=file',
296                                    'file.filename=%s' % old_img ])
297         if self.interface == 'scsi':
298             self.vm.add_device('virtio-scsi-pci')
299         self.vm.add_device('%s,drive=drive0,id=%s' %
300                            (interface_to_device_name(self.interface),
301                             self.device_name))
302         self.vm.launch()
304     def tearDown(self):
305         self.vm.shutdown()
306         os.remove(old_img)
307         os.remove(new_img)
309     def test_insert_on_filled(self):
310         result = self.vm.qmp('blockdev-add',
311                              node_name='new',
312                              driver=iotests.imgfmt,
313                              file={'filename': new_img,
314                                    'driver': 'file'})
315         self.assert_qmp(result, 'return', {})
317         result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
318         self.assert_qmp(result, 'return', {})
320         self.wait_for_open()
322         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
323                                                        node_name='new')
324         self.assert_qmp(result, 'error/class', 'GenericError')
326 class TestInitiallyEmpty(GeneralChangeTestsBaseClass):
327     was_empty = True
329     def setUp(self):
330         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
331         self.vm = iotests.VM()
332         if self.use_drive:
333             self.vm.add_drive(None, 'media=%s' % self.media, 'none')
334         if self.interface == 'scsi':
335             self.vm.add_device('virtio-scsi-pci')
336         self.vm.add_device('%s,%sid=%s' %
337                            (interface_to_device_name(self.interface),
338                             'drive=drive0,' if self.use_drive else '',
339                             self.device_name))
340         self.vm.launch()
342     def tearDown(self):
343         self.vm.shutdown()
344         os.remove(new_img)
346     def test_remove_on_empty(self):
347         result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
348         self.assert_qmp(result, 'return', {})
350         self.wait_for_open()
352         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
353         # Should be a no-op
354         self.assert_qmp(result, 'return', {})
356 # Do this in a function to avoid leaking variables like case into the global
357 # name space (otherwise tests would be run for the abstract base classes)
358 def create_basic_test_classes():
359     for (media, interface, has_real_tray) in [ ('cdrom', 'ide', True),
360                                                ('cdrom', 'scsi', True),
361                                                ('disk', 'floppy', False) ]:
363         for case in [ TestInitiallyFilled, TestInitiallyEmpty ]:
364             for use_drive in [ True, False ]:
365                 attr = { 'media': media,
366                          'interface': interface,
367                          'has_real_tray': has_real_tray,
368                          'use_drive': use_drive }
370                 name = '%s_%s_%s_%s' % (case.__name__, media, interface,
371                                         'drive' if use_drive else 'blockdev')
372                 globals()[name] = type(name, (case, ), attr)
374 create_basic_test_classes()
376 class TestChangeReadOnly(ChangeBaseClass):
377     device_name = 'qdev0'
379     def setUp(self):
380         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
381         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
382         self.vm = iotests.VM()
384     def tearDown(self):
385         self.vm.shutdown()
386         os.chmod(old_img, 0o666)
387         os.chmod(new_img, 0o666)
388         os.remove(old_img)
389         os.remove(new_img)
391     def test_ro_ro_retain(self):
392         os.chmod(old_img, 0o444)
393         os.chmod(new_img, 0o444)
394         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
395         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
396         self.vm.launch()
398         result = self.vm.qmp('query-block')
399         self.assert_qmp(result, 'return[0]/inserted/ro', True)
400         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
402         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
403                                                        filename=new_img,
404                                                        format=iotests.imgfmt,
405                                                        read_only_mode='retain')
406         self.assert_qmp(result, 'return', {})
408         result = self.vm.qmp('query-block')
409         self.assert_qmp(result, 'return[0]/inserted/ro', True)
410         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
412     def test_ro_rw_retain(self):
413         os.chmod(old_img, 0o444)
414         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
415         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
416         self.vm.launch()
418         result = self.vm.qmp('query-block')
419         self.assert_qmp(result, 'return[0]/inserted/ro', True)
420         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
422         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
423                                                        filename=new_img,
424                                                        format=iotests.imgfmt,
425                                                        read_only_mode='retain')
426         self.assert_qmp(result, 'return', {})
428         result = self.vm.qmp('query-block')
429         self.assert_qmp(result, 'return[0]/inserted/ro', True)
430         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
432     @iotests.skip_if_user_is_root
433     def test_rw_ro_retain(self):
434         os.chmod(new_img, 0o444)
435         self.vm.add_drive(old_img, 'media=disk', 'none')
436         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
437         self.vm.launch()
439         result = self.vm.qmp('query-block')
440         self.assert_qmp(result, 'return[0]/inserted/ro', False)
441         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
443         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
444                                                        filename=new_img,
445                                                        format=iotests.imgfmt,
446                                                        read_only_mode='retain')
447         self.assert_qmp(result, 'error/class', 'GenericError')
449         self.assertEqual(self.vm.get_qmp_events(wait=False), [])
451         result = self.vm.qmp('query-block')
452         self.assert_qmp(result, 'return[0]/inserted/ro', False)
453         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
455     def test_ro_rw(self):
456         os.chmod(old_img, 0o444)
457         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
458         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
459         self.vm.launch()
461         result = self.vm.qmp('query-block')
462         self.assert_qmp(result, 'return[0]/inserted/ro', True)
463         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
465         result = self.vm.qmp('blockdev-change-medium',
466                              id=self.device_name,
467                              filename=new_img,
468                              format=iotests.imgfmt,
469                              read_only_mode='read-write')
470         self.assert_qmp(result, 'return', {})
472         result = self.vm.qmp('query-block')
473         self.assert_qmp(result, 'return[0]/inserted/ro', False)
474         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
476     def test_rw_ro(self):
477         os.chmod(new_img, 0o444)
478         self.vm.add_drive(old_img, 'media=disk', 'none')
479         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
480         self.vm.launch()
482         result = self.vm.qmp('query-block')
483         self.assert_qmp(result, 'return[0]/inserted/ro', False)
484         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
486         result = self.vm.qmp('blockdev-change-medium',
487                              id=self.device_name,
488                              filename=new_img,
489                              format=iotests.imgfmt,
490                              read_only_mode='read-only')
491         self.assert_qmp(result, 'return', {})
493         result = self.vm.qmp('query-block')
494         self.assert_qmp(result, 'return[0]/inserted/ro', True)
495         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
497     def test_make_rw_ro(self):
498         self.vm.add_drive(old_img, 'media=disk', 'none')
499         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
500         self.vm.launch()
502         result = self.vm.qmp('query-block')
503         self.assert_qmp(result, 'return[0]/inserted/ro', False)
504         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
506         result = self.vm.qmp('blockdev-change-medium',
507                              id=self.device_name,
508                              filename=new_img,
509                              format=iotests.imgfmt,
510                              read_only_mode='read-only')
511         self.assert_qmp(result, 'return', {})
513         result = self.vm.qmp('query-block')
514         self.assert_qmp(result, 'return[0]/inserted/ro', True)
515         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
517     @iotests.skip_if_user_is_root
518     def test_make_ro_rw(self):
519         os.chmod(new_img, 0o444)
520         self.vm.add_drive(old_img, 'media=disk', 'none')
521         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
522         self.vm.launch()
524         result = self.vm.qmp('query-block')
525         self.assert_qmp(result, 'return[0]/inserted/ro', False)
526         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
528         result = self.vm.qmp('blockdev-change-medium',
529                              id=self.device_name,
530                              filename=new_img,
531                              format=iotests.imgfmt,
532                              read_only_mode='read-write')
533         self.assert_qmp(result, 'error/class', 'GenericError')
535         result = self.vm.qmp('query-block')
536         self.assert_qmp(result, 'return[0]/inserted/ro', False)
537         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
539     def test_make_rw_ro_by_retain(self):
540         os.chmod(old_img, 0o444)
541         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
542         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
543         self.vm.launch()
545         result = self.vm.qmp('query-block')
546         self.assert_qmp(result, 'return[0]/inserted/ro', True)
547         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
549         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
550                                                        filename=new_img,
551                                                        format=iotests.imgfmt,
552                                                        read_only_mode='retain')
553         self.assert_qmp(result, 'return', {})
555         result = self.vm.qmp('query-block')
556         self.assert_qmp(result, 'return[0]/inserted/ro', True)
557         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
559     @iotests.skip_if_user_is_root
560     def test_make_ro_rw_by_retain(self):
561         os.chmod(new_img, 0o444)
562         self.vm.add_drive(old_img, 'media=disk', 'none')
563         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
564         self.vm.launch()
566         result = self.vm.qmp('query-block')
567         self.assert_qmp(result, 'return[0]/inserted/ro', False)
568         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
570         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
571                                                        filename=new_img,
572                                                        format=iotests.imgfmt,
573                                                        read_only_mode='retain')
574         self.assert_qmp(result, 'error/class', 'GenericError')
576         result = self.vm.qmp('query-block')
577         self.assert_qmp(result, 'return[0]/inserted/ro', False)
578         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
580     def test_rw_ro_cycle(self):
581         os.chmod(new_img, 0o444)
582         self.vm.add_drive(old_img, 'media=disk', 'none')
583         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
584         self.vm.launch()
586         result = self.vm.qmp('query-block')
587         self.assert_qmp(result, 'return[0]/inserted/ro', False)
588         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
590         result = self.vm.qmp('blockdev-add',
591                              node_name='new',
592                              driver=iotests.imgfmt,
593                              read_only=True,
594                              file={'filename': new_img,
595                                     'driver': 'file'})
596         self.assert_qmp(result, 'return', {})
598         result = self.vm.qmp('query-block')
599         self.assert_qmp(result, 'return[0]/inserted/ro', False)
600         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
602         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
603         self.assert_qmp(result, 'return', {})
605         result = self.vm.qmp('query-block')
606         self.assert_qmp_absent(result, 'return[0]/inserted')
608         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
609                                                        node_name='new')
610         self.assert_qmp(result, 'return', {})
612         result = self.vm.qmp('query-block')
613         self.assert_qmp(result, 'return[0]/inserted/ro', True)
614         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
616         result = self.vm.qmp('query-block')
617         self.assert_qmp(result, 'return[0]/inserted/ro', True)
618         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
620 GeneralChangeTestsBaseClass = None
621 TestInitiallyFilled = None
622 TestInitiallyEmpty = None
625 class TestBlockJobsAfterCycle(ChangeBaseClass):
626     device_name = 'qdev0'
628     def setUp(self):
629         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K')
631         self.vm = iotests.VM()
632         self.vm.add_drive_raw("id=drive0,driver=null-co,if=none")
633         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
634         self.vm.launch()
636         result = self.vm.qmp('query-block')
637         self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co')
639         # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
640         # is not necessary
641         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
642         self.assert_qmp(result, 'return', {})
644         result = self.vm.qmp('query-block')
645         self.assert_qmp_absent(result, 'return[0]/inserted')
647         result = self.vm.qmp('blockdev-add',
648                              node_name='node0',
649                              driver=iotests.imgfmt,
650                              file={'filename': old_img,
651                                    'driver': 'file'})
652         self.assert_qmp(result, 'return', {})
654         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
655                                                        node_name='node0')
656         self.assert_qmp(result, 'return', {})
658         result = self.vm.qmp('query-block')
659         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
661     def tearDown(self):
662         self.vm.shutdown()
663         os.remove(old_img)
664         try:
665             os.remove(new_img)
666         except OSError:
667             pass
669     # We need backing file support
670     @iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw',
671                                'vhdx'))
672     def test_snapshot_and_commit(self):
673         result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
674                                                        snapshot_file=new_img,
675                                                        format=iotests.imgfmt)
676         self.assert_qmp(result, 'return', {})
678         result = self.vm.qmp('query-block')
679         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
680         self.assert_qmp(result,
681                         'return[0]/inserted/image/backing-image/filename',
682                         old_img)
684         result = self.vm.qmp('block-commit', device='drive0')
685         self.assert_qmp(result, 'return', {})
687         self.vm.event_wait(name='BLOCK_JOB_READY')
689         result = self.vm.qmp('query-block-jobs')
690         self.assert_qmp(result, 'return[0]/device', 'drive0')
692         result = self.vm.qmp('block-job-complete', device='drive0')
693         self.assert_qmp(result, 'return', {})
695         self.vm.event_wait(name='BLOCK_JOB_COMPLETED')
698 if __name__ == '__main__':
699     if iotests.qemu_default_machine != 'pc':
700         # We need floppy and IDE CD-ROM
701         iotests.notrun('not suitable for this machine type: %s' %
702                        iotests.qemu_default_machine)
703     # Need to support image creation
704     iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
705                                  'vmdk', 'raw', 'vhdx', 'qed'],
706                  supported_protocols=['file'])