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