These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / tests / qemu-iotests / 118
1 #!/usr/bin/env python
2 #
3 # Test case for the QMP 'change' command and all other associated
4 # commands
5 #
6 # Copyright (C) 2015 Red Hat, Inc.
7 #
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.
12 #
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.
17 #
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/>.
20 #
21
22 import os
23 import stat
24 import time
25 import iotests
26 from iotests import qemu_img
27
28 old_img = os.path.join(iotests.test_dir, 'test0.img')
29 new_img = os.path.join(iotests.test_dir, 'test1.img')
30
31 class ChangeBaseClass(iotests.QMPTestCase):
32     has_opened = False
33     has_closed = False
34
35     def process_events(self):
36         for event in self.vm.get_qmp_events(wait=False):
37             if (event['event'] == 'DEVICE_TRAY_MOVED' and
38                 event['data']['device'] == 'drive0'):
39                 if event['data']['tray-open'] == False:
40                     self.has_closed = True
41                 else:
42                     self.has_opened = True
43
44     def wait_for_open(self):
45         if not self.has_real_tray:
46             return
47
48         timeout = time.clock() + 3
49         while not self.has_opened and time.clock() < timeout:
50             self.process_events()
51         if not self.has_opened:
52             self.fail('Timeout while waiting for the tray to open')
53
54     def wait_for_close(self):
55         if not self.has_real_tray:
56             return
57
58         timeout = time.clock() + 3
59         while not self.has_closed and time.clock() < timeout:
60             self.process_events()
61         if not self.has_opened:
62             self.fail('Timeout while waiting for the tray to close')
63
64 class GeneralChangeTestsBaseClass(ChangeBaseClass):
65     def test_change(self):
66         result = self.vm.qmp('change', device='drive0', target=new_img,
67                                        arg=iotests.imgfmt)
68         self.assert_qmp(result, 'return', {})
69
70         self.wait_for_open()
71         self.wait_for_close()
72
73         result = self.vm.qmp('query-block')
74         if self.has_real_tray:
75             self.assert_qmp(result, 'return[0]/tray_open', False)
76         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
77
78     def test_blockdev_change_medium(self):
79         result = self.vm.qmp('blockdev-change-medium', device='drive0',
80                                                        filename=new_img,
81                                                        format=iotests.imgfmt)
82         self.assert_qmp(result, 'return', {})
83
84         self.wait_for_open()
85         self.wait_for_close()
86
87         result = self.vm.qmp('query-block')
88         if self.has_real_tray:
89             self.assert_qmp(result, 'return[0]/tray_open', False)
90         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
91
92     def test_eject(self):
93         result = self.vm.qmp('eject', device='drive0', force=True)
94         self.assert_qmp(result, 'return', {})
95
96         self.wait_for_open()
97
98         result = self.vm.qmp('query-block')
99         if self.has_real_tray:
100             self.assert_qmp(result, 'return[0]/tray_open', True)
101         self.assert_qmp_absent(result, 'return[0]/inserted')
102
103     def test_tray_eject_change(self):
104         result = self.vm.qmp('eject', device='drive0', force=True)
105         self.assert_qmp(result, 'return', {})
106
107         self.wait_for_open()
108
109         result = self.vm.qmp('query-block')
110         if self.has_real_tray:
111             self.assert_qmp(result, 'return[0]/tray_open', True)
112         self.assert_qmp_absent(result, 'return[0]/inserted')
113
114         result = self.vm.qmp('blockdev-change-medium', device='drive0',
115                                                        filename=new_img,
116                                                        format=iotests.imgfmt)
117         self.assert_qmp(result, 'return', {})
118
119         self.wait_for_close()
120
121         result = self.vm.qmp('query-block')
122         if self.has_real_tray:
123             self.assert_qmp(result, 'return[0]/tray_open', False)
124         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
125
126     def test_tray_open_close(self):
127         result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True)
128         self.assert_qmp(result, 'return', {})
129
130         self.wait_for_open()
131
132         result = self.vm.qmp('query-block')
133         if self.has_real_tray:
134             self.assert_qmp(result, 'return[0]/tray_open', True)
135         if self.was_empty == True:
136             self.assert_qmp_absent(result, 'return[0]/inserted')
137         else:
138             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
139
140         result = self.vm.qmp('blockdev-close-tray', device='drive0')
141         self.assert_qmp(result, 'return', {})
142
143         if self.has_real_tray or not self.was_empty:
144             self.wait_for_close()
145
146         result = self.vm.qmp('query-block')
147         if self.has_real_tray:
148             self.assert_qmp(result, 'return[0]/tray_open', False)
149         if self.was_empty == True:
150             self.assert_qmp_absent(result, 'return[0]/inserted')
151         else:
152             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
153
154     def test_tray_eject_close(self):
155         result = self.vm.qmp('eject', device='drive0', force=True)
156         self.assert_qmp(result, 'return', {})
157
158         self.wait_for_open()
159
160         result = self.vm.qmp('query-block')
161         if self.has_real_tray:
162             self.assert_qmp(result, 'return[0]/tray_open', True)
163         self.assert_qmp_absent(result, 'return[0]/inserted')
164
165         result = self.vm.qmp('blockdev-close-tray', device='drive0')
166         self.assert_qmp(result, 'return', {})
167
168         self.wait_for_close()
169
170         result = self.vm.qmp('query-block')
171         if self.has_real_tray:
172             self.assert_qmp(result, 'return[0]/tray_open', False)
173         self.assert_qmp_absent(result, 'return[0]/inserted')
174
175     def test_tray_open_change(self):
176         result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True)
177         self.assert_qmp(result, 'return', {})
178
179         self.wait_for_open()
180
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)
188
189         result = self.vm.qmp('blockdev-change-medium', device='drive0',
190                                                        filename=new_img,
191                                                        format=iotests.imgfmt)
192         self.assert_qmp(result, 'return', {})
193
194         self.wait_for_close()
195
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)
200
201     def test_cycle(self):
202         result = self.vm.qmp('blockdev-add',
203                              options={'node-name': 'new',
204                                       'driver': iotests.imgfmt,
205                                       'file': {'filename': new_img,
206                                                'driver': 'file'}})
207         self.assert_qmp(result, 'return', {})
208
209         result = self.vm.qmp('blockdev-open-tray', device='drive0', force=True)
210         self.assert_qmp(result, 'return', {})
211
212         self.wait_for_open()
213
214         result = self.vm.qmp('query-block')
215         if self.has_real_tray:
216             self.assert_qmp(result, 'return[0]/tray_open', True)
217         if self.was_empty == True:
218             self.assert_qmp_absent(result, 'return[0]/inserted')
219         else:
220             self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
221
222         result = self.vm.qmp('x-blockdev-remove-medium', device='drive0')
223         self.assert_qmp(result, 'return', {})
224
225         result = self.vm.qmp('query-block')
226         if self.has_real_tray:
227             self.assert_qmp(result, 'return[0]/tray_open', True)
228         self.assert_qmp_absent(result, 'return[0]/inserted')
229
230         result = self.vm.qmp('x-blockdev-insert-medium', device='drive0',
231                                                        node_name='new')
232         self.assert_qmp(result, 'return', {})
233
234         result = self.vm.qmp('query-block')
235         if self.has_real_tray:
236             self.assert_qmp(result, 'return[0]/tray_open', True)
237         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
238
239         result = self.vm.qmp('blockdev-close-tray', device='drive0')
240         self.assert_qmp(result, 'return', {})
241
242         self.wait_for_close()
243
244         result = self.vm.qmp('query-block')
245         if self.has_real_tray:
246             self.assert_qmp(result, 'return[0]/tray_open', False)
247         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
248
249     def test_close_on_closed(self):
250         result = self.vm.qmp('blockdev-close-tray', device='drive0')
251         # Should be a no-op
252         self.assert_qmp(result, 'return', {})
253         self.assertEquals(self.vm.get_qmp_events(wait=False), [])
254
255     def test_remove_on_closed(self):
256         if not self.has_real_tray:
257             return
258
259         result = self.vm.qmp('x-blockdev-remove-medium', device='drive0')
260         self.assert_qmp(result, 'error/class', 'GenericError')
261
262     def test_insert_on_closed(self):
263         if not self.has_real_tray:
264             return
265
266         result = self.vm.qmp('blockdev-add',
267                              options={'node-name': 'new',
268                                       'driver': iotests.imgfmt,
269                                       'file': {'filename': new_img,
270                                                'driver': 'file'}})
271         self.assert_qmp(result, 'return', {})
272
273         result = self.vm.qmp('x-blockdev-insert-medium', device='drive0',
274                                                        node_name='new')
275         self.assert_qmp(result, 'error/class', 'GenericError')
276
277 class TestInitiallyFilled(GeneralChangeTestsBaseClass):
278     was_empty = False
279
280     def setUp(self, media, interface):
281         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
282         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
283         self.vm = iotests.VM().add_drive(old_img, 'media=%s' % media, interface)
284         self.vm.launch()
285
286     def tearDown(self):
287         self.vm.shutdown()
288         os.remove(old_img)
289         os.remove(new_img)
290
291     def test_insert_on_filled(self):
292         result = self.vm.qmp('blockdev-add',
293                              options={'node-name': 'new',
294                                       'driver': iotests.imgfmt,
295                                       'file': {'filename': new_img,
296                                                'driver': 'file'}})
297         self.assert_qmp(result, 'return', {})
298
299         result = self.vm.qmp('blockdev-open-tray', device='drive0')
300         self.assert_qmp(result, 'return', {})
301
302         self.wait_for_open()
303
304         result = self.vm.qmp('x-blockdev-insert-medium', device='drive0',
305                                                        node_name='new')
306         self.assert_qmp(result, 'error/class', 'GenericError')
307
308 class TestInitiallyEmpty(GeneralChangeTestsBaseClass):
309     was_empty = True
310
311     def setUp(self, media, interface):
312         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
313         self.vm = iotests.VM().add_drive(None, 'media=%s' % media, interface)
314         self.vm.launch()
315
316     def tearDown(self):
317         self.vm.shutdown()
318         os.remove(new_img)
319
320     def test_remove_on_empty(self):
321         result = self.vm.qmp('blockdev-open-tray', device='drive0')
322         self.assert_qmp(result, 'return', {})
323
324         self.wait_for_open()
325
326         result = self.vm.qmp('x-blockdev-remove-medium', device='drive0')
327         # Should be a no-op
328         self.assert_qmp(result, 'return', {})
329
330 class TestCDInitiallyFilled(TestInitiallyFilled):
331     TestInitiallyFilled = TestInitiallyFilled
332     has_real_tray = True
333
334     def setUp(self):
335         self.TestInitiallyFilled.setUp(self, 'cdrom', 'ide')
336
337 class TestCDInitiallyEmpty(TestInitiallyEmpty):
338     TestInitiallyEmpty = TestInitiallyEmpty
339     has_real_tray = True
340
341     def setUp(self):
342         self.TestInitiallyEmpty.setUp(self, 'cdrom', 'ide')
343
344 class TestFloppyInitiallyFilled(TestInitiallyFilled):
345     TestInitiallyFilled = TestInitiallyFilled
346     has_real_tray = False
347
348     def setUp(self):
349         self.TestInitiallyFilled.setUp(self, 'disk', 'floppy')
350
351 class TestFloppyInitiallyEmpty(TestInitiallyEmpty):
352     TestInitiallyEmpty = TestInitiallyEmpty
353     has_real_tray = False
354
355     def setUp(self):
356         self.TestInitiallyEmpty.setUp(self, 'disk', 'floppy')
357         # FDDs not having a real tray and there not being a medium inside the
358         # tray at startup means the tray will be considered open
359         self.has_opened = True
360
361 class TestChangeReadOnly(ChangeBaseClass):
362     def setUp(self):
363         qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
364         qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
365         self.vm = iotests.VM()
366
367     def tearDown(self):
368         self.vm.shutdown()
369         os.chmod(old_img, 0666)
370         os.chmod(new_img, 0666)
371         os.remove(old_img)
372         os.remove(new_img)
373
374     def test_ro_ro_retain(self):
375         os.chmod(old_img, 0444)
376         os.chmod(new_img, 0444)
377         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
378         self.vm.launch()
379
380         result = self.vm.qmp('query-block')
381         self.assert_qmp(result, 'return[0]/inserted/ro', True)
382         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
383
384         result = self.vm.qmp('blockdev-change-medium', device='drive0',
385                                                        filename=new_img,
386                                                        format=iotests.imgfmt,
387                                                        read_only_mode='retain')
388         self.assert_qmp(result, 'return', {})
389
390         result = self.vm.qmp('query-block')
391         self.assert_qmp(result, 'return[0]/inserted/ro', True)
392         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
393
394     def test_ro_rw_retain(self):
395         os.chmod(old_img, 0444)
396         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
397         self.vm.launch()
398
399         result = self.vm.qmp('query-block')
400         self.assert_qmp(result, 'return[0]/inserted/ro', True)
401         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
402
403         result = self.vm.qmp('blockdev-change-medium', device='drive0',
404                                                        filename=new_img,
405                                                        format=iotests.imgfmt,
406                                                        read_only_mode='retain')
407         self.assert_qmp(result, 'return', {})
408
409         result = self.vm.qmp('query-block')
410         self.assert_qmp(result, 'return[0]/inserted/ro', True)
411         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
412
413     def test_rw_ro_retain(self):
414         os.chmod(new_img, 0444)
415         self.vm.add_drive(old_img, 'media=disk', 'floppy')
416         self.vm.launch()
417
418         result = self.vm.qmp('query-block')
419         self.assert_qmp(result, 'return[0]/inserted/ro', False)
420         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
421
422         result = self.vm.qmp('blockdev-change-medium', device='drive0',
423                                                        filename=new_img,
424                                                        format=iotests.imgfmt,
425                                                        read_only_mode='retain')
426         self.assert_qmp(result, 'error/class', 'GenericError')
427
428         self.assertEquals(self.vm.get_qmp_events(wait=False), [])
429
430         result = self.vm.qmp('query-block')
431         self.assert_qmp(result, 'return[0]/inserted/ro', False)
432         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
433
434     def test_ro_rw(self):
435         os.chmod(old_img, 0444)
436         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
437         self.vm.launch()
438
439         result = self.vm.qmp('query-block')
440         self.assert_qmp(result, 'return[0]/inserted/ro', True)
441         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
442
443         result = self.vm.qmp('blockdev-change-medium',
444                              device='drive0',
445                              filename=new_img,
446                              format=iotests.imgfmt,
447                              read_only_mode='read-write')
448         self.assert_qmp(result, 'return', {})
449
450         result = self.vm.qmp('query-block')
451         self.assert_qmp(result, 'return[0]/inserted/ro', False)
452         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
453
454     def test_rw_ro(self):
455         os.chmod(new_img, 0444)
456         self.vm.add_drive(old_img, 'media=disk', 'floppy')
457         self.vm.launch()
458
459         result = self.vm.qmp('query-block')
460         self.assert_qmp(result, 'return[0]/inserted/ro', False)
461         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
462
463         result = self.vm.qmp('blockdev-change-medium',
464                              device='drive0',
465                              filename=new_img,
466                              format=iotests.imgfmt,
467                              read_only_mode='read-only')
468         self.assert_qmp(result, 'return', {})
469
470         result = self.vm.qmp('query-block')
471         self.assert_qmp(result, 'return[0]/inserted/ro', True)
472         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
473
474     def test_make_rw_ro(self):
475         self.vm.add_drive(old_img, 'media=disk', 'floppy')
476         self.vm.launch()
477
478         result = self.vm.qmp('query-block')
479         self.assert_qmp(result, 'return[0]/inserted/ro', False)
480         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
481
482         result = self.vm.qmp('blockdev-change-medium',
483                              device='drive0',
484                              filename=new_img,
485                              format=iotests.imgfmt,
486                              read_only_mode='read-only')
487         self.assert_qmp(result, 'return', {})
488
489         result = self.vm.qmp('query-block')
490         self.assert_qmp(result, 'return[0]/inserted/ro', True)
491         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
492
493     def test_make_ro_rw(self):
494         os.chmod(new_img, 0444)
495         self.vm.add_drive(old_img, 'media=disk', 'floppy')
496         self.vm.launch()
497
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)
501
502         result = self.vm.qmp('blockdev-change-medium',
503                              device='drive0',
504                              filename=new_img,
505                              format=iotests.imgfmt,
506                              read_only_mode='read-write')
507         self.assert_qmp(result, 'error/class', 'GenericError')
508
509         result = self.vm.qmp('query-block')
510         self.assert_qmp(result, 'return[0]/inserted/ro', False)
511         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
512
513     def test_make_rw_ro_by_retain(self):
514         os.chmod(old_img, 0444)
515         self.vm.add_drive(old_img, 'media=disk,read-only=on', 'floppy')
516         self.vm.launch()
517
518         result = self.vm.qmp('query-block')
519         self.assert_qmp(result, 'return[0]/inserted/ro', True)
520         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
521
522         result = self.vm.qmp('blockdev-change-medium', device='drive0',
523                                                        filename=new_img,
524                                                        format=iotests.imgfmt,
525                                                        read_only_mode='retain')
526         self.assert_qmp(result, 'return', {})
527
528         result = self.vm.qmp('query-block')
529         self.assert_qmp(result, 'return[0]/inserted/ro', True)
530         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
531
532     def test_make_ro_rw_by_retain(self):
533         os.chmod(new_img, 0444)
534         self.vm.add_drive(old_img, 'media=disk', 'floppy')
535         self.vm.launch()
536
537         result = self.vm.qmp('query-block')
538         self.assert_qmp(result, 'return[0]/inserted/ro', False)
539         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
540
541         result = self.vm.qmp('blockdev-change-medium', device='drive0',
542                                                        filename=new_img,
543                                                        format=iotests.imgfmt,
544                                                        read_only_mode='retain')
545         self.assert_qmp(result, 'error/class', 'GenericError')
546
547         result = self.vm.qmp('query-block')
548         self.assert_qmp(result, 'return[0]/inserted/ro', False)
549         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
550
551     def test_rw_ro_cycle(self):
552         os.chmod(new_img, 0444)
553         self.vm.add_drive(old_img, 'media=disk', 'floppy')
554         self.vm.launch()
555
556         result = self.vm.qmp('query-block')
557         self.assert_qmp(result, 'return[0]/inserted/ro', False)
558         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
559
560         result = self.vm.qmp('blockdev-add',
561                              options={'node-name': 'new',
562                                       'driver': iotests.imgfmt,
563                                       'read-only': True,
564                                       'file': {'filename': new_img,
565                                                'driver': 'file'}})
566         self.assert_qmp(result, 'return', {})
567
568         result = self.vm.qmp('query-block')
569         self.assert_qmp(result, 'return[0]/inserted/ro', False)
570         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
571
572         result = self.vm.qmp('x-blockdev-remove-medium', device='drive0')
573         self.assert_qmp(result, 'return', {})
574
575         result = self.vm.qmp('query-block')
576         self.assert_qmp_absent(result, 'return[0]/inserted')
577
578         result = self.vm.qmp('x-blockdev-insert-medium', device='drive0',
579                                                        node_name='new')
580         self.assert_qmp(result, 'return', {})
581
582         result = self.vm.qmp('query-block')
583         self.assert_qmp(result, 'return[0]/inserted/ro', True)
584         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
585
586         result = self.vm.qmp('query-block')
587         self.assert_qmp(result, 'return[0]/inserted/ro', True)
588         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
589
590 GeneralChangeTestsBaseClass = None
591 TestInitiallyFilled = None
592 TestInitiallyEmpty = None
593
594
595 class TestBlockJobsAfterCycle(ChangeBaseClass):
596     def setUp(self):
597         qemu_img('create', '-f', iotests.imgfmt, old_img, '1M')
598
599         self.vm = iotests.VM()
600         self.vm.launch()
601
602         result = self.vm.qmp('blockdev-add',
603                              options={'id': 'drive0',
604                                       'driver': 'null-co'})
605         self.assert_qmp(result, 'return', {})
606
607         result = self.vm.qmp('query-block')
608         self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co')
609
610         # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
611         # is not necessary
612         result = self.vm.qmp('x-blockdev-remove-medium', device='drive0')
613         self.assert_qmp(result, 'return', {})
614
615         result = self.vm.qmp('query-block')
616         self.assert_qmp_absent(result, 'return[0]/inserted')
617
618         result = self.vm.qmp('blockdev-add',
619                              options={'node-name': 'node0',
620                                       'driver': iotests.imgfmt,
621                                       'file': {'filename': old_img,
622                                                'driver': 'file'}})
623         self.assert_qmp(result, 'return', {})
624
625         result = self.vm.qmp('x-blockdev-insert-medium', device='drive0',
626                                                        node_name='node0')
627         self.assert_qmp(result, 'return', {})
628
629         result = self.vm.qmp('query-block')
630         self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
631
632     def tearDown(self):
633         self.vm.shutdown()
634         os.remove(old_img)
635         try:
636             os.remove(new_img)
637         except OSError:
638             pass
639
640     def test_snapshot_and_commit(self):
641         # We need backing file support
642         if iotests.imgfmt != 'qcow2' and iotests.imgfmt != 'qed':
643             return
644
645         result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
646                                                        snapshot_file=new_img,
647                                                        format=iotests.imgfmt)
648         self.assert_qmp(result, 'return', {})
649
650         result = self.vm.qmp('query-block')
651         self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
652         self.assert_qmp(result,
653                         'return[0]/inserted/image/backing-image/filename',
654                         old_img)
655
656         result = self.vm.qmp('block-commit', device='drive0')
657         self.assert_qmp(result, 'return', {})
658
659         self.vm.event_wait(name='BLOCK_JOB_READY')
660
661         result = self.vm.qmp('query-block-jobs')
662         self.assert_qmp(result, 'return[0]/device', 'drive0')
663
664         result = self.vm.qmp('block-job-complete', device='drive0')
665         self.assert_qmp(result, 'return', {})
666
667         self.vm.event_wait(name='BLOCK_JOB_COMPLETED')
668
669
670 if __name__ == '__main__':
671     if iotests.qemu_default_machine != 'pc':
672         # We need floppy and IDE CD-ROM
673         iotests.notrun('not suitable for this machine type: %s' %
674                        iotests.qemu_default_machine)
675     # Need to support image creation
676     iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
677                                  'vmdk', 'raw', 'vhdx', 'qed'])