]> Git Repo - qemu.git/blob - tests/qemu-iotests/041
qemu-iotests: make create_image() common
[qemu.git] / tests / qemu-iotests / 041
1 #!/usr/bin/env python
2 #
3 # Tests for image mirroring.
4 #
5 # Copyright (C) 2012 Red Hat, Inc.
6 #
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.
11 #
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.
16 #
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/>.
19 #
20
21 import time
22 import os
23 import iotests
24 from iotests import qemu_img, qemu_io
25
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')
30
31 class ImageMirroringTestCase(iotests.QMPTestCase):
32     '''Abstract base class for image mirroring test cases'''
33
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
43
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)
51
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()
56
57         result = self.vm.qmp('block-job-complete', device=drive)
58         self.assert_qmp(result, 'return', {})
59
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
70
71         self.assert_no_active_block_jobs()
72
73 class TestSingleDrive(ImageMirroringTestCase):
74     image_len = 1 * 1024 * 1024 # MB
75
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()
81
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
90
91     def test_complete(self):
92         self.assert_no_active_block_jobs()
93
94         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
95                              target=target_img)
96         self.assert_qmp(result, 'return', {})
97
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')
104
105     def test_cancel(self):
106         self.assert_no_active_block_jobs()
107
108         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
109                              target=target_img)
110         self.assert_qmp(result, 'return', {})
111
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()
116
117     def test_cancel_after_ready(self):
118         self.assert_no_active_block_jobs()
119
120         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
121                              target=target_img)
122         self.assert_qmp(result, 'return', {})
123
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')
130
131     def test_pause(self):
132         self.assert_no_active_block_jobs()
133
134         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
135                              target=target_img)
136         self.assert_qmp(result, 'return', {})
137
138         result = self.vm.qmp('block-job-pause', device='drive0')
139         self.assert_qmp(result, 'return', {})
140
141         time.sleep(1)
142         result = self.vm.qmp('query-block-jobs')
143         offset = self.dictpath(result, 'return[0]/offset')
144
145         time.sleep(1)
146         result = self.vm.qmp('query-block-jobs')
147         self.assert_qmp(result, 'return[0]/offset', offset)
148
149         result = self.vm.qmp('block-job-resume', device='drive0')
150         self.assert_qmp(result, 'return', {})
151
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')
156
157     def test_small_buffer(self):
158         self.assert_no_active_block_jobs()
159
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', {})
164
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')
171
172     def test_small_buffer2(self):
173         self.assert_no_active_block_jobs()
174
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', {})
180
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')
187
188     def test_large_cluster(self):
189         self.assert_no_active_block_jobs()
190
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', {})
196
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')
203
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')
208
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')
213
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')
218
219 class TestMirrorNoBacking(ImageMirroringTestCase):
220     image_len = 2 * 1024 * 1024 # MB
221
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)
225
226     def compare_images(self, img1, img2):
227         iotests.create_image(target_backing_img, TestMirrorNoBacking.image_len)
228         return iotests.compare_images(img1, img2)
229
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()
235
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)
242
243     def test_complete(self):
244         self.assert_no_active_block_jobs()
245
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', {})
250
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')
257
258     def test_cancel(self):
259         self.assert_no_active_block_jobs()
260
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', {})
265
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')
272
273     def test_large_cluster(self):
274         self.assert_no_active_block_jobs()
275
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)
282
283         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
284                              mode='existing', target=target_img)
285         self.assert_qmp(result, 'return', {})
286
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')
293
294 class TestMirrorResized(ImageMirroringTestCase):
295     backing_len = 1 * 1024 * 1024 # MB
296     image_len = 2 * 1024 * 1024 # MB
297
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()
304
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
313
314     def test_complete_top(self):
315         self.assert_no_active_block_jobs()
316
317         result = self.vm.qmp('drive-mirror', device='drive0', sync='top',
318                              target=target_img)
319         self.assert_qmp(result, 'return', {})
320
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')
327
328     def test_complete_full(self):
329         self.assert_no_active_block_jobs()
330
331         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
332                              target=target_img)
333         self.assert_qmp(result, 'return', {})
334
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')
341
342 class TestReadErrors(ImageMirroringTestCase):
343     image_len = 2 * 1024 * 1024 # MB
344
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
348
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"
359
360 [set-state]
361 state = "1"
362 event = "%s"
363 new_state = "2"
364
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()
371
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()
385
386     def tearDown(self):
387         self.vm.shutdown()
388         os.remove(test_img)
389         os.remove(backing_img)
390         os.remove(self.blkdebug_file)
391
392     def test_report_read(self):
393         self.assert_no_active_block_jobs()
394
395         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
396                              target=target_img)
397         self.assert_qmp(result, 'return', {})
398
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
416
417         self.assert_no_active_block_jobs()
418         self.vm.shutdown()
419
420     def test_ignore_read(self):
421         self.assert_no_active_block_jobs()
422
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', {})
426
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()
435
436     def test_large_cluster(self):
437         self.assert_no_active_block_jobs()
438
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', {})
447
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()
456
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')
461
462     def test_stop_read(self):
463         self.assert_no_active_block_jobs()
464
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', {})
468
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')
476
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')
480
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
488
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')
492
493         self.complete_and_wait(wait_ready=False)
494         self.assert_no_active_block_jobs()
495         self.vm.shutdown()
496
497 class TestWriteErrors(ImageMirroringTestCase):
498     image_len = 2 * 1024 * 1024 # MB
499
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
503
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"
514
515 [set-state]
516 state = "1"
517 event = "%s"
518 new_state = "2"
519
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()
526
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()
536
537     def tearDown(self):
538         self.vm.shutdown()
539         os.remove(test_img)
540         os.remove(backing_img)
541         os.remove(self.blkdebug_file)
542
543     def test_report_write(self):
544         self.assert_no_active_block_jobs()
545
546         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
547                              mode='existing', target=self.target_img)
548         self.assert_qmp(result, 'return', {})
549
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
567
568         self.assert_no_active_block_jobs()
569         self.vm.shutdown()
570
571     def test_ignore_write(self):
572         self.assert_no_active_block_jobs()
573
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', {})
578
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()
587
588     def test_stop_write(self):
589         self.assert_no_active_block_jobs()
590
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', {})
595
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')
603
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')
607
608                     result = self.vm.qmp('block-job-resume', device='drive0')
609                     self.assert_qmp(result, 'return', {})
610
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
619
620         self.complete_and_wait(wait_ready=False)
621         self.assert_no_active_block_jobs()
622         self.vm.shutdown()
623
624 class TestSetSpeed(ImageMirroringTestCase):
625     image_len = 80 * 1024 * 1024 # MB
626
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()
632
633     def tearDown(self):
634         self.vm.shutdown()
635         os.remove(test_img)
636         os.remove(backing_img)
637         os.remove(target_img)
638
639     def test_set_speed(self):
640         self.assert_no_active_block_jobs()
641
642         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
643                              target=target_img)
644         self.assert_qmp(result, 'return', {})
645
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)
650
651         result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
652         self.assert_qmp(result, 'return', {})
653
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)
658
659         self.wait_ready_and_cancel()
660
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', {})
665
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)
669
670         self.wait_ready_and_cancel()
671
672     def test_set_speed_invalid(self):
673         self.assert_no_active_block_jobs()
674
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')
678
679         self.assert_no_active_block_jobs()
680
681         result = self.vm.qmp('drive-mirror', device='drive0', sync='full',
682                              target=target_img)
683         self.assert_qmp(result, 'return', {})
684
685         result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
686         self.assert_qmp(result, 'error/class', 'GenericError')
687
688         self.wait_ready_and_cancel()
689
690 if __name__ == '__main__':
691     iotests.main(supported_fmts=['qcow2', 'qed'])
This page took 0.06687 seconds and 4 git commands to generate.