]>
Commit | Line | Data |
---|---|---|
adfe2030 HR |
1 | #!/usr/bin/env python |
2 | # | |
3 | # Test case for the QMP 'change' command and all other associated | |
4 | # commands | |
5 | # | |
6 | # Copyright (C) 2015 Red Hat, Inc. | |
7 | # | |
8 | # This program is free software; you can redistribute it and/or modify | |
9 | # it under the terms of the GNU General Public License as published by | |
10 | # the Free Software Foundation; either version 2 of the License, or | |
11 | # (at your option) any later version. | |
12 | # | |
13 | # This program is distributed in the hope that it will be useful, | |
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | # GNU General Public License for more details. | |
17 | # | |
18 | # You should have received a copy of the GNU General Public License | |
19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 | # | |
21 | ||
22 | import os | |
23 | import stat | |
24 | import time | |
25 | import iotests | |
26 | from iotests import qemu_img | |
27 | ||
28 | old_img = os.path.join(iotests.test_dir, 'test0.img') | |
29 | new_img = os.path.join(iotests.test_dir, 'test1.img') | |
30 | ||
1d701e0e HR |
31 | def interface_to_device_name(interface): |
32 | if interface == 'ide': | |
33 | return 'ide-cd' | |
34 | elif interface == 'floppy': | |
35 | return 'floppy' | |
36 | else: | |
37 | return None | |
38 | ||
adfe2030 HR |
39 | class ChangeBaseClass(iotests.QMPTestCase): |
40 | has_opened = False | |
41 | has_closed = False | |
42 | ||
43 | def process_events(self): | |
44 | for event in self.vm.get_qmp_events(wait=False): | |
45 | if (event['event'] == 'DEVICE_TRAY_MOVED' and | |
46 | event['data']['device'] == 'drive0'): | |
47 | if event['data']['tray-open'] == False: | |
48 | self.has_closed = True | |
49 | else: | |
50 | self.has_opened = True | |
51 | ||
52 | def wait_for_open(self): | |
abb3e55b HR |
53 | if not self.has_real_tray: |
54 | return | |
55 | ||
d8336c6b KW |
56 | with iotests.Timeout(3, 'Timeout while waiting for the tray to open'): |
57 | while not self.has_opened: | |
58 | self.process_events() | |
adfe2030 HR |
59 | |
60 | def wait_for_close(self): | |
abb3e55b HR |
61 | if not self.has_real_tray: |
62 | return | |
63 | ||
d8336c6b KW |
64 | with iotests.Timeout(3, 'Timeout while waiting for the tray to close'): |
65 | while not self.has_closed: | |
66 | self.process_events() | |
adfe2030 HR |
67 | |
68 | class GeneralChangeTestsBaseClass(ChangeBaseClass): | |
486b88bd | 69 | |
1d701e0e | 70 | device_name = 'qdev0' |
486b88bd | 71 | |
adfe2030 HR |
72 | def test_change(self): |
73 | result = self.vm.qmp('change', device='drive0', target=new_img, | |
74 | arg=iotests.imgfmt) | |
75 | self.assert_qmp(result, 'return', {}) | |
76 | ||
77 | self.wait_for_open() | |
78 | self.wait_for_close() | |
79 | ||
80 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
81 | if self.has_real_tray: |
82 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
83 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
84 | ||
85 | def test_blockdev_change_medium(self): | |
1d701e0e HR |
86 | result = self.vm.qmp('blockdev-change-medium', |
87 | id=self.device_name, filename=new_img, | |
88 | format=iotests.imgfmt) | |
486b88bd | 89 | |
adfe2030 HR |
90 | self.assert_qmp(result, 'return', {}) |
91 | ||
92 | self.wait_for_open() | |
93 | self.wait_for_close() | |
94 | ||
95 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
96 | if self.has_real_tray: |
97 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
98 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
99 | ||
100 | def test_eject(self): | |
1d701e0e | 101 | result = self.vm.qmp('eject', id=self.device_name, force=True) |
adfe2030 HR |
102 | self.assert_qmp(result, 'return', {}) |
103 | ||
104 | self.wait_for_open() | |
105 | ||
106 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
107 | if self.has_real_tray: |
108 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
109 | self.assert_qmp_absent(result, 'return[0]/inserted') |
110 | ||
111 | def test_tray_eject_change(self): | |
1d701e0e | 112 | result = self.vm.qmp('eject', id=self.device_name, force=True) |
adfe2030 HR |
113 | self.assert_qmp(result, 'return', {}) |
114 | ||
115 | self.wait_for_open() | |
116 | ||
117 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
118 | if self.has_real_tray: |
119 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
120 | self.assert_qmp_absent(result, 'return[0]/inserted') |
121 | ||
1d701e0e HR |
122 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
123 | filename=new_img, format=iotests.imgfmt) | |
adfe2030 HR |
124 | self.assert_qmp(result, 'return', {}) |
125 | ||
126 | self.wait_for_close() | |
127 | ||
128 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
129 | if self.has_real_tray: |
130 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
131 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
132 | ||
133 | def test_tray_open_close(self): | |
1d701e0e HR |
134 | result = self.vm.qmp('blockdev-open-tray', |
135 | id=self.device_name, force=True) | |
adfe2030 HR |
136 | self.assert_qmp(result, 'return', {}) |
137 | ||
138 | self.wait_for_open() | |
139 | ||
140 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
141 | if self.has_real_tray: |
142 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
143 | if self.was_empty == True: |
144 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
145 | else: | |
146 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
147 | ||
1d701e0e | 148 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
149 | self.assert_qmp(result, 'return', {}) |
150 | ||
151 | if self.has_real_tray or not self.was_empty: | |
152 | self.wait_for_close() | |
153 | ||
154 | result = self.vm.qmp('query-block') | |
abb3e55b | 155 | if self.has_real_tray: |
adfe2030 | 156 | self.assert_qmp(result, 'return[0]/tray_open', False) |
adfe2030 HR |
157 | if self.was_empty == True: |
158 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
159 | else: | |
160 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
161 | ||
162 | def test_tray_eject_close(self): | |
1d701e0e | 163 | result = self.vm.qmp('eject', id=self.device_name, force=True) |
adfe2030 HR |
164 | self.assert_qmp(result, 'return', {}) |
165 | ||
166 | self.wait_for_open() | |
167 | ||
168 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
169 | if self.has_real_tray: |
170 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
171 | self.assert_qmp_absent(result, 'return[0]/inserted') |
172 | ||
1d701e0e | 173 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
174 | self.assert_qmp(result, 'return', {}) |
175 | ||
abb3e55b | 176 | self.wait_for_close() |
adfe2030 HR |
177 | |
178 | result = self.vm.qmp('query-block') | |
179 | if self.has_real_tray: | |
180 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
181 | self.assert_qmp_absent(result, 'return[0]/inserted') |
182 | ||
183 | def test_tray_open_change(self): | |
1d701e0e HR |
184 | result = self.vm.qmp('blockdev-open-tray', id=self.device_name, |
185 | force=True) | |
adfe2030 HR |
186 | self.assert_qmp(result, 'return', {}) |
187 | ||
188 | self.wait_for_open() | |
189 | ||
190 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
191 | if self.has_real_tray: |
192 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
193 | if self.was_empty == True: |
194 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
195 | else: | |
196 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
197 | ||
1d701e0e | 198 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
199 | filename=new_img, |
200 | format=iotests.imgfmt) | |
201 | self.assert_qmp(result, 'return', {}) | |
202 | ||
203 | self.wait_for_close() | |
204 | ||
205 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
206 | if self.has_real_tray: |
207 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
208 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
209 | ||
210 | def test_cycle(self): | |
211 | result = self.vm.qmp('blockdev-add', | |
0153d2f5 KW |
212 | node_name='new', |
213 | driver=iotests.imgfmt, | |
214 | file={'filename': new_img, | |
215 | 'driver': 'file'}) | |
adfe2030 HR |
216 | self.assert_qmp(result, 'return', {}) |
217 | ||
1d701e0e HR |
218 | result = self.vm.qmp('blockdev-open-tray', |
219 | id=self.device_name, force=True) | |
adfe2030 HR |
220 | self.assert_qmp(result, 'return', {}) |
221 | ||
222 | self.wait_for_open() | |
223 | ||
224 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
225 | if self.has_real_tray: |
226 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
227 | if self.was_empty == True: |
228 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
229 | else: | |
230 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
231 | ||
34ce1111 | 232 | result = self.vm.qmp('blockdev-remove-medium', |
1d701e0e | 233 | id=self.device_name) |
adfe2030 HR |
234 | self.assert_qmp(result, 'return', {}) |
235 | ||
236 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
237 | if self.has_real_tray: |
238 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
239 | self.assert_qmp_absent(result, 'return[0]/inserted') |
240 | ||
34ce1111 | 241 | result = self.vm.qmp('blockdev-insert-medium', |
1d701e0e | 242 | id=self.device_name, node_name='new') |
adfe2030 HR |
243 | self.assert_qmp(result, 'return', {}) |
244 | ||
245 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
246 | if self.has_real_tray: |
247 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
248 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
249 | ||
1d701e0e | 250 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
251 | self.assert_qmp(result, 'return', {}) |
252 | ||
253 | self.wait_for_close() | |
254 | ||
255 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
256 | if self.has_real_tray: |
257 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
258 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
259 | ||
260 | def test_close_on_closed(self): | |
1d701e0e | 261 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
262 | # Should be a no-op |
263 | self.assert_qmp(result, 'return', {}) | |
fa1cfb40 | 264 | self.assertEqual(self.vm.get_qmp_events(wait=False), []) |
adfe2030 HR |
265 | |
266 | def test_remove_on_closed(self): | |
abb3e55b | 267 | if not self.has_real_tray: |
adfe2030 HR |
268 | return |
269 | ||
34ce1111 | 270 | result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) |
adfe2030 HR |
271 | self.assert_qmp(result, 'error/class', 'GenericError') |
272 | ||
273 | def test_insert_on_closed(self): | |
abb3e55b | 274 | if not self.has_real_tray: |
adfe2030 HR |
275 | return |
276 | ||
277 | result = self.vm.qmp('blockdev-add', | |
0153d2f5 KW |
278 | node_name='new', |
279 | driver=iotests.imgfmt, | |
280 | file={'filename': new_img, | |
281 | 'driver': 'file'}) | |
adfe2030 HR |
282 | self.assert_qmp(result, 'return', {}) |
283 | ||
34ce1111 | 284 | result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, |
adfe2030 HR |
285 | node_name='new') |
286 | self.assert_qmp(result, 'error/class', 'GenericError') | |
287 | ||
288 | class TestInitiallyFilled(GeneralChangeTestsBaseClass): | |
289 | was_empty = False | |
290 | ||
291 | def setUp(self, media, interface): | |
292 | qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') | |
293 | qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') | |
486b88bd | 294 | self.vm = iotests.VM() |
1d701e0e HR |
295 | self.vm.add_drive(old_img, 'media=%s' % media, 'none') |
296 | self.vm.add_device('%s,drive=drive0,id=%s' % | |
297 | (interface_to_device_name(interface), | |
298 | self.device_name)) | |
adfe2030 HR |
299 | self.vm.launch() |
300 | ||
301 | def tearDown(self): | |
302 | self.vm.shutdown() | |
303 | os.remove(old_img) | |
304 | os.remove(new_img) | |
305 | ||
306 | def test_insert_on_filled(self): | |
307 | result = self.vm.qmp('blockdev-add', | |
0153d2f5 KW |
308 | node_name='new', |
309 | driver=iotests.imgfmt, | |
310 | file={'filename': new_img, | |
311 | 'driver': 'file'}) | |
adfe2030 HR |
312 | self.assert_qmp(result, 'return', {}) |
313 | ||
1d701e0e | 314 | result = self.vm.qmp('blockdev-open-tray', id=self.device_name) |
adfe2030 HR |
315 | self.assert_qmp(result, 'return', {}) |
316 | ||
317 | self.wait_for_open() | |
318 | ||
34ce1111 | 319 | result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, |
adfe2030 HR |
320 | node_name='new') |
321 | self.assert_qmp(result, 'error/class', 'GenericError') | |
322 | ||
323 | class TestInitiallyEmpty(GeneralChangeTestsBaseClass): | |
324 | was_empty = True | |
325 | ||
326 | def setUp(self, media, interface): | |
327 | qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') | |
1d701e0e HR |
328 | self.vm = iotests.VM().add_drive(None, 'media=%s' % media, 'none') |
329 | self.vm.add_device('%s,drive=drive0,id=%s' % | |
330 | (interface_to_device_name(interface), | |
331 | self.device_name)) | |
adfe2030 HR |
332 | self.vm.launch() |
333 | ||
334 | def tearDown(self): | |
335 | self.vm.shutdown() | |
336 | os.remove(new_img) | |
337 | ||
338 | def test_remove_on_empty(self): | |
1d701e0e | 339 | result = self.vm.qmp('blockdev-open-tray', id=self.device_name) |
adfe2030 HR |
340 | self.assert_qmp(result, 'return', {}) |
341 | ||
342 | self.wait_for_open() | |
343 | ||
34ce1111 | 344 | result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) |
adfe2030 HR |
345 | # Should be a no-op |
346 | self.assert_qmp(result, 'return', {}) | |
347 | ||
348 | class TestCDInitiallyFilled(TestInitiallyFilled): | |
349 | TestInitiallyFilled = TestInitiallyFilled | |
350 | has_real_tray = True | |
351 | ||
352 | def setUp(self): | |
353 | self.TestInitiallyFilled.setUp(self, 'cdrom', 'ide') | |
354 | ||
355 | class TestCDInitiallyEmpty(TestInitiallyEmpty): | |
356 | TestInitiallyEmpty = TestInitiallyEmpty | |
357 | has_real_tray = True | |
358 | ||
359 | def setUp(self): | |
360 | self.TestInitiallyEmpty.setUp(self, 'cdrom', 'ide') | |
361 | ||
362 | class TestFloppyInitiallyFilled(TestInitiallyFilled): | |
363 | TestInitiallyFilled = TestInitiallyFilled | |
364 | has_real_tray = False | |
365 | ||
366 | def setUp(self): | |
367 | self.TestInitiallyFilled.setUp(self, 'disk', 'floppy') | |
368 | ||
369 | class TestFloppyInitiallyEmpty(TestInitiallyEmpty): | |
370 | TestInitiallyEmpty = TestInitiallyEmpty | |
371 | has_real_tray = False | |
372 | ||
373 | def setUp(self): | |
374 | self.TestInitiallyEmpty.setUp(self, 'disk', 'floppy') | |
375 | # FDDs not having a real tray and there not being a medium inside the | |
376 | # tray at startup means the tray will be considered open | |
377 | self.has_opened = True | |
378 | ||
379 | class TestChangeReadOnly(ChangeBaseClass): | |
1d701e0e HR |
380 | device_name = 'qdev0' |
381 | ||
adfe2030 HR |
382 | def setUp(self): |
383 | qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') | |
384 | qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') | |
385 | self.vm = iotests.VM() | |
386 | ||
387 | def tearDown(self): | |
388 | self.vm.shutdown() | |
4803c5cd EH |
389 | os.chmod(old_img, 0o666) |
390 | os.chmod(new_img, 0o666) | |
adfe2030 HR |
391 | os.remove(old_img) |
392 | os.remove(new_img) | |
393 | ||
394 | def test_ro_ro_retain(self): | |
4803c5cd EH |
395 | os.chmod(old_img, 0o444) |
396 | os.chmod(new_img, 0o444) | |
1d701e0e HR |
397 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
398 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
399 | self.vm.launch() |
400 | ||
401 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
402 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
403 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
404 | ||
1d701e0e | 405 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
406 | filename=new_img, |
407 | format=iotests.imgfmt, | |
408 | read_only_mode='retain') | |
409 | self.assert_qmp(result, 'return', {}) | |
410 | ||
adfe2030 | 411 | result = self.vm.qmp('query-block') |
adfe2030 HR |
412 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
413 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
414 | ||
415 | def test_ro_rw_retain(self): | |
4803c5cd | 416 | os.chmod(old_img, 0o444) |
1d701e0e HR |
417 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
418 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
419 | self.vm.launch() |
420 | ||
421 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
422 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
423 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
424 | ||
1d701e0e | 425 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
426 | filename=new_img, |
427 | format=iotests.imgfmt, | |
428 | read_only_mode='retain') | |
429 | self.assert_qmp(result, 'return', {}) | |
430 | ||
adfe2030 | 431 | result = self.vm.qmp('query-block') |
adfe2030 HR |
432 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
433 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
434 | ||
435 | def test_rw_ro_retain(self): | |
4803c5cd | 436 | os.chmod(new_img, 0o444) |
1d701e0e HR |
437 | self.vm.add_drive(old_img, 'media=disk', 'none') |
438 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
439 | self.vm.launch() |
440 | ||
441 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
442 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
443 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
444 | ||
1d701e0e | 445 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
446 | filename=new_img, |
447 | format=iotests.imgfmt, | |
448 | read_only_mode='retain') | |
449 | self.assert_qmp(result, 'error/class', 'GenericError') | |
450 | ||
fa1cfb40 | 451 | self.assertEqual(self.vm.get_qmp_events(wait=False), []) |
adfe2030 HR |
452 | |
453 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
454 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
455 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
456 | ||
457 | def test_ro_rw(self): | |
4803c5cd | 458 | os.chmod(old_img, 0o444) |
1d701e0e HR |
459 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
460 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
461 | self.vm.launch() |
462 | ||
463 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
464 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
465 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
466 | ||
467 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 468 | id=self.device_name, |
adfe2030 HR |
469 | filename=new_img, |
470 | format=iotests.imgfmt, | |
471 | read_only_mode='read-write') | |
472 | self.assert_qmp(result, 'return', {}) | |
473 | ||
adfe2030 | 474 | result = self.vm.qmp('query-block') |
adfe2030 HR |
475 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
476 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
477 | ||
478 | def test_rw_ro(self): | |
4803c5cd | 479 | os.chmod(new_img, 0o444) |
1d701e0e HR |
480 | self.vm.add_drive(old_img, 'media=disk', 'none') |
481 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
482 | self.vm.launch() |
483 | ||
484 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
485 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
486 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
487 | ||
488 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 489 | id=self.device_name, |
adfe2030 HR |
490 | filename=new_img, |
491 | format=iotests.imgfmt, | |
492 | read_only_mode='read-only') | |
493 | self.assert_qmp(result, 'return', {}) | |
494 | ||
adfe2030 | 495 | result = self.vm.qmp('query-block') |
adfe2030 HR |
496 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
497 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
498 | ||
499 | def test_make_rw_ro(self): | |
1d701e0e HR |
500 | self.vm.add_drive(old_img, 'media=disk', 'none') |
501 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
502 | self.vm.launch() |
503 | ||
504 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
505 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
506 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
507 | ||
508 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 509 | id=self.device_name, |
adfe2030 HR |
510 | filename=new_img, |
511 | format=iotests.imgfmt, | |
512 | read_only_mode='read-only') | |
513 | self.assert_qmp(result, 'return', {}) | |
514 | ||
adfe2030 | 515 | result = self.vm.qmp('query-block') |
adfe2030 HR |
516 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
517 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
518 | ||
519 | def test_make_ro_rw(self): | |
4803c5cd | 520 | os.chmod(new_img, 0o444) |
1d701e0e HR |
521 | self.vm.add_drive(old_img, 'media=disk', 'none') |
522 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
523 | self.vm.launch() |
524 | ||
525 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
526 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
527 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
528 | ||
529 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 530 | id=self.device_name, |
adfe2030 HR |
531 | filename=new_img, |
532 | format=iotests.imgfmt, | |
533 | read_only_mode='read-write') | |
534 | self.assert_qmp(result, 'error/class', 'GenericError') | |
535 | ||
adfe2030 | 536 | result = self.vm.qmp('query-block') |
adfe2030 HR |
537 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
538 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
539 | ||
540 | def test_make_rw_ro_by_retain(self): | |
4803c5cd | 541 | os.chmod(old_img, 0o444) |
1d701e0e HR |
542 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
543 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
544 | self.vm.launch() |
545 | ||
546 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
547 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
548 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
549 | ||
1d701e0e | 550 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
551 | filename=new_img, |
552 | format=iotests.imgfmt, | |
553 | read_only_mode='retain') | |
554 | self.assert_qmp(result, 'return', {}) | |
555 | ||
adfe2030 | 556 | result = self.vm.qmp('query-block') |
adfe2030 HR |
557 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
558 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
559 | ||
560 | def test_make_ro_rw_by_retain(self): | |
4803c5cd | 561 | os.chmod(new_img, 0o444) |
1d701e0e HR |
562 | self.vm.add_drive(old_img, 'media=disk', 'none') |
563 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
564 | self.vm.launch() |
565 | ||
566 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
567 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
568 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
569 | ||
1d701e0e | 570 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
571 | filename=new_img, |
572 | format=iotests.imgfmt, | |
573 | read_only_mode='retain') | |
574 | self.assert_qmp(result, 'error/class', 'GenericError') | |
575 | ||
adfe2030 | 576 | result = self.vm.qmp('query-block') |
adfe2030 HR |
577 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
578 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
579 | ||
580 | def test_rw_ro_cycle(self): | |
4803c5cd | 581 | os.chmod(new_img, 0o444) |
1d701e0e HR |
582 | self.vm.add_drive(old_img, 'media=disk', 'none') |
583 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
584 | self.vm.launch() |
585 | ||
586 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
587 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
588 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
589 | ||
590 | result = self.vm.qmp('blockdev-add', | |
0153d2f5 KW |
591 | node_name='new', |
592 | driver=iotests.imgfmt, | |
593 | read_only=True, | |
594 | file={'filename': new_img, | |
595 | 'driver': 'file'}) | |
adfe2030 HR |
596 | self.assert_qmp(result, 'return', {}) |
597 | ||
adfe2030 | 598 | result = self.vm.qmp('query-block') |
adfe2030 HR |
599 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
600 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
601 | ||
34ce1111 | 602 | result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) |
adfe2030 HR |
603 | self.assert_qmp(result, 'return', {}) |
604 | ||
605 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
606 | self.assert_qmp_absent(result, 'return[0]/inserted') |
607 | ||
34ce1111 | 608 | result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, |
adfe2030 HR |
609 | node_name='new') |
610 | self.assert_qmp(result, 'return', {}) | |
611 | ||
612 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
613 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
614 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
615 | ||
adfe2030 | 616 | result = self.vm.qmp('query-block') |
adfe2030 HR |
617 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
618 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
619 | ||
620 | GeneralChangeTestsBaseClass = None | |
621 | TestInitiallyFilled = None | |
622 | TestInitiallyEmpty = None | |
623 | ||
624 | ||
625 | class TestBlockJobsAfterCycle(ChangeBaseClass): | |
1d701e0e HR |
626 | device_name = 'qdev0' |
627 | ||
adfe2030 | 628 | def setUp(self): |
1d701e0e | 629 | qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K') |
adfe2030 HR |
630 | |
631 | self.vm = iotests.VM() | |
e4fd2e9d | 632 | self.vm.add_drive_raw("id=drive0,driver=null-co,if=none") |
1d701e0e | 633 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) |
adfe2030 HR |
634 | self.vm.launch() |
635 | ||
adfe2030 | 636 | result = self.vm.qmp('query-block') |
adfe2030 HR |
637 | self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co') |
638 | ||
639 | # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray | |
640 | # is not necessary | |
34ce1111 | 641 | result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) |
adfe2030 HR |
642 | self.assert_qmp(result, 'return', {}) |
643 | ||
644 | result = self.vm.qmp('query-block') | |
645 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
646 | ||
647 | result = self.vm.qmp('blockdev-add', | |
0153d2f5 KW |
648 | node_name='node0', |
649 | driver=iotests.imgfmt, | |
650 | file={'filename': old_img, | |
651 | 'driver': 'file'}) | |
adfe2030 HR |
652 | self.assert_qmp(result, 'return', {}) |
653 | ||
34ce1111 | 654 | result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, |
adfe2030 HR |
655 | node_name='node0') |
656 | self.assert_qmp(result, 'return', {}) | |
657 | ||
658 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
659 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) |
660 | ||
661 | def tearDown(self): | |
662 | self.vm.shutdown() | |
663 | os.remove(old_img) | |
664 | try: | |
665 | os.remove(new_img) | |
666 | except OSError: | |
667 | pass | |
668 | ||
669 | def test_snapshot_and_commit(self): | |
670 | # We need backing file support | |
671 | if iotests.imgfmt != 'qcow2' and iotests.imgfmt != 'qed': | |
672 | return | |
673 | ||
674 | result = self.vm.qmp('blockdev-snapshot-sync', device='drive0', | |
675 | snapshot_file=new_img, | |
676 | format=iotests.imgfmt) | |
677 | self.assert_qmp(result, 'return', {}) | |
678 | ||
679 | result = self.vm.qmp('query-block') | |
680 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
681 | self.assert_qmp(result, | |
682 | 'return[0]/inserted/image/backing-image/filename', | |
683 | old_img) | |
684 | ||
685 | result = self.vm.qmp('block-commit', device='drive0') | |
686 | self.assert_qmp(result, 'return', {}) | |
687 | ||
688 | self.vm.event_wait(name='BLOCK_JOB_READY') | |
689 | ||
690 | result = self.vm.qmp('query-block-jobs') | |
691 | self.assert_qmp(result, 'return[0]/device', 'drive0') | |
692 | ||
693 | result = self.vm.qmp('block-job-complete', device='drive0') | |
694 | self.assert_qmp(result, 'return', {}) | |
695 | ||
696 | self.vm.event_wait(name='BLOCK_JOB_COMPLETED') | |
697 | ||
698 | ||
699 | if __name__ == '__main__': | |
700 | if iotests.qemu_default_machine != 'pc': | |
701 | # We need floppy and IDE CD-ROM | |
702 | iotests.notrun('not suitable for this machine type: %s' % | |
703 | iotests.qemu_default_machine) | |
cc8c46b7 HR |
704 | # Need to support image creation |
705 | iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2', | |
706 | 'vmdk', 'raw', 'vhdx', 'qed']) |