qemu-iotests: make create_image() common
[qemu/ar7.git] / tests / qemu-iotests / 041
blob1e923e70caa085ac0a4a145936f44aa77bb6e9e1
1 #!/usr/bin/env python
3 # Tests for image mirroring.
5 # Copyright (C) 2012 Red Hat, Inc.
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 import time
22 import os
23 import iotests
24 from iotests import qemu_img, qemu_io
26 backing_img = os.path.join(iotests.test_dir, 'backing.img')
27 target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img')
28 test_img = os.path.join(iotests.test_dir, 'test.img')
29 target_img = os.path.join(iotests.test_dir, 'target.img')
31 class ImageMirroringTestCase(iotests.QMPTestCase):
32 '''Abstract base class for image mirroring test cases'''
34 def wait_ready(self, drive='drive0'):
35 '''Wait until a block job BLOCK_JOB_READY event'''
36 ready = False
37 while not ready:
38 for event in self.vm.get_qmp_events(wait=True):
39 if event['event'] == 'BLOCK_JOB_READY':
40 self.assert_qmp(event, 'data/type', 'mirror')
41 self.assert_qmp(event, 'data/device', drive)
42 ready = True
44 def wait_ready_and_cancel(self, drive='drive0'):
45 self.wait_ready(drive)
46 event = self.cancel_and_wait()
47 self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED')
48 self.assert_qmp(event, 'data/type', 'mirror')
49 self.assert_qmp(event, 'data/offset', self.image_len)
50 self.assert_qmp(event, 'data/len', self.image_len)
52 def complete_and_wait(self, drive='drive0', wait_ready=True):
53 '''Complete a block job and wait for it to finish'''
54 if wait_ready:
55 self.wait_ready()
57 result = self.vm.qmp('block-job-complete', device=drive)
58 self.assert_qmp(result, 'return', {})
60 completed = False
61 while not completed:
62 for event in self.vm.get_qmp_events(wait=True):
63 if event['event'] == 'BLOCK_JOB_COMPLETED':
64 self.assert_qmp(event, 'data/type', 'mirror')
65 self.assert_qmp(event, 'data/device', drive)
66 self.assert_qmp_absent(event, 'data/error')
67 self.assert_qmp(event, 'data/offset', self.image_len)
68 self.assert_qmp(event, 'data/len', self.image_len)
69 completed = True
71 self.assert_no_active_block_jobs()
73 class TestSingleDrive(ImageMirroringTestCase):
74 image_len = 1 * 1024 * 1024 # MB
76 def setUp(self):
77 iotests.create_image(backing_img, TestSingleDrive.image_len)
78 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
79 self.vm = iotests.VM().add_drive(test_img)
80 self.vm.launch()
82 def tearDown(self):
83 self.vm.shutdown()
84 os.remove(test_img)
85 os.remove(backing_img)
86 try:
87 os.remove(target_img)
88 except OSError:
89 pass
91 def test_complete(self):
92 self.assert_no_active_block_jobs()
94 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
95 target=target_img)
96 self.assert_qmp(result, 'return', {})
98 self.complete_and_wait()
99 result = self.vm.qmp('query-block')
100 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
101 self.vm.shutdown()
102 self.assertTrue(iotests.compare_images(test_img, target_img),
103 'target image does not match source after mirroring')
105 def test_cancel(self):
106 self.assert_no_active_block_jobs()
108 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
109 target=target_img)
110 self.assert_qmp(result, 'return', {})
112 self.cancel_and_wait(force=True)
113 result = self.vm.qmp('query-block')
114 self.assert_qmp(result, 'return[0]/inserted/file', test_img)
115 self.vm.shutdown()
117 def test_cancel_after_ready(self):
118 self.assert_no_active_block_jobs()
120 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
121 target=target_img)
122 self.assert_qmp(result, 'return', {})
124 self.wait_ready_and_cancel()
125 result = self.vm.qmp('query-block')
126 self.assert_qmp(result, 'return[0]/inserted/file', test_img)
127 self.vm.shutdown()
128 self.assertTrue(iotests.compare_images(test_img, target_img),
129 'target image does not match source after mirroring')
131 def test_pause(self):
132 self.assert_no_active_block_jobs()
134 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
135 target=target_img)
136 self.assert_qmp(result, 'return', {})
138 result = self.vm.qmp('block-job-pause', device='drive0')
139 self.assert_qmp(result, 'return', {})
141 time.sleep(1)
142 result = self.vm.qmp('query-block-jobs')
143 offset = self.dictpath(result, 'return[0]/offset')
145 time.sleep(1)
146 result = self.vm.qmp('query-block-jobs')
147 self.assert_qmp(result, 'return[0]/offset', offset)
149 result = self.vm.qmp('block-job-resume', device='drive0')
150 self.assert_qmp(result, 'return', {})
152 self.complete_and_wait()
153 self.vm.shutdown()
154 self.assertTrue(iotests.compare_images(test_img, target_img),
155 'target image does not match source after mirroring')
157 def test_small_buffer(self):
158 self.assert_no_active_block_jobs()
160 # A small buffer is rounded up automatically
161 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
162 buf_size=4096, target=target_img)
163 self.assert_qmp(result, 'return', {})
165 self.complete_and_wait()
166 result = self.vm.qmp('query-block')
167 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
168 self.vm.shutdown()
169 self.assertTrue(iotests.compare_images(test_img, target_img),
170 'target image does not match source after mirroring')
172 def test_small_buffer2(self):
173 self.assert_no_active_block_jobs()
175 qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,size=%d'
176 % (TestSingleDrive.image_len, TestSingleDrive.image_len), target_img)
177 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
178 buf_size=65536, mode='existing', target=target_img)
179 self.assert_qmp(result, 'return', {})
181 self.complete_and_wait()
182 result = self.vm.qmp('query-block')
183 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
184 self.vm.shutdown()
185 self.assertTrue(iotests.compare_images(test_img, target_img),
186 'target image does not match source after mirroring')
188 def test_large_cluster(self):
189 self.assert_no_active_block_jobs()
191 qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
192 % (TestSingleDrive.image_len, backing_img), target_img)
193 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
194 mode='existing', target=target_img)
195 self.assert_qmp(result, 'return', {})
197 self.complete_and_wait()
198 result = self.vm.qmp('query-block')
199 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
200 self.vm.shutdown()
201 self.assertTrue(iotests.compare_images(test_img, target_img),
202 'target image does not match source after mirroring')
204 def test_medium_not_found(self):
205 result = self.vm.qmp('drive-mirror', device='ide1-cd0', sync='full',
206 target=target_img)
207 self.assert_qmp(result, 'error/class', 'GenericError')
209 def test_image_not_found(self):
210 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
211 mode='existing', target=target_img)
212 self.assert_qmp(result, 'error/class', 'GenericError')
214 def test_device_not_found(self):
215 result = self.vm.qmp('drive-mirror', device='nonexistent', sync='full',
216 target=target_img)
217 self.assert_qmp(result, 'error/class', 'DeviceNotFound')
219 class TestMirrorNoBacking(ImageMirroringTestCase):
220 image_len = 2 * 1024 * 1024 # MB
222 def complete_and_wait(self, drive='drive0', wait_ready=True):
223 iotests.create_image(target_backing_img, TestMirrorNoBacking.image_len)
224 return ImageMirroringTestCase.complete_and_wait(self, drive, wait_ready)
226 def compare_images(self, img1, img2):
227 iotests.create_image(target_backing_img, TestMirrorNoBacking.image_len)
228 return iotests.compare_images(img1, img2)
230 def setUp(self):
231 iotests.create_image(backing_img, TestMirrorNoBacking.image_len)
232 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
233 self.vm = iotests.VM().add_drive(test_img)
234 self.vm.launch()
236 def tearDown(self):
237 self.vm.shutdown()
238 os.remove(test_img)
239 os.remove(backing_img)
240 os.remove(target_backing_img)
241 os.remove(target_img)
243 def test_complete(self):
244 self.assert_no_active_block_jobs()
246 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
247 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
248 mode='existing', target=target_img)
249 self.assert_qmp(result, 'return', {})
251 self.complete_and_wait()
252 result = self.vm.qmp('query-block')
253 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
254 self.vm.shutdown()
255 self.assertTrue(self.compare_images(test_img, target_img),
256 'target image does not match source after mirroring')
258 def test_cancel(self):
259 self.assert_no_active_block_jobs()
261 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img)
262 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
263 mode='existing', target=target_img)
264 self.assert_qmp(result, 'return', {})
266 self.wait_ready_and_cancel()
267 result = self.vm.qmp('query-block')
268 self.assert_qmp(result, 'return[0]/inserted/file', test_img)
269 self.vm.shutdown()
270 self.assertTrue(self.compare_images(test_img, target_img),
271 'target image does not match source after mirroring')
273 def test_large_cluster(self):
274 self.assert_no_active_block_jobs()
276 # qemu-img create fails if the image is not there
277 qemu_img('create', '-f', iotests.imgfmt, '-o', 'size=%d'
278 %(TestMirrorNoBacking.image_len), target_backing_img)
279 qemu_img('create', '-f', iotests.imgfmt, '-o', 'cluster_size=%d,backing_file=%s'
280 % (TestMirrorNoBacking.image_len, target_backing_img), target_img)
281 os.remove(target_backing_img)
283 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
284 mode='existing', target=target_img)
285 self.assert_qmp(result, 'return', {})
287 self.complete_and_wait()
288 result = self.vm.qmp('query-block')
289 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
290 self.vm.shutdown()
291 self.assertTrue(self.compare_images(test_img, target_img),
292 'target image does not match source after mirroring')
294 class TestMirrorResized(ImageMirroringTestCase):
295 backing_len = 1 * 1024 * 1024 # MB
296 image_len = 2 * 1024 * 1024 # MB
298 def setUp(self):
299 iotests.create_image(backing_img, TestMirrorResized.backing_len)
300 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
301 qemu_img('resize', test_img, '2M')
302 self.vm = iotests.VM().add_drive(test_img)
303 self.vm.launch()
305 def tearDown(self):
306 self.vm.shutdown()
307 os.remove(test_img)
308 os.remove(backing_img)
309 try:
310 os.remove(target_img)
311 except OSError:
312 pass
314 def test_complete_top(self):
315 self.assert_no_active_block_jobs()
317 result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
318 target=target_img)
319 self.assert_qmp(result, 'return', {})
321 self.complete_and_wait()
322 result = self.vm.qmp('query-block')
323 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
324 self.vm.shutdown()
325 self.assertTrue(iotests.compare_images(test_img, target_img),
326 'target image does not match source after mirroring')
328 def test_complete_full(self):
329 self.assert_no_active_block_jobs()
331 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
332 target=target_img)
333 self.assert_qmp(result, 'return', {})
335 self.complete_and_wait()
336 result = self.vm.qmp('query-block')
337 self.assert_qmp(result, 'return[0]/inserted/file', target_img)
338 self.vm.shutdown()
339 self.assertTrue(iotests.compare_images(test_img, target_img),
340 'target image does not match source after mirroring')
342 class TestReadErrors(ImageMirroringTestCase):
343 image_len = 2 * 1024 * 1024 # MB
345 # this should be a multiple of twice the default granularity
346 # so that we hit this offset first in state 1
347 MIRROR_GRANULARITY = 1024 * 1024
349 def create_blkdebug_file(self, name, event, errno):
350 file = open(name, 'w')
351 file.write('''
352 [inject-error]
353 state = "1"
354 event = "%s"
355 errno = "%d"
356 immediately = "off"
357 once = "on"
358 sector = "%d"
360 [set-state]
361 state = "1"
362 event = "%s"
363 new_state = "2"
365 [set-state]
366 state = "2"
367 event = "%s"
368 new_state = "1"
369 ''' % (event, errno, self.MIRROR_GRANULARITY / 512, event, event))
370 file.close()
372 def setUp(self):
373 self.blkdebug_file = backing_img + ".blkdebug"
374 iotests.create_image(backing_img, TestReadErrors.image_len)
375 self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5)
376 qemu_img('create', '-f', iotests.imgfmt,
377 '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw'
378 % (self.blkdebug_file, backing_img),
379 test_img)
380 # Write something for tests that use sync='top'
381 qemu_io('-c', 'write %d 512' % (self.MIRROR_GRANULARITY + 65536),
382 test_img)
383 self.vm = iotests.VM().add_drive(test_img)
384 self.vm.launch()
386 def tearDown(self):
387 self.vm.shutdown()
388 os.remove(test_img)
389 os.remove(backing_img)
390 os.remove(self.blkdebug_file)
392 def test_report_read(self):
393 self.assert_no_active_block_jobs()
395 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
396 target=target_img)
397 self.assert_qmp(result, 'return', {})
399 completed = False
400 error = False
401 while not completed:
402 for event in self.vm.get_qmp_events(wait=True):
403 if event['event'] == 'BLOCK_JOB_ERROR':
404 self.assert_qmp(event, 'data/device', 'drive0')
405 self.assert_qmp(event, 'data/operation', 'read')
406 error = True
407 elif event['event'] == 'BLOCK_JOB_READY':
408 self.assertTrue(False, 'job completed unexpectedly')
409 elif event['event'] == 'BLOCK_JOB_COMPLETED':
410 self.assertTrue(error, 'job completed unexpectedly')
411 self.assert_qmp(event, 'data/type', 'mirror')
412 self.assert_qmp(event, 'data/device', 'drive0')
413 self.assert_qmp(event, 'data/error', 'Input/output error')
414 self.assert_qmp(event, 'data/len', self.image_len)
415 completed = True
417 self.assert_no_active_block_jobs()
418 self.vm.shutdown()
420 def test_ignore_read(self):
421 self.assert_no_active_block_jobs()
423 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
424 target=target_img, on_source_error='ignore')
425 self.assert_qmp(result, 'return', {})
427 event = self.vm.get_qmp_event(wait=True)
428 self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
429 self.assert_qmp(event, 'data/device', 'drive0')
430 self.assert_qmp(event, 'data/operation', 'read')
431 result = self.vm.qmp('query-block-jobs')
432 self.assert_qmp(result, 'return[0]/paused', False)
433 self.complete_and_wait()
434 self.vm.shutdown()
436 def test_large_cluster(self):
437 self.assert_no_active_block_jobs()
439 # Test COW into the target image. The first half of the
440 # cluster at MIRROR_GRANULARITY has to be copied from
441 # backing_img, even though sync='top'.
442 qemu_img('create', '-f', iotests.imgfmt, '-ocluster_size=131072,backing_file=%s' %(backing_img), target_img)
443 result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
444 on_source_error='ignore',
445 mode='existing', target=target_img)
446 self.assert_qmp(result, 'return', {})
448 event = self.vm.get_qmp_event(wait=True)
449 self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
450 self.assert_qmp(event, 'data/device', 'drive0')
451 self.assert_qmp(event, 'data/operation', 'read')
452 result = self.vm.qmp('query-block-jobs')
453 self.assert_qmp(result, 'return[0]/paused', False)
454 self.complete_and_wait()
455 self.vm.shutdown()
457 # Detach blkdebug to compare images successfully
458 qemu_img('rebase', '-f', iotests.imgfmt, '-u', '-b', backing_img, test_img)
459 self.assertTrue(iotests.compare_images(test_img, target_img),
460 'target image does not match source after mirroring')
462 def test_stop_read(self):
463 self.assert_no_active_block_jobs()
465 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
466 target=target_img, on_source_error='stop')
467 self.assert_qmp(result, 'return', {})
469 error = False
470 ready = False
471 while not ready:
472 for event in self.vm.get_qmp_events(wait=True):
473 if event['event'] == 'BLOCK_JOB_ERROR':
474 self.assert_qmp(event, 'data/device', 'drive0')
475 self.assert_qmp(event, 'data/operation', 'read')
477 result = self.vm.qmp('query-block-jobs')
478 self.assert_qmp(result, 'return[0]/paused', True)
479 self.assert_qmp(result, 'return[0]/io-status', 'failed')
481 result = self.vm.qmp('block-job-resume', device='drive0')
482 self.assert_qmp(result, 'return', {})
483 error = True
484 elif event['event'] == 'BLOCK_JOB_READY':
485 self.assertTrue(error, 'job completed unexpectedly')
486 self.assert_qmp(event, 'data/device', 'drive0')
487 ready = True
489 result = self.vm.qmp('query-block-jobs')
490 self.assert_qmp(result, 'return[0]/paused', False)
491 self.assert_qmp(result, 'return[0]/io-status', 'ok')
493 self.complete_and_wait(wait_ready=False)
494 self.assert_no_active_block_jobs()
495 self.vm.shutdown()
497 class TestWriteErrors(ImageMirroringTestCase):
498 image_len = 2 * 1024 * 1024 # MB
500 # this should be a multiple of twice the default granularity
501 # so that we hit this offset first in state 1
502 MIRROR_GRANULARITY = 1024 * 1024
504 def create_blkdebug_file(self, name, event, errno):
505 file = open(name, 'w')
506 file.write('''
507 [inject-error]
508 state = "1"
509 event = "%s"
510 errno = "%d"
511 immediately = "off"
512 once = "on"
513 sector = "%d"
515 [set-state]
516 state = "1"
517 event = "%s"
518 new_state = "2"
520 [set-state]
521 state = "2"
522 event = "%s"
523 new_state = "1"
524 ''' % (event, errno, self.MIRROR_GRANULARITY / 512, event, event))
525 file.close()
527 def setUp(self):
528 self.blkdebug_file = target_img + ".blkdebug"
529 iotests.create_image(backing_img, TestWriteErrors.image_len)
530 self.create_blkdebug_file(self.blkdebug_file, "write_aio", 5)
531 qemu_img('create', '-f', iotests.imgfmt, '-obacking_file=%s' %(backing_img), test_img)
532 self.vm = iotests.VM().add_drive(test_img)
533 self.target_img = 'blkdebug:%s:%s' % (self.blkdebug_file, target_img)
534 qemu_img('create', '-f', iotests.imgfmt, '-osize=%d' %(TestWriteErrors.image_len), target_img)
535 self.vm.launch()
537 def tearDown(self):
538 self.vm.shutdown()
539 os.remove(test_img)
540 os.remove(backing_img)
541 os.remove(self.blkdebug_file)
543 def test_report_write(self):
544 self.assert_no_active_block_jobs()
546 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
547 mode='existing', target=self.target_img)
548 self.assert_qmp(result, 'return', {})
550 completed = False
551 error = False
552 while not completed:
553 for event in self.vm.get_qmp_events(wait=True):
554 if event['event'] == 'BLOCK_JOB_ERROR':
555 self.assert_qmp(event, 'data/device', 'drive0')
556 self.assert_qmp(event, 'data/operation', 'write')
557 error = True
558 elif event['event'] == 'BLOCK_JOB_READY':
559 self.assertTrue(False, 'job completed unexpectedly')
560 elif event['event'] == 'BLOCK_JOB_COMPLETED':
561 self.assertTrue(error, 'job completed unexpectedly')
562 self.assert_qmp(event, 'data/type', 'mirror')
563 self.assert_qmp(event, 'data/device', 'drive0')
564 self.assert_qmp(event, 'data/error', 'Input/output error')
565 self.assert_qmp(event, 'data/len', self.image_len)
566 completed = True
568 self.assert_no_active_block_jobs()
569 self.vm.shutdown()
571 def test_ignore_write(self):
572 self.assert_no_active_block_jobs()
574 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
575 mode='existing', target=self.target_img,
576 on_target_error='ignore')
577 self.assert_qmp(result, 'return', {})
579 event = self.vm.get_qmp_event(wait=True)
580 self.assertEquals(event['event'], 'BLOCK_JOB_ERROR')
581 self.assert_qmp(event, 'data/device', 'drive0')
582 self.assert_qmp(event, 'data/operation', 'write')
583 result = self.vm.qmp('query-block-jobs')
584 self.assert_qmp(result, 'return[0]/paused', False)
585 self.complete_and_wait()
586 self.vm.shutdown()
588 def test_stop_write(self):
589 self.assert_no_active_block_jobs()
591 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
592 mode='existing', target=self.target_img,
593 on_target_error='stop')
594 self.assert_qmp(result, 'return', {})
596 error = False
597 ready = False
598 while not ready:
599 for event in self.vm.get_qmp_events(wait=True):
600 if event['event'] == 'BLOCK_JOB_ERROR':
601 self.assert_qmp(event, 'data/device', 'drive0')
602 self.assert_qmp(event, 'data/operation', 'write')
604 result = self.vm.qmp('query-block-jobs')
605 self.assert_qmp(result, 'return[0]/paused', True)
606 self.assert_qmp(result, 'return[0]/io-status', 'failed')
608 result = self.vm.qmp('block-job-resume', device='drive0')
609 self.assert_qmp(result, 'return', {})
611 result = self.vm.qmp('query-block-jobs')
612 self.assert_qmp(result, 'return[0]/paused', False)
613 self.assert_qmp(result, 'return[0]/io-status', 'ok')
614 error = True
615 elif event['event'] == 'BLOCK_JOB_READY':
616 self.assertTrue(error, 'job completed unexpectedly')
617 self.assert_qmp(event, 'data/device', 'drive0')
618 ready = True
620 self.complete_and_wait(wait_ready=False)
621 self.assert_no_active_block_jobs()
622 self.vm.shutdown()
624 class TestSetSpeed(ImageMirroringTestCase):
625 image_len = 80 * 1024 * 1024 # MB
627 def setUp(self):
628 qemu_img('create', backing_img, str(TestSetSpeed.image_len))
629 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
630 self.vm = iotests.VM().add_drive(test_img)
631 self.vm.launch()
633 def tearDown(self):
634 self.vm.shutdown()
635 os.remove(test_img)
636 os.remove(backing_img)
637 os.remove(target_img)
639 def test_set_speed(self):
640 self.assert_no_active_block_jobs()
642 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
643 target=target_img)
644 self.assert_qmp(result, 'return', {})
646 # Default speed is 0
647 result = self.vm.qmp('query-block-jobs')
648 self.assert_qmp(result, 'return[0]/device', 'drive0')
649 self.assert_qmp(result, 'return[0]/speed', 0)
651 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
652 self.assert_qmp(result, 'return', {})
654 # Ensure the speed we set was accepted
655 result = self.vm.qmp('query-block-jobs')
656 self.assert_qmp(result, 'return[0]/device', 'drive0')
657 self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
659 self.wait_ready_and_cancel()
661 # Check setting speed in drive-mirror works
662 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
663 target=target_img, speed=4*1024*1024)
664 self.assert_qmp(result, 'return', {})
666 result = self.vm.qmp('query-block-jobs')
667 self.assert_qmp(result, 'return[0]/device', 'drive0')
668 self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
670 self.wait_ready_and_cancel()
672 def test_set_speed_invalid(self):
673 self.assert_no_active_block_jobs()
675 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
676 target=target_img, speed=-1)
677 self.assert_qmp(result, 'error/class', 'GenericError')
679 self.assert_no_active_block_jobs()
681 result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
682 target=target_img)
683 self.assert_qmp(result, 'return', {})
685 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
686 self.assert_qmp(result, 'error/class', 'GenericError')
688 self.wait_ready_and_cancel()
690 if __name__ == '__main__':
691 iotests.main(supported_fmts=['qcow2', 'qed'])