blob: 03dd6a6a9e58e8294436ba281ecca8edad6777ba [file] [log] [blame]
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +00001#!/usr/bin/env python
2#
3# Tests for image streaming.
4#
5# Copyright (C) 2012 IBM Corp.
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
Paolo Bonzini0c817342012-09-28 17:22:52 +020021import time
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000022import os
23import iotests
24from iotests import qemu_img, qemu_io
Paolo Bonziniab68cdf2012-06-06 16:23:26 +020025import struct
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000026
27backing_img = os.path.join(iotests.test_dir, 'backing.img')
Paolo Bonzini6e343602012-05-09 15:05:03 +020028mid_img = os.path.join(iotests.test_dir, 'mid.img')
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000029test_img = os.path.join(iotests.test_dir, 'test.img')
30
31class ImageStreamingTestCase(iotests.QMPTestCase):
32 '''Abstract base class for image streaming test cases'''
33
Stefan Hajnoczie4253062012-04-25 16:51:04 +010034 def cancel_and_wait(self, drive='drive0'):
35 '''Cancel a block job and wait for it to finish'''
36 result = self.vm.qmp('block-job-cancel', device=drive)
37 self.assert_qmp(result, 'return', {})
38
39 cancelled = False
40 while not cancelled:
41 for event in self.vm.get_qmp_events(wait=True):
42 if event['event'] == 'BLOCK_JOB_CANCELLED':
43 self.assert_qmp(event, 'data/type', 'stream')
44 self.assert_qmp(event, 'data/device', drive)
45 cancelled = True
46
Stefan Hajnocziecc1c882013-05-28 17:11:34 +020047 self.assert_no_active_block_jobs()
Stefan Hajnoczie4253062012-04-25 16:51:04 +010048
Paolo Bonziniab68cdf2012-06-06 16:23:26 +020049 def create_image(self, name, size):
50 file = open(name, 'w')
51 i = 0
52 while i < size:
53 sector = struct.pack('>l504xl', i / 512, i / 512)
54 file.write(sector)
55 i = i + 512
56 file.close()
57
58
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000059class TestSingleDrive(ImageStreamingTestCase):
60 image_len = 1 * 1024 * 1024 # MB
61
62 def setUp(self):
Paolo Bonziniab68cdf2012-06-06 16:23:26 +020063 self.create_image(backing_img, TestSingleDrive.image_len)
Paolo Bonzini6e343602012-05-09 15:05:03 +020064 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
65 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000066 self.vm = iotests.VM().add_drive(test_img)
67 self.vm.launch()
68
69 def tearDown(self):
70 self.vm.shutdown()
71 os.remove(test_img)
Paolo Bonzini6e343602012-05-09 15:05:03 +020072 os.remove(mid_img)
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000073 os.remove(backing_img)
74
75 def test_stream(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +020076 self.assert_no_active_block_jobs()
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000077
Stefan Hajnoczidb58f9c2012-04-11 16:27:10 +010078 result = self.vm.qmp('block-stream', device='drive0')
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000079 self.assert_qmp(result, 'return', {})
80
81 completed = False
82 while not completed:
83 for event in self.vm.get_qmp_events(wait=True):
84 if event['event'] == 'BLOCK_JOB_COMPLETED':
85 self.assert_qmp(event, 'data/type', 'stream')
86 self.assert_qmp(event, 'data/device', 'drive0')
87 self.assert_qmp(event, 'data/offset', self.image_len)
88 self.assert_qmp(event, 'data/len', self.image_len)
89 completed = True
90
Stefan Hajnocziecc1c882013-05-28 17:11:34 +020091 self.assert_no_active_block_jobs()
Paolo Bonzini863a5d02012-05-08 16:51:53 +020092 self.vm.shutdown()
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000093
Paolo Bonziniefcc7a22012-05-08 16:51:58 +020094 self.assertEqual(qemu_io('-c', 'map', backing_img),
95 qemu_io('-c', 'map', test_img),
96 'image file map does not match backing file after streaming')
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +000097
Paolo Bonzini0c817342012-09-28 17:22:52 +020098 def test_stream_pause(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +020099 self.assert_no_active_block_jobs()
Paolo Bonzini0c817342012-09-28 17:22:52 +0200100
101 result = self.vm.qmp('block-stream', device='drive0')
102 self.assert_qmp(result, 'return', {})
103
104 result = self.vm.qmp('block-job-pause', device='drive0')
105 self.assert_qmp(result, 'return', {})
106
107 time.sleep(1)
108 result = self.vm.qmp('query-block-jobs')
109 offset = self.dictpath(result, 'return[0]/offset')
110
111 time.sleep(1)
112 result = self.vm.qmp('query-block-jobs')
113 self.assert_qmp(result, 'return[0]/offset', offset)
114
115 result = self.vm.qmp('block-job-resume', device='drive0')
116 self.assert_qmp(result, 'return', {})
117
118 completed = False
119 while not completed:
120 for event in self.vm.get_qmp_events(wait=True):
121 if event['event'] == 'BLOCK_JOB_COMPLETED':
122 self.assert_qmp(event, 'data/type', 'stream')
123 self.assert_qmp(event, 'data/device', 'drive0')
124 self.assert_qmp(event, 'data/offset', self.image_len)
125 self.assert_qmp(event, 'data/len', self.image_len)
126 completed = True
127
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200128 self.assert_no_active_block_jobs()
Paolo Bonzini0c817342012-09-28 17:22:52 +0200129 self.vm.shutdown()
130
131 self.assertEqual(qemu_io('-c', 'map', backing_img),
132 qemu_io('-c', 'map', test_img),
133 'image file map does not match backing file after streaming')
134
Paolo Bonzini6e343602012-05-09 15:05:03 +0200135 def test_stream_partial(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200136 self.assert_no_active_block_jobs()
Paolo Bonzini6e343602012-05-09 15:05:03 +0200137
138 result = self.vm.qmp('block-stream', device='drive0', base=mid_img)
139 self.assert_qmp(result, 'return', {})
140
141 completed = False
142 while not completed:
143 for event in self.vm.get_qmp_events(wait=True):
144 if event['event'] == 'BLOCK_JOB_COMPLETED':
145 self.assert_qmp(event, 'data/type', 'stream')
146 self.assert_qmp(event, 'data/device', 'drive0')
147 self.assert_qmp(event, 'data/offset', self.image_len)
148 self.assert_qmp(event, 'data/len', self.image_len)
149 completed = True
150
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200151 self.assert_no_active_block_jobs()
Paolo Bonzini6e343602012-05-09 15:05:03 +0200152 self.vm.shutdown()
153
154 self.assertEqual(qemu_io('-c', 'map', mid_img),
155 qemu_io('-c', 'map', test_img),
156 'image file map does not match backing file after streaming')
157
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000158 def test_device_not_found(self):
Stefan Hajnoczidb58f9c2012-04-11 16:27:10 +0100159 result = self.vm.qmp('block-stream', device='nonexistent')
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000160 self.assert_qmp(result, 'error/class', 'DeviceNotFound')
161
Stefan Hajnoczi774a8852012-08-28 15:26:49 +0100162
163class TestSmallerBackingFile(ImageStreamingTestCase):
164 backing_len = 1 * 1024 * 1024 # MB
165 image_len = 2 * backing_len
166
167 def setUp(self):
168 self.create_image(backing_img, self.backing_len)
169 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img, str(self.image_len))
170 self.vm = iotests.VM().add_drive(test_img)
171 self.vm.launch()
172
173 # If this hangs, then you are missing a fix to complete streaming when the
174 # end of the backing file is reached.
175 def test_stream(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200176 self.assert_no_active_block_jobs()
Stefan Hajnoczi774a8852012-08-28 15:26:49 +0100177
178 result = self.vm.qmp('block-stream', device='drive0')
179 self.assert_qmp(result, 'return', {})
180
181 completed = False
182 while not completed:
183 for event in self.vm.get_qmp_events(wait=True):
184 if event['event'] == 'BLOCK_JOB_COMPLETED':
185 self.assert_qmp(event, 'data/type', 'stream')
186 self.assert_qmp(event, 'data/device', 'drive0')
187 self.assert_qmp(event, 'data/offset', self.image_len)
188 self.assert_qmp(event, 'data/len', self.image_len)
189 completed = True
190
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200191 self.assert_no_active_block_jobs()
Stefan Hajnoczi774a8852012-08-28 15:26:49 +0100192 self.vm.shutdown()
193
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200194class TestErrors(ImageStreamingTestCase):
195 image_len = 2 * 1024 * 1024 # MB
196
197 # this should match STREAM_BUFFER_SIZE/512 in block/stream.c
198 STREAM_BUFFER_SIZE = 512 * 1024
199
200 def create_blkdebug_file(self, name, event, errno):
201 file = open(name, 'w')
202 file.write('''
203[inject-error]
204state = "1"
205event = "%s"
206errno = "%d"
207immediately = "off"
208once = "on"
209sector = "%d"
210
211[set-state]
212state = "1"
213event = "%s"
214new_state = "2"
215
216[set-state]
217state = "2"
218event = "%s"
219new_state = "1"
220''' % (event, errno, self.STREAM_BUFFER_SIZE / 512, event, event))
221 file.close()
222
223class TestEIO(TestErrors):
224 def setUp(self):
225 self.blkdebug_file = backing_img + ".blkdebug"
226 self.create_image(backing_img, TestErrors.image_len)
227 self.create_blkdebug_file(self.blkdebug_file, "read_aio", 5)
228 qemu_img('create', '-f', iotests.imgfmt,
229 '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw'
230 % (self.blkdebug_file, backing_img),
231 test_img)
232 self.vm = iotests.VM().add_drive(test_img)
233 self.vm.launch()
234
235 def tearDown(self):
236 self.vm.shutdown()
237 os.remove(test_img)
238 os.remove(backing_img)
239 os.remove(self.blkdebug_file)
240
241 def test_report(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200242 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200243
244 result = self.vm.qmp('block-stream', device='drive0')
245 self.assert_qmp(result, 'return', {})
246
247 completed = False
248 error = False
249 while not completed:
250 for event in self.vm.get_qmp_events(wait=True):
251 if event['event'] == 'BLOCK_JOB_ERROR':
252 self.assert_qmp(event, 'data/device', 'drive0')
253 self.assert_qmp(event, 'data/operation', 'read')
254 error = True
255 elif event['event'] == 'BLOCK_JOB_COMPLETED':
256 self.assertTrue(error, 'job completed unexpectedly')
257 self.assert_qmp(event, 'data/type', 'stream')
258 self.assert_qmp(event, 'data/device', 'drive0')
259 self.assert_qmp(event, 'data/error', 'Input/output error')
260 self.assert_qmp(event, 'data/offset', self.STREAM_BUFFER_SIZE)
261 self.assert_qmp(event, 'data/len', self.image_len)
262 completed = True
263
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200264 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200265 self.vm.shutdown()
266
267 def test_ignore(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200268 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200269
270 result = self.vm.qmp('block-stream', device='drive0', on_error='ignore')
271 self.assert_qmp(result, 'return', {})
272
273 error = False
274 completed = False
275 while not completed:
276 for event in self.vm.get_qmp_events(wait=True):
277 if event['event'] == 'BLOCK_JOB_ERROR':
278 self.assert_qmp(event, 'data/device', 'drive0')
279 self.assert_qmp(event, 'data/operation', 'read')
280 result = self.vm.qmp('query-block-jobs')
281 self.assert_qmp(result, 'return[0]/paused', False)
282 error = True
283 elif event['event'] == 'BLOCK_JOB_COMPLETED':
284 self.assertTrue(error, 'job completed unexpectedly')
285 self.assert_qmp(event, 'data/type', 'stream')
286 self.assert_qmp(event, 'data/device', 'drive0')
287 self.assert_qmp(event, 'data/error', 'Input/output error')
288 self.assert_qmp(event, 'data/offset', self.image_len)
289 self.assert_qmp(event, 'data/len', self.image_len)
290 completed = True
291
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200292 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200293 self.vm.shutdown()
294
295 def test_stop(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200296 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200297
298 result = self.vm.qmp('block-stream', device='drive0', on_error='stop')
299 self.assert_qmp(result, 'return', {})
300
301 error = False
302 completed = False
303 while not completed:
304 for event in self.vm.get_qmp_events(wait=True):
305 if event['event'] == 'BLOCK_JOB_ERROR':
306 self.assert_qmp(event, 'data/device', 'drive0')
307 self.assert_qmp(event, 'data/operation', 'read')
308
309 result = self.vm.qmp('query-block-jobs')
310 self.assert_qmp(result, 'return[0]/paused', True)
311 self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE)
312 self.assert_qmp(result, 'return[0]/io-status', 'failed')
313
314 result = self.vm.qmp('block-job-resume', device='drive0')
315 self.assert_qmp(result, 'return', {})
316
317 result = self.vm.qmp('query-block-jobs')
318 self.assert_qmp(result, 'return[0]/paused', False)
319 self.assert_qmp(result, 'return[0]/io-status', 'ok')
320 error = True
321 elif event['event'] == 'BLOCK_JOB_COMPLETED':
322 self.assertTrue(error, 'job completed unexpectedly')
323 self.assert_qmp(event, 'data/type', 'stream')
324 self.assert_qmp(event, 'data/device', 'drive0')
325 self.assert_qmp_absent(event, 'data/error')
326 self.assert_qmp(event, 'data/offset', self.image_len)
327 self.assert_qmp(event, 'data/len', self.image_len)
328 completed = True
329
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200330 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200331 self.vm.shutdown()
332
333 def test_enospc(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200334 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200335
336 result = self.vm.qmp('block-stream', device='drive0', on_error='enospc')
337 self.assert_qmp(result, 'return', {})
338
339 completed = False
340 error = False
341 while not completed:
342 for event in self.vm.get_qmp_events(wait=True):
343 if event['event'] == 'BLOCK_JOB_ERROR':
344 self.assert_qmp(event, 'data/device', 'drive0')
345 self.assert_qmp(event, 'data/operation', 'read')
346 error = True
347 elif event['event'] == 'BLOCK_JOB_COMPLETED':
348 self.assertTrue(error, 'job completed unexpectedly')
349 self.assert_qmp(event, 'data/type', 'stream')
350 self.assert_qmp(event, 'data/device', 'drive0')
351 self.assert_qmp(event, 'data/error', 'Input/output error')
352 self.assert_qmp(event, 'data/offset', self.STREAM_BUFFER_SIZE)
353 self.assert_qmp(event, 'data/len', self.image_len)
354 completed = True
355
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200356 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200357 self.vm.shutdown()
358
359class TestENOSPC(TestErrors):
360 def setUp(self):
361 self.blkdebug_file = backing_img + ".blkdebug"
362 self.create_image(backing_img, TestErrors.image_len)
363 self.create_blkdebug_file(self.blkdebug_file, "read_aio", 28)
364 qemu_img('create', '-f', iotests.imgfmt,
365 '-o', 'backing_file=blkdebug:%s:%s,backing_fmt=raw'
366 % (self.blkdebug_file, backing_img),
367 test_img)
368 self.vm = iotests.VM().add_drive(test_img)
369 self.vm.launch()
370
371 def tearDown(self):
372 self.vm.shutdown()
373 os.remove(test_img)
374 os.remove(backing_img)
375 os.remove(self.blkdebug_file)
376
377 def test_enospc(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200378 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200379
380 result = self.vm.qmp('block-stream', device='drive0', on_error='enospc')
381 self.assert_qmp(result, 'return', {})
382
383 error = False
384 completed = False
385 while not completed:
386 for event in self.vm.get_qmp_events(wait=True):
387 if event['event'] == 'BLOCK_JOB_ERROR':
388 self.assert_qmp(event, 'data/device', 'drive0')
389 self.assert_qmp(event, 'data/operation', 'read')
390
391 result = self.vm.qmp('query-block-jobs')
392 self.assert_qmp(result, 'return[0]/paused', True)
393 self.assert_qmp(result, 'return[0]/offset', self.STREAM_BUFFER_SIZE)
394 self.assert_qmp(result, 'return[0]/io-status', 'nospace')
395
396 result = self.vm.qmp('block-job-resume', device='drive0')
397 self.assert_qmp(result, 'return', {})
398
399 result = self.vm.qmp('query-block-jobs')
400 self.assert_qmp(result, 'return[0]/paused', False)
401 self.assert_qmp(result, 'return[0]/io-status', 'ok')
402 error = True
403 elif event['event'] == 'BLOCK_JOB_COMPLETED':
404 self.assertTrue(error, 'job completed unexpectedly')
405 self.assert_qmp(event, 'data/type', 'stream')
406 self.assert_qmp(event, 'data/device', 'drive0')
407 self.assert_qmp_absent(event, 'data/error')
408 self.assert_qmp(event, 'data/offset', self.image_len)
409 self.assert_qmp(event, 'data/len', self.image_len)
410 completed = True
411
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200412 self.assert_no_active_block_jobs()
Paolo Bonzini90f0b712012-09-28 17:23:02 +0200413 self.vm.shutdown()
Stefan Hajnoczi774a8852012-08-28 15:26:49 +0100414
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000415class TestStreamStop(ImageStreamingTestCase):
416 image_len = 8 * 1024 * 1024 * 1024 # GB
417
418 def setUp(self):
419 qemu_img('create', backing_img, str(TestStreamStop.image_len))
420 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
421 self.vm = iotests.VM().add_drive(test_img)
422 self.vm.launch()
423
424 def tearDown(self):
425 self.vm.shutdown()
426 os.remove(test_img)
427 os.remove(backing_img)
428
429 def test_stream_stop(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200430 self.assert_no_active_block_jobs()
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000431
Stefan Hajnoczidb58f9c2012-04-11 16:27:10 +0100432 result = self.vm.qmp('block-stream', device='drive0')
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000433 self.assert_qmp(result, 'return', {})
434
Paolo Bonzini0fd05e82012-06-06 16:23:27 +0200435 time.sleep(0.1)
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000436 events = self.vm.get_qmp_events(wait=False)
437 self.assertEqual(events, [], 'unexpected QMP event: %s' % events)
438
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100439 self.cancel_and_wait()
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000440
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000441class TestSetSpeed(ImageStreamingTestCase):
442 image_len = 80 * 1024 * 1024 # MB
443
444 def setUp(self):
445 qemu_img('create', backing_img, str(TestSetSpeed.image_len))
446 qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
447 self.vm = iotests.VM().add_drive(test_img)
448 self.vm.launch()
449
450 def tearDown(self):
451 self.vm.shutdown()
452 os.remove(test_img)
453 os.remove(backing_img)
454
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100455 # This is a short performance test which is not run by default.
456 # Invoke "IMGFMT=qed ./030 TestSetSpeed.perf_test_throughput"
457 def perf_test_throughput(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200458 self.assert_no_active_block_jobs()
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000459
Stefan Hajnoczidb58f9c2012-04-11 16:27:10 +0100460 result = self.vm.qmp('block-stream', device='drive0')
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000461 self.assert_qmp(result, 'return', {})
462
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100463 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000464 self.assert_qmp(result, 'return', {})
465
466 completed = False
467 while not completed:
468 for event in self.vm.get_qmp_events(wait=True):
469 if event['event'] == 'BLOCK_JOB_COMPLETED':
470 self.assert_qmp(event, 'data/type', 'stream')
471 self.assert_qmp(event, 'data/device', 'drive0')
472 self.assert_qmp(event, 'data/offset', self.image_len)
473 self.assert_qmp(event, 'data/len', self.image_len)
474 completed = True
475
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200476 self.assert_no_active_block_jobs()
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000477
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100478 def test_set_speed(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200479 self.assert_no_active_block_jobs()
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100480
481 result = self.vm.qmp('block-stream', device='drive0')
482 self.assert_qmp(result, 'return', {})
483
484 # Default speed is 0
485 result = self.vm.qmp('query-block-jobs')
486 self.assert_qmp(result, 'return[0]/device', 'drive0')
487 self.assert_qmp(result, 'return[0]/speed', 0)
488
489 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
490 self.assert_qmp(result, 'return', {})
491
492 # Ensure the speed we set was accepted
493 result = self.vm.qmp('query-block-jobs')
494 self.assert_qmp(result, 'return[0]/device', 'drive0')
495 self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
496
497 self.cancel_and_wait()
498
499 # Check setting speed in block-stream works
500 result = self.vm.qmp('block-stream', device='drive0', speed=4 * 1024 * 1024)
501 self.assert_qmp(result, 'return', {})
502
503 result = self.vm.qmp('query-block-jobs')
504 self.assert_qmp(result, 'return[0]/device', 'drive0')
505 self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
506
507 self.cancel_and_wait()
508
509 def test_set_speed_invalid(self):
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200510 self.assert_no_active_block_jobs()
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100511
512 result = self.vm.qmp('block-stream', device='drive0', speed=-1)
Kevin Wolf58c8cce2012-08-15 14:08:56 +0200513 self.assert_qmp(result, 'error/class', 'GenericError')
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100514
Stefan Hajnocziecc1c882013-05-28 17:11:34 +0200515 self.assert_no_active_block_jobs()
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100516
517 result = self.vm.qmp('block-stream', device='drive0')
518 self.assert_qmp(result, 'return', {})
519
520 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
Kevin Wolf58c8cce2012-08-15 14:08:56 +0200521 self.assert_qmp(result, 'error/class', 'GenericError')
Stefan Hajnoczie4253062012-04-25 16:51:04 +0100522
523 self.cancel_and_wait()
524
Stefan Hajnoczi37ce63e2012-02-29 13:25:22 +0000525if __name__ == '__main__':
526 iotests.main(supported_fmts=['qcow2', 'qed'])