]>
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 SH |
31 | |
32 | class 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 |
157 | class 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 |
245 | class 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 | |
452 | class 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 |
548 | if __name__ == '__main__': |
549 | iotests.main(supported_fmts=['raw', 'qcow2']) |