]> git.proxmox.com Git - mirror_qemu.git/blob - tests/qemu-iotests/118
iotest 134: test cluster-misaligned encrypted write
[mirror_qemu.git] / 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 def interface_to_device_name(interface):
32 if interface == 'ide':
33 return 'ide-cd'
34 elif interface == 'floppy':
35 return 'floppy'
36 else:
37 return None
38
39 class ChangeBaseClass(iotests.QMPTestCase):
40 has_opened = False
41 has_closed = False
42
43 def process_events(self):
44 for event in self.vm.get_qmp_events(wait=False):
45 if (event['event'] == 'DEVICE_TRAY_MOVED' and
46 event['data']['device'] == 'drive0'):
47 if event['data']['tray-open'] == False:
48 self.has_closed = True
49 else:
50 self.has_opened = True
51
52 def wait_for_open(self):
53 if not self.has_real_tray:
54 return
55
56 with iotests.Timeout(3, 'Timeout while waiting for the tray to open'):
57 while not self.has_opened:
58 self.process_events()
59
60 def wait_for_close(self):
61 if not self.has_real_tray:
62 return
63
64 with iotests.Timeout(3, 'Timeout while waiting for the tray to close'):
65 while not self.has_closed:
66 self.process_events()
67
68 class GeneralChangeTestsBaseClass(ChangeBaseClass):
69
70 device_name = 'qdev0'
71
72 def test_change(self):
73 result = self.vm.qmp('change', device='drive0', target=new_img,
74 arg=iotests.imgfmt)
75 self.assert_qmp(result, 'return', {})
76
77 self.wait_for_open()
78 self.wait_for_close()
79
80 result = self.vm.qmp('query-block')
81 if self.has_real_tray:
82 self.assert_qmp(result, 'return[0]/tray_open', False)
83 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
84
85 def test_blockdev_change_medium(self):
86 result = self.vm.qmp('blockdev-change-medium',
87 id=self.device_name, filename=new_img,
88 format=iotests.imgfmt)
89
90 self.assert_qmp(result, 'return', {})
91
92 self.wait_for_open()
93 self.wait_for_close()
94
95 result = self.vm.qmp('query-block')
96 if self.has_real_tray:
97 self.assert_qmp(result, 'return[0]/tray_open', False)
98 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
99
100 def test_eject(self):
101 result = self.vm.qmp('eject', id=self.device_name, force=True)
102 self.assert_qmp(result, 'return', {})
103
104 self.wait_for_open()
105
106 result = self.vm.qmp('query-block')
107 if self.has_real_tray:
108 self.assert_qmp(result, 'return[0]/tray_open', True)
109 self.assert_qmp_absent(result, 'return[0]/inserted')
110
111 def test_tray_eject_change(self):
112 result = self.vm.qmp('eject', id=self.device_name, force=True)
113 self.assert_qmp(result, 'return', {})
114
115 self.wait_for_open()
116
117 result = self.vm.qmp('query-block')
118 if self.has_real_tray:
119 self.assert_qmp(result, 'return[0]/tray_open', True)
120 self.assert_qmp_absent(result, 'return[0]/inserted')
121
122 result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
123 filename=new_img, format=iotests.imgfmt)
124 self.assert_qmp(result, 'return', {})
125
126 self.wait_for_close()
127
128 result = self.vm.qmp('query-block')
129 if self.has_real_tray:
130 self.assert_qmp(result, 'return[0]/tray_open', False)
131 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
132
133 def test_tray_open_close(self):
134 result = self.vm.qmp('blockdev-open-tray',
135 id=self.device_name, force=True)
136 self.assert_qmp(result, 'return', {})
137
138 self.wait_for_open()
139
140 result = self.vm.qmp('query-block')
141 if self.has_real_tray:
142 self.assert_qmp(result, 'return[0]/tray_open', True)
143 if self.was_empty == True:
144 self.assert_qmp_absent(result, 'return[0]/inserted')
145 else:
146 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
147
148 result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
149 self.assert_qmp(result, 'return', {})
150
151 if self.has_real_tray or not self.was_empty:
152 self.wait_for_close()
153
154 result = self.vm.qmp('query-block')
155 if self.has_real_tray:
156 self.assert_qmp(result, 'return[0]/tray_open', False)
157 if self.was_empty == True:
158 self.assert_qmp_absent(result, 'return[0]/inserted')
159 else:
160 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
161
162 def test_tray_eject_close(self):
163 result = self.vm.qmp('eject', id=self.device_name, force=True)
164 self.assert_qmp(result, 'return', {})
165
166 self.wait_for_open()
167
168 result = self.vm.qmp('query-block')
169 if self.has_real_tray:
170 self.assert_qmp(result, 'return[0]/tray_open', True)
171 self.assert_qmp_absent(result, 'return[0]/inserted')
172
173 result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
174 self.assert_qmp(result, 'return', {})
175
176 self.wait_for_close()
177
178 result = self.vm.qmp('query-block')
179 if self.has_real_tray:
180 self.assert_qmp(result, 'return[0]/tray_open', False)
181 self.assert_qmp_absent(result, 'return[0]/inserted')
182
183 def test_tray_open_change(self):
184 result = self.vm.qmp('blockdev-open-tray', id=self.device_name,
185 force=True)
186 self.assert_qmp(result, 'return', {})
187
188 self.wait_for_open()
189
190 result = self.vm.qmp('query-block')
191 if self.has_real_tray:
192 self.assert_qmp(result, 'return[0]/tray_open', True)
193 if self.was_empty == True:
194 self.assert_qmp_absent(result, 'return[0]/inserted')
195 else:
196 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
197
198 result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
199 filename=new_img,
200 format=iotests.imgfmt)
201 self.assert_qmp(result, 'return', {})
202
203 self.wait_for_close()
204
205 result = self.vm.qmp('query-block')
206 if self.has_real_tray:
207 self.assert_qmp(result, 'return[0]/tray_open', False)
208 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
209
210 def test_cycle(self):
211 result = self.vm.qmp('blockdev-add',
212 node_name='new',
213 driver=iotests.imgfmt,
214 file={'filename': new_img,
215 'driver': 'file'})
216 self.assert_qmp(result, 'return', {})
217
218 result = self.vm.qmp('blockdev-open-tray',
219 id=self.device_name, force=True)
220 self.assert_qmp(result, 'return', {})
221
222 self.wait_for_open()
223
224 result = self.vm.qmp('query-block')
225 if self.has_real_tray:
226 self.assert_qmp(result, 'return[0]/tray_open', True)
227 if self.was_empty == True:
228 self.assert_qmp_absent(result, 'return[0]/inserted')
229 else:
230 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
231
232 result = self.vm.qmp('blockdev-remove-medium',
233 id=self.device_name)
234 self.assert_qmp(result, 'return', {})
235
236 result = self.vm.qmp('query-block')
237 if self.has_real_tray:
238 self.assert_qmp(result, 'return[0]/tray_open', True)
239 self.assert_qmp_absent(result, 'return[0]/inserted')
240
241 result = self.vm.qmp('blockdev-insert-medium',
242 id=self.device_name, node_name='new')
243 self.assert_qmp(result, 'return', {})
244
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(result, 'return[0]/inserted/image/filename', new_img)
249
250 result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
251 self.assert_qmp(result, 'return', {})
252
253 self.wait_for_close()
254
255 result = self.vm.qmp('query-block')
256 if self.has_real_tray:
257 self.assert_qmp(result, 'return[0]/tray_open', False)
258 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
259
260 def test_close_on_closed(self):
261 result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
262 # Should be a no-op
263 self.assert_qmp(result, 'return', {})
264 self.assertEqual(self.vm.get_qmp_events(wait=False), [])
265
266 def test_remove_on_closed(self):
267 if not self.has_real_tray:
268 return
269
270 result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
271 self.assert_qmp(result, 'error/class', 'GenericError')
272
273 def test_insert_on_closed(self):
274 if not self.has_real_tray:
275 return
276
277 result = self.vm.qmp('blockdev-add',
278 node_name='new',
279 driver=iotests.imgfmt,
280 file={'filename': new_img,
281 'driver': 'file'})
282 self.assert_qmp(result, 'return', {})
283
284 result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
285 node_name='new')
286 self.assert_qmp(result, 'error/class', 'GenericError')
287
288 class TestInitiallyFilled(GeneralChangeTestsBaseClass):
289 was_empty = False
290
291 def setUp(self, media, interface):
292 qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
293 qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
294 self.vm = iotests.VM()
295 self.vm.add_drive(old_img, 'media=%s' % media, 'none')
296 self.vm.add_device('%s,drive=drive0,id=%s' %
297 (interface_to_device_name(interface),
298 self.device_name))
299 self.vm.launch()
300
301 def tearDown(self):
302 self.vm.shutdown()
303 os.remove(old_img)
304 os.remove(new_img)
305
306 def test_insert_on_filled(self):
307 result = self.vm.qmp('blockdev-add',
308 node_name='new',
309 driver=iotests.imgfmt,
310 file={'filename': new_img,
311 'driver': 'file'})
312 self.assert_qmp(result, 'return', {})
313
314 result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
315 self.assert_qmp(result, 'return', {})
316
317 self.wait_for_open()
318
319 result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
320 node_name='new')
321 self.assert_qmp(result, 'error/class', 'GenericError')
322
323 class TestInitiallyEmpty(GeneralChangeTestsBaseClass):
324 was_empty = True
325
326 def setUp(self, media, interface):
327 qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
328 self.vm = iotests.VM().add_drive(None, 'media=%s' % media, 'none')
329 self.vm.add_device('%s,drive=drive0,id=%s' %
330 (interface_to_device_name(interface),
331 self.device_name))
332 self.vm.launch()
333
334 def tearDown(self):
335 self.vm.shutdown()
336 os.remove(new_img)
337
338 def test_remove_on_empty(self):
339 result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
340 self.assert_qmp(result, 'return', {})
341
342 self.wait_for_open()
343
344 result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
345 # Should be a no-op
346 self.assert_qmp(result, 'return', {})
347
348 class TestCDInitiallyFilled(TestInitiallyFilled):
349 TestInitiallyFilled = TestInitiallyFilled
350 has_real_tray = True
351
352 def setUp(self):
353 self.TestInitiallyFilled.setUp(self, 'cdrom', 'ide')
354
355 class TestCDInitiallyEmpty(TestInitiallyEmpty):
356 TestInitiallyEmpty = TestInitiallyEmpty
357 has_real_tray = True
358
359 def setUp(self):
360 self.TestInitiallyEmpty.setUp(self, 'cdrom', 'ide')
361
362 class TestFloppyInitiallyFilled(TestInitiallyFilled):
363 TestInitiallyFilled = TestInitiallyFilled
364 has_real_tray = False
365
366 def setUp(self):
367 self.TestInitiallyFilled.setUp(self, 'disk', 'floppy')
368
369 class TestFloppyInitiallyEmpty(TestInitiallyEmpty):
370 TestInitiallyEmpty = TestInitiallyEmpty
371 has_real_tray = False
372
373 def setUp(self):
374 self.TestInitiallyEmpty.setUp(self, 'disk', 'floppy')
375 # FDDs not having a real tray and there not being a medium inside the
376 # tray at startup means the tray will be considered open
377 self.has_opened = True
378
379 class TestChangeReadOnly(ChangeBaseClass):
380 device_name = 'qdev0'
381
382 def setUp(self):
383 qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
384 qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
385 self.vm = iotests.VM()
386
387 def tearDown(self):
388 self.vm.shutdown()
389 os.chmod(old_img, 0o666)
390 os.chmod(new_img, 0o666)
391 os.remove(old_img)
392 os.remove(new_img)
393
394 def test_ro_ro_retain(self):
395 os.chmod(old_img, 0o444)
396 os.chmod(new_img, 0o444)
397 self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
398 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
399 self.vm.launch()
400
401 result = self.vm.qmp('query-block')
402 self.assert_qmp(result, 'return[0]/inserted/ro', True)
403 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
404
405 result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
406 filename=new_img,
407 format=iotests.imgfmt,
408 read_only_mode='retain')
409 self.assert_qmp(result, 'return', {})
410
411 result = self.vm.qmp('query-block')
412 self.assert_qmp(result, 'return[0]/inserted/ro', True)
413 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
414
415 def test_ro_rw_retain(self):
416 os.chmod(old_img, 0o444)
417 self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
418 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
419 self.vm.launch()
420
421 result = self.vm.qmp('query-block')
422 self.assert_qmp(result, 'return[0]/inserted/ro', True)
423 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
424
425 result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
426 filename=new_img,
427 format=iotests.imgfmt,
428 read_only_mode='retain')
429 self.assert_qmp(result, 'return', {})
430
431 result = self.vm.qmp('query-block')
432 self.assert_qmp(result, 'return[0]/inserted/ro', True)
433 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
434
435 def test_rw_ro_retain(self):
436 os.chmod(new_img, 0o444)
437 self.vm.add_drive(old_img, 'media=disk', 'none')
438 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
439 self.vm.launch()
440
441 result = self.vm.qmp('query-block')
442 self.assert_qmp(result, 'return[0]/inserted/ro', False)
443 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
444
445 result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
446 filename=new_img,
447 format=iotests.imgfmt,
448 read_only_mode='retain')
449 self.assert_qmp(result, 'error/class', 'GenericError')
450
451 self.assertEqual(self.vm.get_qmp_events(wait=False), [])
452
453 result = self.vm.qmp('query-block')
454 self.assert_qmp(result, 'return[0]/inserted/ro', False)
455 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
456
457 def test_ro_rw(self):
458 os.chmod(old_img, 0o444)
459 self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
460 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
461 self.vm.launch()
462
463 result = self.vm.qmp('query-block')
464 self.assert_qmp(result, 'return[0]/inserted/ro', True)
465 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
466
467 result = self.vm.qmp('blockdev-change-medium',
468 id=self.device_name,
469 filename=new_img,
470 format=iotests.imgfmt,
471 read_only_mode='read-write')
472 self.assert_qmp(result, 'return', {})
473
474 result = self.vm.qmp('query-block')
475 self.assert_qmp(result, 'return[0]/inserted/ro', False)
476 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
477
478 def test_rw_ro(self):
479 os.chmod(new_img, 0o444)
480 self.vm.add_drive(old_img, 'media=disk', 'none')
481 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
482 self.vm.launch()
483
484 result = self.vm.qmp('query-block')
485 self.assert_qmp(result, 'return[0]/inserted/ro', False)
486 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
487
488 result = self.vm.qmp('blockdev-change-medium',
489 id=self.device_name,
490 filename=new_img,
491 format=iotests.imgfmt,
492 read_only_mode='read-only')
493 self.assert_qmp(result, 'return', {})
494
495 result = self.vm.qmp('query-block')
496 self.assert_qmp(result, 'return[0]/inserted/ro', True)
497 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
498
499 def test_make_rw_ro(self):
500 self.vm.add_drive(old_img, 'media=disk', 'none')
501 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
502 self.vm.launch()
503
504 result = self.vm.qmp('query-block')
505 self.assert_qmp(result, 'return[0]/inserted/ro', False)
506 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
507
508 result = self.vm.qmp('blockdev-change-medium',
509 id=self.device_name,
510 filename=new_img,
511 format=iotests.imgfmt,
512 read_only_mode='read-only')
513 self.assert_qmp(result, 'return', {})
514
515 result = self.vm.qmp('query-block')
516 self.assert_qmp(result, 'return[0]/inserted/ro', True)
517 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
518
519 def test_make_ro_rw(self):
520 os.chmod(new_img, 0o444)
521 self.vm.add_drive(old_img, 'media=disk', 'none')
522 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
523 self.vm.launch()
524
525 result = self.vm.qmp('query-block')
526 self.assert_qmp(result, 'return[0]/inserted/ro', False)
527 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
528
529 result = self.vm.qmp('blockdev-change-medium',
530 id=self.device_name,
531 filename=new_img,
532 format=iotests.imgfmt,
533 read_only_mode='read-write')
534 self.assert_qmp(result, 'error/class', 'GenericError')
535
536 result = self.vm.qmp('query-block')
537 self.assert_qmp(result, 'return[0]/inserted/ro', False)
538 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
539
540 def test_make_rw_ro_by_retain(self):
541 os.chmod(old_img, 0o444)
542 self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
543 self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
544 self.vm.launch()
545
546 result = self.vm.qmp('query-block')
547 self.assert_qmp(result, 'return[0]/inserted/ro', True)
548 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
549
550 result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
551 filename=new_img,
552 format=iotests.imgfmt,
553 read_only_mode='retain')
554 self.assert_qmp(result, 'return', {})
555
556 result = self.vm.qmp('query-block')
557 self.assert_qmp(result, 'return[0]/inserted/ro', True)
558 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
559
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()
565
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)
569
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')
575
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)
579
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()
585
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)
589
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', {})
597
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)
601
602 result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
603 self.assert_qmp(result, 'return', {})
604
605 result = self.vm.qmp('query-block')
606 self.assert_qmp_absent(result, 'return[0]/inserted')
607
608 result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
609 node_name='new')
610 self.assert_qmp(result, 'return', {})
611
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)
615
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)
619
620 GeneralChangeTestsBaseClass = None
621 TestInitiallyFilled = None
622 TestInitiallyEmpty = None
623
624
625 class TestBlockJobsAfterCycle(ChangeBaseClass):
626 device_name = 'qdev0'
627
628 def setUp(self):
629 qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K')
630
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()
635
636 result = self.vm.qmp('query-block')
637 self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co')
638
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', {})
643
644 result = self.vm.qmp('query-block')
645 self.assert_qmp_absent(result, 'return[0]/inserted')
646
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', {})
653
654 result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
655 node_name='node0')
656 self.assert_qmp(result, 'return', {})
657
658 result = self.vm.qmp('query-block')
659 self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
660
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
668
669 def test_snapshot_and_commit(self):
670 # We need backing file support
671 if iotests.imgfmt != 'qcow2' and iotests.imgfmt != 'qed':
672 return
673
674 result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
675 snapshot_file=new_img,
676 format=iotests.imgfmt)
677 self.assert_qmp(result, 'return', {})
678
679 result = self.vm.qmp('query-block')
680 self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
681 self.assert_qmp(result,
682 'return[0]/inserted/image/backing-image/filename',
683 old_img)
684
685 result = self.vm.qmp('block-commit', device='drive0')
686 self.assert_qmp(result, 'return', {})
687
688 self.vm.event_wait(name='BLOCK_JOB_READY')
689
690 result = self.vm.qmp('query-block-jobs')
691 self.assert_qmp(result, 'return[0]/device', 'drive0')
692
693 result = self.vm.qmp('block-job-complete', device='drive0')
694 self.assert_qmp(result, 'return', {})
695
696 self.vm.event_wait(name='BLOCK_JOB_COMPLETED')
697
698
699 if __name__ == '__main__':
700 if iotests.qemu_default_machine != 'pc':
701 # We need floppy and IDE CD-ROM
702 iotests.notrun('not suitable for this machine type: %s' %
703 iotests.qemu_default_machine)
704 # Need to support image creation
705 iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
706 'vmdk', 'raw', 'vhdx', 'qed'])