machine: add default_ram_size to machine class
[qemu/ar7.git] / tests / qemu-iotests / 055
blob017a609f39d06a1f77cc6bfb6f0dc9f921742906
1 #!/usr/bin/env python
3 # Tests for drive-backup and blockdev-backup
5 # Copyright (C) 2013, 2014 Red Hat, Inc.
7 # Based on 041.
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 import time
24 import os
25 import iotests
26 from iotests import qemu_img, qemu_io
28 test_img = os.path.join(iotests.test_dir, 'test.img')
29 target_img = os.path.join(iotests.test_dir, 'target.img')
30 blockdev_target_img = os.path.join(iotests.test_dir, 'blockdev-target.img')
32 class TestSingleDrive(iotests.QMPTestCase):
33 image_len = 64 * 1024 * 1024 # MB
35 def setUp(self):
36 # Write data to the image so we can compare later
37 qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleDrive.image_len))
38 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
39 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
40 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
41 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
42 qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(TestSingleDrive.image_len))
44 self.vm = iotests.VM().add_drive(test_img).add_drive(blockdev_target_img)
45 self.vm.launch()
47 def tearDown(self):
48 self.vm.shutdown()
49 os.remove(test_img)
50 os.remove(blockdev_target_img)
51 try:
52 os.remove(target_img)
53 except OSError:
54 pass
56 def do_test_cancel(self, cmd, target):
57 self.assert_no_active_block_jobs()
59 result = self.vm.qmp(cmd, device='drive0', target=target, sync='full')
60 self.assert_qmp(result, 'return', {})
62 event = self.cancel_and_wait()
63 self.assert_qmp(event, 'data/type', 'backup')
65 def test_cancel_drive_backup(self):
66 self.do_test_cancel('drive-backup', target_img)
68 def test_cancel_blockdev_backup(self):
69 self.do_test_cancel('blockdev-backup', 'drive1')
71 def do_test_pause(self, cmd, target, image):
72 self.assert_no_active_block_jobs()
74 self.vm.pause_drive('drive0')
75 result = self.vm.qmp(cmd, device='drive0',
76 target=target, sync='full')
77 self.assert_qmp(result, 'return', {})
79 result = self.vm.qmp('block-job-pause', device='drive0')
80 self.assert_qmp(result, 'return', {})
82 self.vm.resume_drive('drive0')
83 time.sleep(1)
84 result = self.vm.qmp('query-block-jobs')
85 offset = self.dictpath(result, 'return[0]/offset')
87 time.sleep(1)
88 result = self.vm.qmp('query-block-jobs')
89 self.assert_qmp(result, 'return[0]/offset', offset)
91 result = self.vm.qmp('block-job-resume', device='drive0')
92 self.assert_qmp(result, 'return', {})
94 self.wait_until_completed()
96 self.vm.shutdown()
97 self.assertTrue(iotests.compare_images(test_img, image),
98 'target image does not match source after backup')
100 def test_pause_drive_backup(self):
101 self.do_test_pause('drive-backup', target_img, target_img)
103 def test_pause_blockdev_backup(self):
104 self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
106 def test_medium_not_found(self):
107 result = self.vm.qmp('drive-backup', device='ide1-cd0',
108 target=target_img, sync='full')
109 self.assert_qmp(result, 'error/class', 'GenericError')
111 def test_medium_not_found_blockdev_backup(self):
112 result = self.vm.qmp('blockdev-backup', device='ide1-cd0',
113 target='drive1', sync='full')
114 self.assert_qmp(result, 'error/class', 'GenericError')
116 def test_image_not_found(self):
117 result = self.vm.qmp('drive-backup', device='drive0',
118 target=target_img, sync='full', mode='existing')
119 self.assert_qmp(result, 'error/class', 'GenericError')
121 def test_invalid_format(self):
122 result = self.vm.qmp('drive-backup', device='drive0',
123 target=target_img, sync='full',
124 format='spaghetti-noodles')
125 self.assert_qmp(result, 'error/class', 'GenericError')
127 def do_test_device_not_found(self, cmd, **args):
128 result = self.vm.qmp(cmd, **args)
129 if cmd == 'drive-backup':
130 self.assert_qmp(result, 'error/class', 'DeviceNotFound')
131 else:
132 self.assert_qmp(result, 'error/class', 'GenericError')
134 def test_device_not_found(self):
135 self.do_test_device_not_found('drive-backup', device='nonexistent',
136 target=target_img, sync='full')
138 self.do_test_device_not_found('blockdev-backup', device='nonexistent',
139 target='drive0', sync='full')
141 self.do_test_device_not_found('blockdev-backup', device='drive0',
142 target='nonexistent', sync='full')
144 self.do_test_device_not_found('blockdev-backup', device='nonexistent',
145 target='nonexistent', sync='full')
147 def test_target_is_source(self):
148 result = self.vm.qmp('blockdev-backup', device='drive0',
149 target='drive0', sync='full')
150 self.assert_qmp(result, 'error/class', 'GenericError')
152 class TestSetSpeed(iotests.QMPTestCase):
153 image_len = 80 * 1024 * 1024 # MB
155 def setUp(self):
156 qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSetSpeed.image_len))
157 qemu_io('-f', iotests.imgfmt, '-c', 'write -P1 0 512', test_img)
158 qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(TestSingleDrive.image_len))
160 self.vm = iotests.VM().add_drive(test_img).add_drive(blockdev_target_img)
161 self.vm.launch()
163 def tearDown(self):
164 self.vm.shutdown()
165 os.remove(test_img)
166 os.remove(blockdev_target_img)
167 try:
168 os.remove(target_img)
169 except OSError:
170 pass
172 def do_test_set_speed(self, cmd, target):
173 self.assert_no_active_block_jobs()
175 self.vm.pause_drive('drive0')
176 result = self.vm.qmp(cmd, device='drive0', target=target, sync='full')
177 self.assert_qmp(result, 'return', {})
179 # Default speed is 0
180 result = self.vm.qmp('query-block-jobs')
181 self.assert_qmp(result, 'return[0]/device', 'drive0')
182 self.assert_qmp(result, 'return[0]/speed', 0)
184 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
185 self.assert_qmp(result, 'return', {})
187 # Ensure the speed we set was accepted
188 result = self.vm.qmp('query-block-jobs')
189 self.assert_qmp(result, 'return[0]/device', 'drive0')
190 self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
192 event = self.cancel_and_wait(resume=True)
193 self.assert_qmp(event, 'data/type', 'backup')
195 # Check setting speed option works
196 self.vm.pause_drive('drive0')
197 result = self.vm.qmp(cmd, device='drive0',
198 target=target, sync='full', speed=4*1024*1024)
199 self.assert_qmp(result, 'return', {})
201 result = self.vm.qmp('query-block-jobs')
202 self.assert_qmp(result, 'return[0]/device', 'drive0')
203 self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
205 event = self.cancel_and_wait(resume=True)
206 self.assert_qmp(event, 'data/type', 'backup')
208 def test_set_speed_drive_backup(self):
209 self.do_test_set_speed('drive-backup', target_img)
211 def test_set_speed_blockdev_backup(self):
212 self.do_test_set_speed('blockdev-backup', 'drive1')
214 def do_test_set_speed_invalid(self, cmd, target):
215 self.assert_no_active_block_jobs()
217 result = self.vm.qmp(cmd, device='drive0',
218 target=target, sync='full', speed=-1)
219 self.assert_qmp(result, 'error/class', 'GenericError')
221 self.assert_no_active_block_jobs()
223 self.vm.pause_drive('drive0')
224 result = self.vm.qmp(cmd, device='drive0',
225 target=target, sync='full')
226 self.assert_qmp(result, 'return', {})
228 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
229 self.assert_qmp(result, 'error/class', 'GenericError')
231 event = self.cancel_and_wait(resume=True)
232 self.assert_qmp(event, 'data/type', 'backup')
234 def test_set_speed_invalid_drive_backup(self):
235 self.do_test_set_speed_invalid('drive-backup', target_img)
237 def test_set_speed_invalid_blockdev_backup(self):
238 self.do_test_set_speed_invalid('blockdev-backup', 'drive1')
240 class TestSingleTransaction(iotests.QMPTestCase):
241 image_len = 64 * 1024 * 1024 # MB
243 def setUp(self):
244 qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleTransaction.image_len))
245 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
246 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
247 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
248 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
249 qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(TestSingleDrive.image_len))
251 self.vm = iotests.VM().add_drive(test_img).add_drive(blockdev_target_img)
252 self.vm.launch()
254 def tearDown(self):
255 self.vm.shutdown()
256 os.remove(test_img)
257 os.remove(blockdev_target_img)
258 try:
259 os.remove(target_img)
260 except OSError:
261 pass
263 def do_test_cancel(self, cmd, target):
264 self.assert_no_active_block_jobs()
266 result = self.vm.qmp('transaction', actions=[{
267 'type': cmd,
268 'data': { 'device': 'drive0',
269 'target': target,
270 'sync': 'full' },
274 self.assert_qmp(result, 'return', {})
276 event = self.cancel_and_wait()
277 self.assert_qmp(event, 'data/type', 'backup')
279 def test_cancel_drive_backup(self):
280 self.do_test_cancel('drive-backup', target_img)
282 def test_cancel_blockdev_backup(self):
283 self.do_test_cancel('blockdev-backup', 'drive1')
285 def do_test_pause(self, cmd, target, image):
286 self.assert_no_active_block_jobs()
288 self.vm.pause_drive('drive0')
289 result = self.vm.qmp('transaction', actions=[{
290 'type': cmd,
291 'data': { 'device': 'drive0',
292 'target': target,
293 'sync': 'full' },
296 self.assert_qmp(result, 'return', {})
298 result = self.vm.qmp('block-job-pause', device='drive0')
299 self.assert_qmp(result, 'return', {})
301 self.vm.resume_drive('drive0')
302 time.sleep(1)
303 result = self.vm.qmp('query-block-jobs')
304 offset = self.dictpath(result, 'return[0]/offset')
306 time.sleep(1)
307 result = self.vm.qmp('query-block-jobs')
308 self.assert_qmp(result, 'return[0]/offset', offset)
310 result = self.vm.qmp('block-job-resume', device='drive0')
311 self.assert_qmp(result, 'return', {})
313 self.wait_until_completed()
315 self.vm.shutdown()
316 self.assertTrue(iotests.compare_images(test_img, image),
317 'target image does not match source after backup')
319 def test_pause_drive_backup(self):
320 self.do_test_pause('drive-backup', target_img, target_img)
322 def test_pause_blockdev_backup(self):
323 self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
325 def do_test_medium_not_found(self, cmd, target):
326 result = self.vm.qmp('transaction', actions=[{
327 'type': cmd,
328 'data': { 'device': 'ide1-cd0',
329 'target': target,
330 'sync': 'full' },
333 self.assert_qmp(result, 'error/class', 'GenericError')
335 def test_medium_not_found_drive_backup(self):
336 self.do_test_medium_not_found('drive-backup', target_img)
338 def test_medium_not_found_blockdev_backup(self):
339 self.do_test_medium_not_found('blockdev-backup', 'drive1')
341 def test_image_not_found(self):
342 result = self.vm.qmp('transaction', actions=[{
343 'type': 'drive-backup',
344 'data': { 'device': 'drive0',
345 'mode': 'existing',
346 'target': target_img,
347 'sync': 'full' },
350 self.assert_qmp(result, 'error/class', 'GenericError')
352 def test_device_not_found(self):
353 result = self.vm.qmp('transaction', actions=[{
354 'type': 'drive-backup',
355 'data': { 'device': 'nonexistent',
356 'mode': 'existing',
357 'target': target_img,
358 'sync': 'full' },
361 self.assert_qmp(result, 'error/class', 'DeviceNotFound')
363 result = self.vm.qmp('transaction', actions=[{
364 'type': 'blockdev-backup',
365 'data': { 'device': 'nonexistent',
366 'target': 'drive1',
367 'sync': 'full' },
370 self.assert_qmp(result, 'error/class', 'GenericError')
372 result = self.vm.qmp('transaction', actions=[{
373 'type': 'blockdev-backup',
374 'data': { 'device': 'drive0',
375 'target': 'nonexistent',
376 'sync': 'full' },
379 self.assert_qmp(result, 'error/class', 'GenericError')
381 result = self.vm.qmp('transaction', actions=[{
382 'type': 'blockdev-backup',
383 'data': { 'device': 'nonexistent',
384 'target': 'nonexistent',
385 'sync': 'full' },
388 self.assert_qmp(result, 'error/class', 'GenericError')
390 def test_target_is_source(self):
391 result = self.vm.qmp('transaction', actions=[{
392 'type': 'blockdev-backup',
393 'data': { 'device': 'drive0',
394 'target': 'drive0',
395 'sync': 'full' },
398 self.assert_qmp(result, 'error/class', 'GenericError')
400 def test_abort(self):
401 result = self.vm.qmp('transaction', actions=[{
402 'type': 'drive-backup',
403 'data': { 'device': 'nonexistent',
404 'mode': 'existing',
405 'target': target_img,
406 'sync': 'full' },
407 }, {
408 'type': 'Abort',
409 'data': {},
412 self.assert_qmp(result, 'error/class', 'GenericError')
413 self.assert_no_active_block_jobs()
415 result = self.vm.qmp('transaction', actions=[{
416 'type': 'blockdev-backup',
417 'data': { 'device': 'nonexistent',
418 'target': 'drive1',
419 'sync': 'full' },
420 }, {
421 'type': 'Abort',
422 'data': {},
425 self.assert_qmp(result, 'error/class', 'GenericError')
426 self.assert_no_active_block_jobs()
428 result = self.vm.qmp('transaction', actions=[{
429 'type': 'blockdev-backup',
430 'data': { 'device': 'drive0',
431 'target': 'nonexistent',
432 'sync': 'full' },
433 }, {
434 'type': 'Abort',
435 'data': {},
438 self.assert_qmp(result, 'error/class', 'GenericError')
439 self.assert_no_active_block_jobs()
441 if __name__ == '__main__':
442 iotests.main(supported_fmts=['raw', 'qcow2'])