iotests.py: qemu_io(): reuse qemu_tool_pipe_and_status()
[qemu/ar7.git] / tests / qemu-iotests / 118
blob1a2e219057997e509db88b6a8a37e3b14a3087f4
1 #!/usr/bin/env python3
2 # group: rw
4 # Test case for the QMP 'change' command and all other associated
5 # commands
7 # Copyright (C) 2015 Red Hat, Inc.
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 import os
24 import stat
25 import time
26 import iotests
27 from iotests import qemu_img
29 old_img = os.path.join(iotests.test_dir, 'test0.img')
30 new_img = os.path.join(iotests.test_dir, 'test1.img')
32 def interface_to_device_name(interface):
33     if interface == 'ide':
34         return 'ide-cd'
35     elif interface == 'floppy':
36         return 'floppy'
37     elif interface == 'scsi':
38         return 'scsi-cd'
39     else:
40         return None
42 class ChangeBaseClass(iotests.QMPTestCase):
43     has_opened = False
44     has_closed = False
46     device_name = 'qdev0'
47     use_drive = False
49     def process_events(self):
50         for event in self.vm.get_qmp_events(wait=False):
51             if (event['event'] == 'DEVICE_TRAY_MOVED' and
52                 (event['data']['device'] == 'drive0' or
53                  event['data']['id'] == self.device_name)):
54                 if event['data']['tray-open'] == False:
55                     self.has_closed = True
56                 else:
57                     self.has_opened = True
59     def wait_for_open(self):
60         if not self.has_real_tray:
61             return
63         with iotests.Timeout(3, 'Timeout while waiting for the tray to open'):
64             while not self.has_opened:
65                 self.process_events()
67     def wait_for_close(self):
68         if not self.has_real_tray:
69             return
71         with iotests.Timeout(3, 'Timeout while waiting for the tray to close'):
72             while not self.has_closed:
73                 self.process_events()
75 class GeneralChangeTestsBaseClass(ChangeBaseClass):
77     def test_change(self):
78         # 'change' requires a drive name, so skip the test for blockdev
79         if not self.use_drive:
80             return
82         result = self.vm.qmp('change', device='drive0', target=new_img,
83                                        arg=iotests.imgfmt)
84         self.assert_qmp(result, 'return', {})
86         self.wait_for_open()
87         self.wait_for_close()
89         result = self.vm.qmp('query-block')
90         if self.has_real_tray:
91             self.assert_qmp(result, 'return[0]/tray_open', False)
92         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
94     def test_blockdev_change_medium(self):
95         result = self.vm.qmp('blockdev-change-medium',
96                              id=self.device_name, filename=new_img,
97                              format=iotests.imgfmt)
99         self.assert_qmp(result, 'return', {})
101         self.wait_for_open()
102         self.wait_for_close()
104         result = self.vm.qmp('query-block')
105         if self.has_real_tray:
106             self.assert_qmp(result, 'return[0]/tray_open', False)
107         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
109     def test_eject(self):
110         result = self.vm.qmp('eject', id=self.device_name, force=True)
111         self.assert_qmp(result, 'return', {})
113         self.wait_for_open()
115         result = self.vm.qmp('query-block')
116         if self.has_real_tray:
117             self.assert_qmp(result, 'return[0]/tray_open', True)
118         self.assert_qmp_absent(result, 'return[0]/inserted')
120     def test_tray_eject_change(self):
121         result = self.vm.qmp('eject', id=self.device_name, force=True)
122         self.assert_qmp(result, 'return', {})
124         self.wait_for_open()
126         result = self.vm.qmp('query-block')
127         if self.has_real_tray:
128             self.assert_qmp(result, 'return[0]/tray_open', True)
129         self.assert_qmp_absent(result, 'return[0]/inserted')
131         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
132                              filename=new_img, format=iotests.imgfmt)
133         self.assert_qmp(result, 'return', {})
135         self.wait_for_close()
137         result = self.vm.qmp('query-block')
138         if self.has_real_tray:
139             self.assert_qmp(result, 'return[0]/tray_open', False)
140         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
142     def test_tray_open_close(self):
143         result = self.vm.qmp('blockdev-open-tray',
144                              id=self.device_name, force=True)
145         self.assert_qmp(result, 'return', {})
147         self.wait_for_open()
149         result = self.vm.qmp('query-block')
150         if self.has_real_tray:
151             self.assert_qmp(result, 'return[0]/tray_open', True)
152         if self.was_empty == True:
153             self.assert_qmp_absent(result, 'return[0]/inserted')
154         else:
155             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
157         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
158         self.assert_qmp(result, 'return', {})
160         if self.has_real_tray or not self.was_empty:
161             self.wait_for_close()
163         result = self.vm.qmp('query-block')
164         if self.has_real_tray:
165             self.assert_qmp(result, 'return[0]/tray_open', False)
166         if self.was_empty == True:
167             self.assert_qmp_absent(result, 'return[0]/inserted')
168         else:
169             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
171     def test_tray_eject_close(self):
172         result = self.vm.qmp('eject', id=self.device_name, force=True)
173         self.assert_qmp(result, 'return', {})
175         self.wait_for_open()
177         result = self.vm.qmp('query-block')
178         if self.has_real_tray:
179             self.assert_qmp(result, 'return[0]/tray_open', True)
180         self.assert_qmp_absent(result, 'return[0]/inserted')
182         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
183         self.assert_qmp(result, 'return', {})
185         self.wait_for_close()
187         result = self.vm.qmp('query-block')
188         if self.has_real_tray:
189             self.assert_qmp(result, 'return[0]/tray_open', False)
190         self.assert_qmp_absent(result, 'return[0]/inserted')
192     def test_tray_open_change(self):
193         result = self.vm.qmp('blockdev-open-tray', id=self.device_name,
194                                                    force=True)
195         self.assert_qmp(result, 'return', {})
197         self.wait_for_open()
199         result = self.vm.qmp('query-block')
200         if self.has_real_tray:
201             self.assert_qmp(result, 'return[0]/tray_open', True)
202         if self.was_empty == True:
203             self.assert_qmp_absent(result, 'return[0]/inserted')
204         else:
205             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
207         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
208                                                        filename=new_img,
209                                                        format=iotests.imgfmt)
210         self.assert_qmp(result, 'return', {})
212         self.wait_for_close()
214         result = self.vm.qmp('query-block')
215         if self.has_real_tray:
216             self.assert_qmp(result, 'return[0]/tray_open', False)
217         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
219     def test_cycle(self, read_only_node=False):
220         result = self.vm.qmp('blockdev-add',
221                              node_name='new',
222                              driver=iotests.imgfmt,
223                              read_only=read_only_node,
224                              file={'filename': new_img,
225                                     'driver': 'file'})
226         self.assert_qmp(result, 'return', {})
228         result = self.vm.qmp('blockdev-open-tray',
229                              id=self.device_name, force=True)
230         self.assert_qmp(result, 'return', {})
232         self.wait_for_open()
234         result = self.vm.qmp('query-block')
235         if self.has_real_tray:
236             self.assert_qmp(result, 'return[0]/tray_open', True)
237         if self.was_empty == True:
238             self.assert_qmp_absent(result, 'return[0]/inserted')
239         else:
240             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
242         result = self.vm.qmp('blockdev-remove-medium',
243                              id=self.device_name)
244         self.assert_qmp(result, 'return', {})
246         result = self.vm.qmp('query-block')
247         if self.has_real_tray:
248             self.assert_qmp(result, 'return[0]/tray_open', True)
249         self.assert_qmp_absent(result, 'return[0]/inserted')
251         result = self.vm.qmp('blockdev-insert-medium',
252                              id=self.device_name, node_name='new')
253         self.assert_qmp(result, 'return', {})
255         result = self.vm.qmp('query-block')
256         if self.has_real_tray:
257             self.assert_qmp(result, 'return[0]/tray_open', True)
258         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
260         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
261         self.assert_qmp(result, 'return', {})
263         self.wait_for_close()
265         result = self.vm.qmp('query-block')
266         if self.has_real_tray:
267             self.assert_qmp(result, 'return[0]/tray_open', False)
268         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
270     def test_cycle_read_only_media(self):
271         self.test_cycle(True)
273     def test_close_on_closed(self):
274         result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
275         # Should be a no-op
276         self.assert_qmp(result, 'return', {})
277         self.assertEqual(self.vm.get_qmp_events(wait=False), [])
279     def test_remove_on_closed(self):
280         if not self.has_real_tray:
281             return
283         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
284         self.assert_qmp(result, 'error/class', 'GenericError')
286     def test_insert_on_closed(self):
287         if not self.has_real_tray:
288             return
290         result = self.vm.qmp('blockdev-add',
291                              node_name='new',
292                              driver=iotests.imgfmt,
293                              file={'filename': new_img,
294                                    'driver': 'file'})
295         self.assert_qmp(result, 'return', {})
297         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
298                                                        node_name='new')
299         self.assert_qmp(result, 'error/class', 'GenericError')
301 class TestInitiallyFilled(GeneralChangeTestsBaseClass):
302     was_empty = False
304     def setUp(self):
305         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
306         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
307         self.vm = iotests.VM()
308         if self.use_drive:
309             self.vm.add_drive(old_img, 'media=%s' % self.media, 'none')
310         else:
311             self.vm.add_blockdev([ 'node-name=drive0',
312                                    'driver=%s' % iotests.imgfmt,
313                                    'file.driver=file',
314                                    'file.filename=%s' % old_img ])
315         if self.interface == 'scsi':
316             self.vm.add_device('virtio-scsi-pci')
317         self.vm.add_device('%s,drive=drive0,id=%s' %
318                            (interface_to_device_name(self.interface),
319                             self.device_name))
320         self.vm.launch()
322     def tearDown(self):
323         self.vm.shutdown()
324         os.remove(old_img)
325         os.remove(new_img)
327     def test_insert_on_filled(self):
328         result = self.vm.qmp('blockdev-add',
329                              node_name='new',
330                              driver=iotests.imgfmt,
331                              file={'filename': new_img,
332                                    'driver': 'file'})
333         self.assert_qmp(result, 'return', {})
335         result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
336         self.assert_qmp(result, 'return', {})
338         self.wait_for_open()
340         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
341                                                        node_name='new')
342         self.assert_qmp(result, 'error/class', 'GenericError')
344 class TestInitiallyEmpty(GeneralChangeTestsBaseClass):
345     was_empty = True
347     def setUp(self):
348         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
349         self.vm = iotests.VM()
350         if self.use_drive:
351             self.vm.add_drive(None, 'media=%s' % self.media, 'none')
352         if self.interface == 'scsi':
353             self.vm.add_device('virtio-scsi-pci')
354         self.vm.add_device('%s,%sid=%s' %
355                            (interface_to_device_name(self.interface),
356                             'drive=drive0,' if self.use_drive else '',
357                             self.device_name))
358         self.vm.launch()
360     def tearDown(self):
361         self.vm.shutdown()
362         os.remove(new_img)
364     def test_remove_on_empty(self):
365         result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
366         self.assert_qmp(result, 'return', {})
368         self.wait_for_open()
370         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
371         # Should be a no-op
372         self.assert_qmp(result, 'return', {})
374 # Do this in a function to avoid leaking variables like case into the global
375 # name space (otherwise tests would be run for the abstract base classes)
376 def create_basic_test_classes():
377     for (media, interface, has_real_tray) in [ ('cdrom', 'ide', True),
378                                                ('cdrom', 'scsi', True),
379                                                ('disk', 'floppy', False) ]:
381         for case in [ TestInitiallyFilled, TestInitiallyEmpty ]:
382             for use_drive in [ True, False ]:
383                 attr = { 'media': media,
384                          'interface': interface,
385                          'has_real_tray': has_real_tray,
386                          'use_drive': use_drive }
388                 name = '%s_%s_%s_%s' % (case.__name__, media, interface,
389                                         'drive' if use_drive else 'blockdev')
390                 globals()[name] = type(name, (case, ), attr)
392 create_basic_test_classes()
394 class TestChangeReadOnly(ChangeBaseClass):
395     device_name = 'qdev0'
397     def setUp(self):
398         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
399         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
400         self.vm = iotests.VM()
402     def tearDown(self):
403         self.vm.shutdown()
404         os.chmod(old_img, 0o666)
405         os.chmod(new_img, 0o666)
406         os.remove(old_img)
407         os.remove(new_img)
409     def test_ro_ro_retain(self):
410         os.chmod(old_img, 0o444)
411         os.chmod(new_img, 0o444)
412         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
413         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
414         self.vm.launch()
416         result = self.vm.qmp('query-block')
417         self.assert_qmp(result, 'return[0]/inserted/ro', True)
418         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
420         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
421                                                        filename=new_img,
422                                                        format=iotests.imgfmt,
423                                                        read_only_mode='retain')
424         self.assert_qmp(result, 'return', {})
426         result = self.vm.qmp('query-block')
427         self.assert_qmp(result, 'return[0]/inserted/ro', True)
428         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
430     def test_ro_rw_retain(self):
431         os.chmod(old_img, 0o444)
432         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
433         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
434         self.vm.launch()
436         result = self.vm.qmp('query-block')
437         self.assert_qmp(result, 'return[0]/inserted/ro', True)
438         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
440         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
441                                                        filename=new_img,
442                                                        format=iotests.imgfmt,
443                                                        read_only_mode='retain')
444         self.assert_qmp(result, 'return', {})
446         result = self.vm.qmp('query-block')
447         self.assert_qmp(result, 'return[0]/inserted/ro', True)
448         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
450     @iotests.skip_if_user_is_root
451     def test_rw_ro_retain(self):
452         os.chmod(new_img, 0o444)
453         self.vm.add_drive(old_img, 'media=disk', 'none')
454         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
455         self.vm.launch()
457         result = self.vm.qmp('query-block')
458         self.assert_qmp(result, 'return[0]/inserted/ro', False)
459         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
461         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
462                                                        filename=new_img,
463                                                        format=iotests.imgfmt,
464                                                        read_only_mode='retain')
465         self.assert_qmp(result, 'error/class', 'GenericError')
467         self.assertEqual(self.vm.get_qmp_events(wait=False), [])
469         result = self.vm.qmp('query-block')
470         self.assert_qmp(result, 'return[0]/inserted/ro', False)
471         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
473     def test_ro_rw(self):
474         os.chmod(old_img, 0o444)
475         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
476         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
477         self.vm.launch()
479         result = self.vm.qmp('query-block')
480         self.assert_qmp(result, 'return[0]/inserted/ro', True)
481         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
483         result = self.vm.qmp('blockdev-change-medium',
484                              id=self.device_name,
485                              filename=new_img,
486                              format=iotests.imgfmt,
487                              read_only_mode='read-write')
488         self.assert_qmp(result, 'return', {})
490         result = self.vm.qmp('query-block')
491         self.assert_qmp(result, 'return[0]/inserted/ro', False)
492         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
494     def test_rw_ro(self):
495         os.chmod(new_img, 0o444)
496         self.vm.add_drive(old_img, 'media=disk', 'none')
497         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
498         self.vm.launch()
500         result = self.vm.qmp('query-block')
501         self.assert_qmp(result, 'return[0]/inserted/ro', False)
502         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
504         result = self.vm.qmp('blockdev-change-medium',
505                              id=self.device_name,
506                              filename=new_img,
507                              format=iotests.imgfmt,
508                              read_only_mode='read-only')
509         self.assert_qmp(result, 'return', {})
511         result = self.vm.qmp('query-block')
512         self.assert_qmp(result, 'return[0]/inserted/ro', True)
513         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
515     def test_make_rw_ro(self):
516         self.vm.add_drive(old_img, 'media=disk', 'none')
517         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
518         self.vm.launch()
520         result = self.vm.qmp('query-block')
521         self.assert_qmp(result, 'return[0]/inserted/ro', False)
522         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
524         result = self.vm.qmp('blockdev-change-medium',
525                              id=self.device_name,
526                              filename=new_img,
527                              format=iotests.imgfmt,
528                              read_only_mode='read-only')
529         self.assert_qmp(result, 'return', {})
531         result = self.vm.qmp('query-block')
532         self.assert_qmp(result, 'return[0]/inserted/ro', True)
533         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
535     @iotests.skip_if_user_is_root
536     def test_make_ro_rw(self):
537         os.chmod(new_img, 0o444)
538         self.vm.add_drive(old_img, 'media=disk', 'none')
539         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
540         self.vm.launch()
542         result = self.vm.qmp('query-block')
543         self.assert_qmp(result, 'return[0]/inserted/ro', False)
544         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
546         result = self.vm.qmp('blockdev-change-medium',
547                              id=self.device_name,
548                              filename=new_img,
549                              format=iotests.imgfmt,
550                              read_only_mode='read-write')
551         self.assert_qmp(result, 'error/class', 'GenericError')
553         result = self.vm.qmp('query-block')
554         self.assert_qmp(result, 'return[0]/inserted/ro', False)
555         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
557     def test_make_rw_ro_by_retain(self):
558         os.chmod(old_img, 0o444)
559         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
560         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
561         self.vm.launch()
563         result = self.vm.qmp('query-block')
564         self.assert_qmp(result, 'return[0]/inserted/ro', True)
565         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
567         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
568                                                        filename=new_img,
569                                                        format=iotests.imgfmt,
570                                                        read_only_mode='retain')
571         self.assert_qmp(result, 'return', {})
573         result = self.vm.qmp('query-block')
574         self.assert_qmp(result, 'return[0]/inserted/ro', True)
575         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
577     @iotests.skip_if_user_is_root
578     def test_make_ro_rw_by_retain(self):
579         os.chmod(new_img, 0o444)
580         self.vm.add_drive(old_img, 'media=disk', 'none')
581         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
582         self.vm.launch()
584         result = self.vm.qmp('query-block')
585         self.assert_qmp(result, 'return[0]/inserted/ro', False)
586         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
588         result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
589                                                        filename=new_img,
590                                                        format=iotests.imgfmt,
591                                                        read_only_mode='retain')
592         self.assert_qmp(result, 'error/class', 'GenericError')
594         result = self.vm.qmp('query-block')
595         self.assert_qmp(result, 'return[0]/inserted/ro', False)
596         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
598     def test_rw_ro_cycle(self):
599         os.chmod(new_img, 0o444)
600         self.vm.add_drive(old_img, 'media=disk', 'none')
601         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
602         self.vm.launch()
604         result = self.vm.qmp('query-block')
605         self.assert_qmp(result, 'return[0]/inserted/ro', False)
606         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
608         result = self.vm.qmp('blockdev-add',
609                              node_name='new',
610                              driver=iotests.imgfmt,
611                              read_only=True,
612                              file={'filename': new_img,
613                                     'driver': 'file'})
614         self.assert_qmp(result, 'return', {})
616         result = self.vm.qmp('query-block')
617         self.assert_qmp(result, 'return[0]/inserted/ro', False)
618         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
620         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
621         self.assert_qmp(result, 'return', {})
623         result = self.vm.qmp('query-block')
624         self.assert_qmp_absent(result, 'return[0]/inserted')
626         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
627                                                        node_name='new')
628         self.assert_qmp(result, 'return', {})
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         result = self.vm.qmp('query-block')
635         self.assert_qmp(result, 'return[0]/inserted/ro', True)
636         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
638 GeneralChangeTestsBaseClass = None
639 TestInitiallyFilled = None
640 TestInitiallyEmpty = None
643 class TestBlockJobsAfterCycle(ChangeBaseClass):
644     device_name = 'qdev0'
646     def setUp(self):
647         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K')
649         self.vm = iotests.VM()
650         self.vm.add_drive_raw("id=drive0,driver=null-co,if=none")
651         self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
652         self.vm.launch()
654         result = self.vm.qmp('query-block')
655         self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co')
657         # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
658         # is not necessary
659         result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
660         self.assert_qmp(result, 'return', {})
662         result = self.vm.qmp('query-block')
663         self.assert_qmp_absent(result, 'return[0]/inserted')
665         result = self.vm.qmp('blockdev-add',
666                              node_name='node0',
667                              driver=iotests.imgfmt,
668                              file={'filename': old_img,
669                                    'driver': 'file'})
670         self.assert_qmp(result, 'return', {})
672         result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
673                                                        node_name='node0')
674         self.assert_qmp(result, 'return', {})
676         result = self.vm.qmp('query-block')
677         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
679     def tearDown(self):
680         self.vm.shutdown()
681         os.remove(old_img)
682         try:
683             os.remove(new_img)
684         except OSError:
685             pass
687     # We need backing file support
688     @iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw',
689                                'vhdx'))
690     def test_snapshot_and_commit(self):
691         result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
692                                                        snapshot_file=new_img,
693                                                        format=iotests.imgfmt)
694         self.assert_qmp(result, 'return', {})
696         result = self.vm.qmp('query-block')
697         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
698         self.assert_qmp(result,
699                         'return[0]/inserted/image/backing-image/filename',
700                         old_img)
702         result = self.vm.qmp('block-commit', device='drive0')
703         self.assert_qmp(result, 'return', {})
705         self.vm.event_wait(name='BLOCK_JOB_READY')
707         result = self.vm.qmp('query-block-jobs')
708         self.assert_qmp(result, 'return[0]/device', 'drive0')
710         result = self.vm.qmp('block-job-complete', device='drive0')
711         self.assert_qmp(result, 'return', {})
713         self.vm.event_wait(name='BLOCK_JOB_COMPLETED')
716 if __name__ == '__main__':
717     if iotests.qemu_default_machine != 'pc':
718         # We need floppy and IDE CD-ROM
719         iotests.notrun('not suitable for this machine type: %s' %
720                        iotests.qemu_default_machine)
721     # Need to support image creation
722     iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
723                                  'vmdk', 'raw', 'vhdx', 'qed'],
724                  supported_protocols=['file'])