]> Git Repo - qemu.git/blame - tests/qemu-iotests/055
qemu-iotests: test backup compression in 055
[qemu.git] / tests / qemu-iotests / 055
CommitLineData
e5ca8fdd
SH
1#!/usr/bin/env python
2#
7c6a4ab8 3# Tests for drive-backup and blockdev-backup
e5ca8fdd 4#
7c6a4ab8 5# Copyright (C) 2013, 2014 Red Hat, Inc.
e5ca8fdd
SH
6#
7# Based on 041.
8#
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.
13#
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.
18#
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/>.
21#
22
23import time
24import os
25import iotests
26from iotests import qemu_img, qemu_io
27
28test_img = os.path.join(iotests.test_dir, 'test.img')
29target_img = os.path.join(iotests.test_dir, 'target.img')
7c6a4ab8 30blockdev_target_img = os.path.join(iotests.test_dir, 'blockdev-target.img')
e5ca8fdd
SH
31
32class TestSingleDrive(iotests.QMPTestCase):
33 image_len = 64 * 1024 * 1024 # MB
34
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))
90c9b167
KW
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)
7c6a4ab8 42 qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(TestSingleDrive.image_len))
e5ca8fdd 43
7c6a4ab8 44 self.vm = iotests.VM().add_drive(test_img).add_drive(blockdev_target_img)
0ed82f7a
HR
45 if iotests.qemu_default_machine == 'pc':
46 self.vm.add_drive(None, 'media=cdrom', 'ide')
e5ca8fdd
SH
47 self.vm.launch()
48
49 def tearDown(self):
50 self.vm.shutdown()
51 os.remove(test_img)
7c6a4ab8 52 os.remove(blockdev_target_img)
e5ca8fdd
SH
53 try:
54 os.remove(target_img)
55 except OSError:
56 pass
57
7c6a4ab8 58 def do_test_cancel(self, cmd, target):
e5ca8fdd
SH
59 self.assert_no_active_block_jobs()
60
7c6a4ab8 61 result = self.vm.qmp(cmd, device='drive0', target=target, sync='full')
e5ca8fdd
SH
62 self.assert_qmp(result, 'return', {})
63
64 event = self.cancel_and_wait()
65 self.assert_qmp(event, 'data/type', 'backup')
66
7c6a4ab8
FZ
67 def test_cancel_drive_backup(self):
68 self.do_test_cancel('drive-backup', target_img)
69
70 def test_cancel_blockdev_backup(self):
71 self.do_test_cancel('blockdev-backup', 'drive1')
72
73 def do_test_pause(self, cmd, target, image):
e5ca8fdd
SH
74 self.assert_no_active_block_jobs()
75
b59b3d57 76 self.vm.pause_drive('drive0')
7c6a4ab8
FZ
77 result = self.vm.qmp(cmd, device='drive0',
78 target=target, sync='full')
e5ca8fdd
SH
79 self.assert_qmp(result, 'return', {})
80
81 result = self.vm.qmp('block-job-pause', device='drive0')
82 self.assert_qmp(result, 'return', {})
83
b59b3d57 84 self.vm.resume_drive('drive0')
e5ca8fdd
SH
85 time.sleep(1)
86 result = self.vm.qmp('query-block-jobs')
87 offset = self.dictpath(result, 'return[0]/offset')
88
89 time.sleep(1)
90 result = self.vm.qmp('query-block-jobs')
91 self.assert_qmp(result, 'return[0]/offset', offset)
92
93 result = self.vm.qmp('block-job-resume', device='drive0')
94 self.assert_qmp(result, 'return', {})
95
96 self.wait_until_completed()
97
98 self.vm.shutdown()
7c6a4ab8 99 self.assertTrue(iotests.compare_images(test_img, image),
e5ca8fdd
SH
100 'target image does not match source after backup')
101
7c6a4ab8
FZ
102 def test_pause_drive_backup(self):
103 self.do_test_pause('drive-backup', target_img, target_img)
104
105 def test_pause_blockdev_backup(self):
106 self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
107
e5ca8fdd 108 def test_medium_not_found(self):
d8683155
BT
109 if iotests.qemu_default_machine != 'pc':
110 return
111
0ed82f7a 112 result = self.vm.qmp('drive-backup', device='drive2', # CD-ROM
b53169ea 113 target=target_img, sync='full')
e5ca8fdd
SH
114 self.assert_qmp(result, 'error/class', 'GenericError')
115
7c6a4ab8 116 def test_medium_not_found_blockdev_backup(self):
d8683155
BT
117 if iotests.qemu_default_machine != 'pc':
118 return
119
0ed82f7a 120 result = self.vm.qmp('blockdev-backup', device='drive2', # CD-ROM
7c6a4ab8
FZ
121 target='drive1', sync='full')
122 self.assert_qmp(result, 'error/class', 'GenericError')
123
e5ca8fdd
SH
124 def test_image_not_found(self):
125 result = self.vm.qmp('drive-backup', device='drive0',
b53169ea 126 target=target_img, sync='full', mode='existing')
e5ca8fdd
SH
127 self.assert_qmp(result, 'error/class', 'GenericError')
128
e3409362
IM
129 def test_invalid_format(self):
130 result = self.vm.qmp('drive-backup', device='drive0',
131 target=target_img, sync='full',
132 format='spaghetti-noodles')
133 self.assert_qmp(result, 'error/class', 'GenericError')
134
7c6a4ab8
FZ
135 def do_test_device_not_found(self, cmd, **args):
136 result = self.vm.qmp(cmd, **args)
b7e4fa22 137 self.assert_qmp(result, 'error/class', 'GenericError')
e5ca8fdd 138
7c6a4ab8
FZ
139 def test_device_not_found(self):
140 self.do_test_device_not_found('drive-backup', device='nonexistent',
141 target=target_img, sync='full')
142
143 self.do_test_device_not_found('blockdev-backup', device='nonexistent',
144 target='drive0', sync='full')
145
146 self.do_test_device_not_found('blockdev-backup', device='drive0',
147 target='nonexistent', sync='full')
148
149 self.do_test_device_not_found('blockdev-backup', device='nonexistent',
150 target='nonexistent', sync='full')
151
152 def test_target_is_source(self):
153 result = self.vm.qmp('blockdev-backup', device='drive0',
154 target='drive0', sync='full')
155 self.assert_qmp(result, 'error/class', 'GenericError')
156
e5ca8fdd
SH
157class TestSetSpeed(iotests.QMPTestCase):
158 image_len = 80 * 1024 * 1024 # MB
159
160 def setUp(self):
161 qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSetSpeed.image_len))
90c9b167 162 qemu_io('-f', iotests.imgfmt, '-c', 'write -P1 0 512', test_img)
7c6a4ab8
FZ
163 qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(TestSingleDrive.image_len))
164
165 self.vm = iotests.VM().add_drive(test_img).add_drive(blockdev_target_img)
e5ca8fdd
SH
166 self.vm.launch()
167
168 def tearDown(self):
169 self.vm.shutdown()
170 os.remove(test_img)
7c6a4ab8
FZ
171 os.remove(blockdev_target_img)
172 try:
173 os.remove(target_img)
174 except OSError:
175 pass
e5ca8fdd 176
7c6a4ab8 177 def do_test_set_speed(self, cmd, target):
e5ca8fdd
SH
178 self.assert_no_active_block_jobs()
179
b59b3d57 180 self.vm.pause_drive('drive0')
7c6a4ab8 181 result = self.vm.qmp(cmd, device='drive0', target=target, sync='full')
e5ca8fdd
SH
182 self.assert_qmp(result, 'return', {})
183
184 # Default speed is 0
185 result = self.vm.qmp('query-block-jobs')
186 self.assert_qmp(result, 'return[0]/device', 'drive0')
187 self.assert_qmp(result, 'return[0]/speed', 0)
188
189 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
190 self.assert_qmp(result, 'return', {})
191
192 # Ensure the speed we set was accepted
193 result = self.vm.qmp('query-block-jobs')
194 self.assert_qmp(result, 'return[0]/device', 'drive0')
195 self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
196
b59b3d57 197 event = self.cancel_and_wait(resume=True)
e5ca8fdd
SH
198 self.assert_qmp(event, 'data/type', 'backup')
199
7c6a4ab8 200 # Check setting speed option works
b59b3d57 201 self.vm.pause_drive('drive0')
7c6a4ab8
FZ
202 result = self.vm.qmp(cmd, device='drive0',
203 target=target, sync='full', speed=4*1024*1024)
e5ca8fdd
SH
204 self.assert_qmp(result, 'return', {})
205
206 result = self.vm.qmp('query-block-jobs')
207 self.assert_qmp(result, 'return[0]/device', 'drive0')
208 self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
209
b59b3d57 210 event = self.cancel_and_wait(resume=True)
e5ca8fdd
SH
211 self.assert_qmp(event, 'data/type', 'backup')
212
7c6a4ab8
FZ
213 def test_set_speed_drive_backup(self):
214 self.do_test_set_speed('drive-backup', target_img)
215
216 def test_set_speed_blockdev_backup(self):
217 self.do_test_set_speed('blockdev-backup', 'drive1')
218
219 def do_test_set_speed_invalid(self, cmd, target):
e5ca8fdd
SH
220 self.assert_no_active_block_jobs()
221
7c6a4ab8
FZ
222 result = self.vm.qmp(cmd, device='drive0',
223 target=target, sync='full', speed=-1)
e5ca8fdd
SH
224 self.assert_qmp(result, 'error/class', 'GenericError')
225
226 self.assert_no_active_block_jobs()
227
b59b3d57 228 self.vm.pause_drive('drive0')
7c6a4ab8
FZ
229 result = self.vm.qmp(cmd, device='drive0',
230 target=target, sync='full')
e5ca8fdd
SH
231 self.assert_qmp(result, 'return', {})
232
233 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
234 self.assert_qmp(result, 'error/class', 'GenericError')
235
b59b3d57 236 event = self.cancel_and_wait(resume=True)
e5ca8fdd
SH
237 self.assert_qmp(event, 'data/type', 'backup')
238
7c6a4ab8
FZ
239 def test_set_speed_invalid_drive_backup(self):
240 self.do_test_set_speed_invalid('drive-backup', target_img)
241
242 def test_set_speed_invalid_blockdev_backup(self):
243 self.do_test_set_speed_invalid('blockdev-backup', 'drive1')
244
e5ca8fdd
SH
245class TestSingleTransaction(iotests.QMPTestCase):
246 image_len = 64 * 1024 * 1024 # MB
247
248 def setUp(self):
249 qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleTransaction.image_len))
90c9b167
KW
250 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
251 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
252 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
253 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
7c6a4ab8 254 qemu_img('create', '-f', iotests.imgfmt, blockdev_target_img, str(TestSingleDrive.image_len))
e5ca8fdd 255
7c6a4ab8 256 self.vm = iotests.VM().add_drive(test_img).add_drive(blockdev_target_img)
0ed82f7a
HR
257 if iotests.qemu_default_machine == 'pc':
258 self.vm.add_drive(None, 'media=cdrom', 'ide')
e5ca8fdd
SH
259 self.vm.launch()
260
261 def tearDown(self):
262 self.vm.shutdown()
263 os.remove(test_img)
7c6a4ab8 264 os.remove(blockdev_target_img)
e5ca8fdd
SH
265 try:
266 os.remove(target_img)
267 except OSError:
268 pass
269
7c6a4ab8 270 def do_test_cancel(self, cmd, target):
e5ca8fdd
SH
271 self.assert_no_active_block_jobs()
272
273 result = self.vm.qmp('transaction', actions=[{
7c6a4ab8 274 'type': cmd,
e5ca8fdd 275 'data': { 'device': 'drive0',
7c6a4ab8 276 'target': target,
b53169ea 277 'sync': 'full' },
e5ca8fdd
SH
278 }
279 ])
7c6a4ab8 280
e5ca8fdd
SH
281 self.assert_qmp(result, 'return', {})
282
283 event = self.cancel_and_wait()
284 self.assert_qmp(event, 'data/type', 'backup')
285
7c6a4ab8
FZ
286 def test_cancel_drive_backup(self):
287 self.do_test_cancel('drive-backup', target_img)
288
289 def test_cancel_blockdev_backup(self):
290 self.do_test_cancel('blockdev-backup', 'drive1')
291
292 def do_test_pause(self, cmd, target, image):
e5ca8fdd
SH
293 self.assert_no_active_block_jobs()
294
b59b3d57 295 self.vm.pause_drive('drive0')
e5ca8fdd 296 result = self.vm.qmp('transaction', actions=[{
7c6a4ab8 297 'type': cmd,
e5ca8fdd 298 'data': { 'device': 'drive0',
7c6a4ab8 299 'target': target,
b53169ea 300 'sync': 'full' },
e5ca8fdd
SH
301 }
302 ])
303 self.assert_qmp(result, 'return', {})
304
305 result = self.vm.qmp('block-job-pause', device='drive0')
306 self.assert_qmp(result, 'return', {})
307
b59b3d57 308 self.vm.resume_drive('drive0')
e5ca8fdd
SH
309 time.sleep(1)
310 result = self.vm.qmp('query-block-jobs')
311 offset = self.dictpath(result, 'return[0]/offset')
312
313 time.sleep(1)
314 result = self.vm.qmp('query-block-jobs')
315 self.assert_qmp(result, 'return[0]/offset', offset)
316
317 result = self.vm.qmp('block-job-resume', device='drive0')
318 self.assert_qmp(result, 'return', {})
319
320 self.wait_until_completed()
321
322 self.vm.shutdown()
7c6a4ab8 323 self.assertTrue(iotests.compare_images(test_img, image),
e5ca8fdd
SH
324 'target image does not match source after backup')
325
7c6a4ab8
FZ
326 def test_pause_drive_backup(self):
327 self.do_test_pause('drive-backup', target_img, target_img)
328
329 def test_pause_blockdev_backup(self):
330 self.do_test_pause('blockdev-backup', 'drive1', blockdev_target_img)
331
332 def do_test_medium_not_found(self, cmd, target):
d8683155
BT
333 if iotests.qemu_default_machine != 'pc':
334 return
335
e5ca8fdd 336 result = self.vm.qmp('transaction', actions=[{
7c6a4ab8 337 'type': cmd,
0ed82f7a 338 'data': { 'device': 'drive2', # CD-ROM
7c6a4ab8 339 'target': target,
b53169ea 340 'sync': 'full' },
e5ca8fdd
SH
341 }
342 ])
343 self.assert_qmp(result, 'error/class', 'GenericError')
344
7c6a4ab8
FZ
345 def test_medium_not_found_drive_backup(self):
346 self.do_test_medium_not_found('drive-backup', target_img)
347
348 def test_medium_not_found_blockdev_backup(self):
349 self.do_test_medium_not_found('blockdev-backup', 'drive1')
350
e5ca8fdd
SH
351 def test_image_not_found(self):
352 result = self.vm.qmp('transaction', actions=[{
353 'type': 'drive-backup',
354 'data': { 'device': 'drive0',
355 'mode': 'existing',
b53169ea
SH
356 'target': target_img,
357 'sync': 'full' },
e5ca8fdd
SH
358 }
359 ])
360 self.assert_qmp(result, 'error/class', 'GenericError')
361
362 def test_device_not_found(self):
363 result = self.vm.qmp('transaction', actions=[{
364 'type': 'drive-backup',
365 'data': { 'device': 'nonexistent',
366 'mode': 'existing',
b53169ea
SH
367 'target': target_img,
368 'sync': 'full' },
e5ca8fdd
SH
369 }
370 ])
b7e4fa22 371 self.assert_qmp(result, 'error/class', 'GenericError')
e5ca8fdd 372
7c6a4ab8
FZ
373 result = self.vm.qmp('transaction', actions=[{
374 'type': 'blockdev-backup',
375 'data': { 'device': 'nonexistent',
376 'target': 'drive1',
377 'sync': 'full' },
378 }
379 ])
5b347c54 380 self.assert_qmp(result, 'error/class', 'GenericError')
7c6a4ab8
FZ
381
382 result = self.vm.qmp('transaction', actions=[{
383 'type': 'blockdev-backup',
384 'data': { 'device': 'drive0',
385 'target': 'nonexistent',
386 'sync': 'full' },
387 }
388 ])
5b347c54 389 self.assert_qmp(result, 'error/class', 'GenericError')
7c6a4ab8
FZ
390
391 result = self.vm.qmp('transaction', actions=[{
392 'type': 'blockdev-backup',
393 'data': { 'device': 'nonexistent',
394 'target': 'nonexistent',
395 'sync': 'full' },
396 }
397 ])
5b347c54 398 self.assert_qmp(result, 'error/class', 'GenericError')
7c6a4ab8
FZ
399
400 def test_target_is_source(self):
401 result = self.vm.qmp('transaction', actions=[{
402 'type': 'blockdev-backup',
403 'data': { 'device': 'drive0',
404 'target': 'drive0',
405 'sync': 'full' },
406 }
407 ])
408 self.assert_qmp(result, 'error/class', 'GenericError')
409
e5ca8fdd
SH
410 def test_abort(self):
411 result = self.vm.qmp('transaction', actions=[{
412 'type': 'drive-backup',
413 'data': { 'device': 'nonexistent',
414 'mode': 'existing',
b53169ea
SH
415 'target': target_img,
416 'sync': 'full' },
e5ca8fdd
SH
417 }, {
418 'type': 'Abort',
419 'data': {},
420 }
421 ])
422 self.assert_qmp(result, 'error/class', 'GenericError')
423 self.assert_no_active_block_jobs()
424
7c6a4ab8
FZ
425 result = self.vm.qmp('transaction', actions=[{
426 'type': 'blockdev-backup',
427 'data': { 'device': 'nonexistent',
428 'target': 'drive1',
429 'sync': 'full' },
430 }, {
431 'type': 'Abort',
432 'data': {},
433 }
434 ])
435 self.assert_qmp(result, 'error/class', 'GenericError')
436 self.assert_no_active_block_jobs()
437
438 result = self.vm.qmp('transaction', actions=[{
439 'type': 'blockdev-backup',
440 'data': { 'device': 'drive0',
441 'target': 'nonexistent',
442 'sync': 'full' },
443 }, {
444 'type': 'Abort',
445 'data': {},
446 }
447 ])
448 self.assert_qmp(result, 'error/class', 'GenericError')
449 self.assert_no_active_block_jobs()
450
e1b5c51f
PB
451
452class TestDriveCompression(iotests.QMPTestCase):
453 image_len = 64 * 1024 * 1024 # MB
454 outfmt = 'qcow2'
455
456 def setUp(self):
457 # Write data to the image so we can compare later
458 qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestDriveCompression.image_len))
459 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x11 0 64k', test_img)
460 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x00 64k 128k', test_img)
461 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x22 162k 32k', test_img)
462 qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x33 67043328 64k', test_img)
463
464 qemu_img('create', '-f', TestDriveCompression.outfmt, blockdev_target_img,
465 str(TestDriveCompression.image_len))
466 self.vm = iotests.VM().add_drive(test_img).add_drive(blockdev_target_img,
467 format=TestDriveCompression.outfmt)
468 self.vm.launch()
469
470 def tearDown(self):
471 self.vm.shutdown()
472 os.remove(test_img)
473 os.remove(blockdev_target_img)
474 try:
475 os.remove(target_img)
476 except OSError:
477 pass
478
479 def do_test_compress_complete(self, cmd, **args):
480 self.assert_no_active_block_jobs()
481
482 result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args)
483 self.assert_qmp(result, 'return', {})
484
485 self.wait_until_completed()
486
487 self.vm.shutdown()
488 self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
489 iotests.imgfmt, TestDriveCompression.outfmt),
490 'target image does not match source after backup')
491
492 def test_complete_compress_drive_backup(self):
493 self.do_test_compress_complete('drive-backup', target=blockdev_target_img, mode='existing')
494
495 def test_complete_compress_blockdev_backup(self):
496 self.do_test_compress_complete('blockdev-backup', target='drive1')
497
498 def do_test_compress_cancel(self, cmd, **args):
499 self.assert_no_active_block_jobs()
500
501 result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args)
502 self.assert_qmp(result, 'return', {})
503
504 event = self.cancel_and_wait()
505 self.assert_qmp(event, 'data/type', 'backup')
506
507 def test_compress_cancel_drive_backup(self):
508 self.do_test_compress_cancel('drive-backup', target=blockdev_target_img, mode='existing')
509
510 def test_compress_cancel_blockdev_backup(self):
511 self.do_test_compress_cancel('blockdev-backup', target='drive1')
512
513 def do_test_compress_pause(self, cmd, **args):
514 self.assert_no_active_block_jobs()
515
516 self.vm.pause_drive('drive0')
517 result = self.vm.qmp(cmd, device='drive0', sync='full', compress=True, **args)
518 self.assert_qmp(result, 'return', {})
519
520 result = self.vm.qmp('block-job-pause', device='drive0')
521 self.assert_qmp(result, 'return', {})
522
523 self.vm.resume_drive('drive0')
524 time.sleep(1)
525 result = self.vm.qmp('query-block-jobs')
526 offset = self.dictpath(result, 'return[0]/offset')
527
528 time.sleep(1)
529 result = self.vm.qmp('query-block-jobs')
530 self.assert_qmp(result, 'return[0]/offset', offset)
531
532 result = self.vm.qmp('block-job-resume', device='drive0')
533 self.assert_qmp(result, 'return', {})
534
535 self.wait_until_completed()
536
537 self.vm.shutdown()
538 self.assertTrue(iotests.compare_images(test_img, blockdev_target_img,
539 iotests.imgfmt, TestDriveCompression.outfmt),
540 'target image does not match source after backup')
541
542 def test_compress_pause_drive_backup(self):
543 self.do_test_compress_pause('drive-backup', target=blockdev_target_img, mode='existing')
544
545 def test_compress_pause_blockdev_backup(self):
546 self.do_test_compress_pause('blockdev-backup', target='drive1')
547
e5ca8fdd
SH
548if __name__ == '__main__':
549 iotests.main(supported_fmts=['raw', 'qcow2'])
This page took 0.288006 seconds and 4 git commands to generate.