python/qemu: make 'args' style arguments immutable
[qemu.git] / tests / qemu-iotests / 118
blob2350929fd833f4ec2b4640a7891c7cc7a8bd1876
1 #!/usr/bin/env python3
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     @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)
454         self.vm.launch()
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,
461                                                        filename=new_img,
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)
476         self.vm.launch()
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',
483                              id=self.device_name,
484                              filename=new_img,
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)
497         self.vm.launch()
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',
504                              id=self.device_name,
505                              filename=new_img,
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)
517         self.vm.launch()
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',
524                              id=self.device_name,
525                              filename=new_img,
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)
539         self.vm.launch()
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',
546                              id=self.device_name,
547                              filename=new_img,
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)
560         self.vm.launch()
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,
567                                                        filename=new_img,
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)
581         self.vm.launch()
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,
588                                                        filename=new_img,
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)
601         self.vm.launch()
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',
608                              node_name='new',
609                              driver=iotests.imgfmt,
610                              read_only=True,
611                              file={'filename': new_img,
612                                     'driver': 'file'})
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,
626                                                        node_name='new')
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'
645     def setUp(self):
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)
651         self.vm.launch()
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
657         # is not necessary
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',
665                              node_name='node0',
666                              driver=iotests.imgfmt,
667                              file={'filename': old_img,
668                                    'driver': 'file'})
669         self.assert_qmp(result, 'return', {})
671         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
672                                                        node_name='node0')
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)
678     def tearDown(self):
679         self.vm.shutdown()
680         os.remove(old_img)
681         try:
682             os.remove(new_img)
683         except OSError:
684             pass
686     # We need backing file support
687     @iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw',
688                                'vhdx'))
689     def test_snapshot_and_commit(self):
690         result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
691                                                        snapshot_file=new_img,
692                                                        format=iotests.imgfmt)
693         self.assert_qmp(result, 'return', {})
695         result = self.vm.qmp('query-block')
696         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
697         self.assert_qmp(result,
698                         'return[0]/inserted/image/backing-image/filename',
699                         old_img)
701         result = self.vm.qmp('block-commit', device='drive0')
702         self.assert_qmp(result, 'return', {})
704         self.vm.event_wait(name='BLOCK_JOB_READY')
706         result = self.vm.qmp('query-block-jobs')
707         self.assert_qmp(result, 'return[0]/device', 'drive0')
709         result = self.vm.qmp('block-job-complete', device='drive0')
710         self.assert_qmp(result, 'return', {})
712         self.vm.event_wait(name='BLOCK_JOB_COMPLETED')
715 if __name__ == '__main__':
716     if iotests.qemu_default_machine != 'pc':
717         # We need floppy and IDE CD-ROM
718         iotests.notrun('not suitable for this machine type: %s' %
719                        iotests.qemu_default_machine)
720     # Need to support image creation
721     iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
722                                  'vmdk', 'raw', 'vhdx', 'qed'],
723                  supported_protocols=['file'])