]>
Commit | Line | Data |
---|---|---|
903cb1bf | 1 | #!/usr/bin/env python3 |
9dd003a9 | 2 | # group: rw |
adfe2030 | 3 | # |
014bb4b0 | 4 | # Test case for media change monitor commands |
adfe2030 HR |
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' | |
dfa26a11 KW |
36 | elif interface == 'scsi': |
37 | return 'scsi-cd' | |
1d701e0e HR |
38 | else: |
39 | return None | |
40 | ||
adfe2030 HR |
41 | class ChangeBaseClass(iotests.QMPTestCase): |
42 | has_opened = False | |
43 | has_closed = False | |
44 | ||
19462c4b KW |
45 | device_name = 'qdev0' |
46 | use_drive = False | |
47 | ||
adfe2030 HR |
48 | def process_events(self): |
49 | for event in self.vm.get_qmp_events(wait=False): | |
50 | if (event['event'] == 'DEVICE_TRAY_MOVED' and | |
19462c4b KW |
51 | (event['data']['device'] == 'drive0' or |
52 | event['data']['id'] == self.device_name)): | |
adfe2030 HR |
53 | if event['data']['tray-open'] == False: |
54 | self.has_closed = True | |
55 | else: | |
56 | self.has_opened = True | |
57 | ||
58 | def wait_for_open(self): | |
abb3e55b HR |
59 | if not self.has_real_tray: |
60 | return | |
61 | ||
d8336c6b KW |
62 | with iotests.Timeout(3, 'Timeout while waiting for the tray to open'): |
63 | while not self.has_opened: | |
64 | self.process_events() | |
adfe2030 HR |
65 | |
66 | def wait_for_close(self): | |
abb3e55b HR |
67 | if not self.has_real_tray: |
68 | return | |
69 | ||
d8336c6b KW |
70 | with iotests.Timeout(3, 'Timeout while waiting for the tray to close'): |
71 | while not self.has_closed: | |
72 | self.process_events() | |
adfe2030 HR |
73 | |
74 | class GeneralChangeTestsBaseClass(ChangeBaseClass): | |
486b88bd | 75 | |
adfe2030 | 76 | def test_blockdev_change_medium(self): |
1d701e0e HR |
77 | result = self.vm.qmp('blockdev-change-medium', |
78 | id=self.device_name, filename=new_img, | |
79 | format=iotests.imgfmt) | |
486b88bd | 80 | |
adfe2030 HR |
81 | self.assert_qmp(result, 'return', {}) |
82 | ||
83 | self.wait_for_open() | |
84 | self.wait_for_close() | |
85 | ||
86 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
87 | if self.has_real_tray: |
88 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
89 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
90 | ||
91 | def test_eject(self): | |
1d701e0e | 92 | result = self.vm.qmp('eject', id=self.device_name, force=True) |
adfe2030 HR |
93 | self.assert_qmp(result, 'return', {}) |
94 | ||
95 | self.wait_for_open() | |
96 | ||
97 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
98 | if self.has_real_tray: |
99 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
100 | self.assert_qmp_absent(result, 'return[0]/inserted') |
101 | ||
102 | def test_tray_eject_change(self): | |
1d701e0e | 103 | result = self.vm.qmp('eject', id=self.device_name, force=True) |
adfe2030 HR |
104 | self.assert_qmp(result, 'return', {}) |
105 | ||
106 | self.wait_for_open() | |
107 | ||
108 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
109 | if self.has_real_tray: |
110 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
111 | self.assert_qmp_absent(result, 'return[0]/inserted') |
112 | ||
1d701e0e HR |
113 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
114 | filename=new_img, format=iotests.imgfmt) | |
adfe2030 HR |
115 | self.assert_qmp(result, 'return', {}) |
116 | ||
117 | self.wait_for_close() | |
118 | ||
119 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
120 | if self.has_real_tray: |
121 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
122 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
123 | ||
124 | def test_tray_open_close(self): | |
1d701e0e HR |
125 | result = self.vm.qmp('blockdev-open-tray', |
126 | id=self.device_name, force=True) | |
adfe2030 HR |
127 | self.assert_qmp(result, 'return', {}) |
128 | ||
129 | self.wait_for_open() | |
130 | ||
131 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
132 | if self.has_real_tray: |
133 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
134 | if self.was_empty == True: |
135 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
136 | else: | |
137 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
138 | ||
1d701e0e | 139 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
140 | self.assert_qmp(result, 'return', {}) |
141 | ||
142 | if self.has_real_tray or not self.was_empty: | |
143 | self.wait_for_close() | |
144 | ||
145 | result = self.vm.qmp('query-block') | |
abb3e55b | 146 | if self.has_real_tray: |
adfe2030 | 147 | self.assert_qmp(result, 'return[0]/tray_open', False) |
adfe2030 HR |
148 | if self.was_empty == True: |
149 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
150 | else: | |
151 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
152 | ||
153 | def test_tray_eject_close(self): | |
1d701e0e | 154 | result = self.vm.qmp('eject', id=self.device_name, force=True) |
adfe2030 HR |
155 | self.assert_qmp(result, 'return', {}) |
156 | ||
157 | self.wait_for_open() | |
158 | ||
159 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
160 | if self.has_real_tray: |
161 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
162 | self.assert_qmp_absent(result, 'return[0]/inserted') |
163 | ||
1d701e0e | 164 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
165 | self.assert_qmp(result, 'return', {}) |
166 | ||
abb3e55b | 167 | self.wait_for_close() |
adfe2030 HR |
168 | |
169 | result = self.vm.qmp('query-block') | |
170 | if self.has_real_tray: | |
171 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
172 | self.assert_qmp_absent(result, 'return[0]/inserted') |
173 | ||
174 | def test_tray_open_change(self): | |
1d701e0e HR |
175 | result = self.vm.qmp('blockdev-open-tray', id=self.device_name, |
176 | force=True) | |
adfe2030 HR |
177 | self.assert_qmp(result, 'return', {}) |
178 | ||
179 | self.wait_for_open() | |
180 | ||
181 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
182 | if self.has_real_tray: |
183 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
184 | if self.was_empty == True: |
185 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
186 | else: | |
187 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
188 | ||
1d701e0e | 189 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
190 | filename=new_img, |
191 | format=iotests.imgfmt) | |
192 | self.assert_qmp(result, 'return', {}) | |
193 | ||
194 | self.wait_for_close() | |
195 | ||
196 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
197 | if self.has_real_tray: |
198 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
199 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
200 | ||
68174160 | 201 | def test_cycle(self, read_only_node=False): |
adfe2030 | 202 | result = self.vm.qmp('blockdev-add', |
0153d2f5 KW |
203 | node_name='new', |
204 | driver=iotests.imgfmt, | |
68174160 | 205 | read_only=read_only_node, |
0153d2f5 KW |
206 | file={'filename': new_img, |
207 | 'driver': 'file'}) | |
adfe2030 HR |
208 | self.assert_qmp(result, 'return', {}) |
209 | ||
1d701e0e HR |
210 | result = self.vm.qmp('blockdev-open-tray', |
211 | id=self.device_name, force=True) | |
adfe2030 HR |
212 | self.assert_qmp(result, 'return', {}) |
213 | ||
214 | self.wait_for_open() | |
215 | ||
216 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
217 | if self.has_real_tray: |
218 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
219 | if self.was_empty == True: |
220 | self.assert_qmp_absent(result, 'return[0]/inserted') | |
221 | else: | |
222 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
223 | ||
34ce1111 | 224 | result = self.vm.qmp('blockdev-remove-medium', |
1d701e0e | 225 | id=self.device_name) |
adfe2030 HR |
226 | self.assert_qmp(result, 'return', {}) |
227 | ||
228 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
229 | if self.has_real_tray: |
230 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
231 | self.assert_qmp_absent(result, 'return[0]/inserted') |
232 | ||
34ce1111 | 233 | result = self.vm.qmp('blockdev-insert-medium', |
1d701e0e | 234 | id=self.device_name, node_name='new') |
adfe2030 HR |
235 | self.assert_qmp(result, 'return', {}) |
236 | ||
237 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
238 | if self.has_real_tray: |
239 | self.assert_qmp(result, 'return[0]/tray_open', True) | |
adfe2030 HR |
240 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
241 | ||
1d701e0e | 242 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
243 | self.assert_qmp(result, 'return', {}) |
244 | ||
245 | self.wait_for_close() | |
246 | ||
247 | result = self.vm.qmp('query-block') | |
abb3e55b HR |
248 | if self.has_real_tray: |
249 | self.assert_qmp(result, 'return[0]/tray_open', False) | |
adfe2030 HR |
250 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) |
251 | ||
68174160 KW |
252 | def test_cycle_read_only_media(self): |
253 | self.test_cycle(True) | |
254 | ||
adfe2030 | 255 | def test_close_on_closed(self): |
1d701e0e | 256 | result = self.vm.qmp('blockdev-close-tray', id=self.device_name) |
adfe2030 HR |
257 | # Should be a no-op |
258 | self.assert_qmp(result, 'return', {}) | |
fa1cfb40 | 259 | self.assertEqual(self.vm.get_qmp_events(wait=False), []) |
adfe2030 HR |
260 | |
261 | def test_remove_on_closed(self): | |
abb3e55b | 262 | if not self.has_real_tray: |
adfe2030 HR |
263 | return |
264 | ||
34ce1111 | 265 | result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) |
adfe2030 HR |
266 | self.assert_qmp(result, 'error/class', 'GenericError') |
267 | ||
268 | def test_insert_on_closed(self): | |
abb3e55b | 269 | if not self.has_real_tray: |
adfe2030 HR |
270 | return |
271 | ||
272 | result = self.vm.qmp('blockdev-add', | |
0153d2f5 KW |
273 | node_name='new', |
274 | driver=iotests.imgfmt, | |
275 | file={'filename': new_img, | |
276 | 'driver': 'file'}) | |
adfe2030 HR |
277 | self.assert_qmp(result, 'return', {}) |
278 | ||
34ce1111 | 279 | result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, |
adfe2030 HR |
280 | node_name='new') |
281 | self.assert_qmp(result, 'error/class', 'GenericError') | |
282 | ||
283 | class TestInitiallyFilled(GeneralChangeTestsBaseClass): | |
284 | was_empty = False | |
285 | ||
dfc82894 | 286 | def setUp(self): |
adfe2030 HR |
287 | qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') |
288 | qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') | |
486b88bd | 289 | self.vm = iotests.VM() |
19462c4b KW |
290 | if self.use_drive: |
291 | self.vm.add_drive(old_img, 'media=%s' % self.media, 'none') | |
292 | else: | |
293 | self.vm.add_blockdev([ 'node-name=drive0', | |
294 | 'driver=%s' % iotests.imgfmt, | |
295 | 'file.driver=file', | |
296 | 'file.filename=%s' % old_img ]) | |
dfc82894 | 297 | if self.interface == 'scsi': |
dfa26a11 | 298 | self.vm.add_device('virtio-scsi-pci') |
1d701e0e | 299 | self.vm.add_device('%s,drive=drive0,id=%s' % |
dfc82894 | 300 | (interface_to_device_name(self.interface), |
1d701e0e | 301 | self.device_name)) |
adfe2030 HR |
302 | self.vm.launch() |
303 | ||
304 | def tearDown(self): | |
305 | self.vm.shutdown() | |
306 | os.remove(old_img) | |
307 | os.remove(new_img) | |
308 | ||
309 | def test_insert_on_filled(self): | |
310 | result = self.vm.qmp('blockdev-add', | |
0153d2f5 KW |
311 | node_name='new', |
312 | driver=iotests.imgfmt, | |
313 | file={'filename': new_img, | |
314 | 'driver': 'file'}) | |
adfe2030 HR |
315 | self.assert_qmp(result, 'return', {}) |
316 | ||
1d701e0e | 317 | result = self.vm.qmp('blockdev-open-tray', id=self.device_name) |
adfe2030 HR |
318 | self.assert_qmp(result, 'return', {}) |
319 | ||
320 | self.wait_for_open() | |
321 | ||
34ce1111 | 322 | result = self.vm.qmp('blockdev-insert-medium', id=self.device_name, |
adfe2030 HR |
323 | node_name='new') |
324 | self.assert_qmp(result, 'error/class', 'GenericError') | |
325 | ||
326 | class TestInitiallyEmpty(GeneralChangeTestsBaseClass): | |
327 | was_empty = True | |
328 | ||
dfc82894 | 329 | def setUp(self): |
adfe2030 | 330 | qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') |
19462c4b KW |
331 | self.vm = iotests.VM() |
332 | if self.use_drive: | |
333 | self.vm.add_drive(None, 'media=%s' % self.media, 'none') | |
dfc82894 | 334 | if self.interface == 'scsi': |
dfa26a11 | 335 | self.vm.add_device('virtio-scsi-pci') |
19462c4b | 336 | self.vm.add_device('%s,%sid=%s' % |
dfc82894 | 337 | (interface_to_device_name(self.interface), |
19462c4b | 338 | 'drive=drive0,' if self.use_drive else '', |
1d701e0e | 339 | self.device_name)) |
adfe2030 HR |
340 | self.vm.launch() |
341 | ||
342 | def tearDown(self): | |
343 | self.vm.shutdown() | |
344 | os.remove(new_img) | |
345 | ||
346 | def test_remove_on_empty(self): | |
1d701e0e | 347 | result = self.vm.qmp('blockdev-open-tray', id=self.device_name) |
adfe2030 HR |
348 | self.assert_qmp(result, 'return', {}) |
349 | ||
350 | self.wait_for_open() | |
351 | ||
34ce1111 | 352 | result = self.vm.qmp('blockdev-remove-medium', id=self.device_name) |
adfe2030 HR |
353 | # Should be a no-op |
354 | self.assert_qmp(result, 'return', {}) | |
355 | ||
dfc82894 KW |
356 | # Do this in a function to avoid leaking variables like case into the global |
357 | # name space (otherwise tests would be run for the abstract base classes) | |
358 | def create_basic_test_classes(): | |
359 | for (media, interface, has_real_tray) in [ ('cdrom', 'ide', True), | |
360 | ('cdrom', 'scsi', True), | |
361 | ('disk', 'floppy', False) ]: | |
adfe2030 | 362 | |
dfc82894 | 363 | for case in [ TestInitiallyFilled, TestInitiallyEmpty ]: |
19462c4b KW |
364 | for use_drive in [ True, False ]: |
365 | attr = { 'media': media, | |
366 | 'interface': interface, | |
367 | 'has_real_tray': has_real_tray, | |
368 | 'use_drive': use_drive } | |
369 | ||
370 | name = '%s_%s_%s_%s' % (case.__name__, media, interface, | |
371 | 'drive' if use_drive else 'blockdev') | |
372 | globals()[name] = type(name, (case, ), attr) | |
dfa26a11 | 373 | |
dfc82894 | 374 | create_basic_test_classes() |
adfe2030 HR |
375 | |
376 | class TestChangeReadOnly(ChangeBaseClass): | |
1d701e0e HR |
377 | device_name = 'qdev0' |
378 | ||
adfe2030 HR |
379 | def setUp(self): |
380 | qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k') | |
381 | qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k') | |
382 | self.vm = iotests.VM() | |
383 | ||
384 | def tearDown(self): | |
385 | self.vm.shutdown() | |
4803c5cd EH |
386 | os.chmod(old_img, 0o666) |
387 | os.chmod(new_img, 0o666) | |
adfe2030 HR |
388 | os.remove(old_img) |
389 | os.remove(new_img) | |
390 | ||
391 | def test_ro_ro_retain(self): | |
4803c5cd EH |
392 | os.chmod(old_img, 0o444) |
393 | os.chmod(new_img, 0o444) | |
1d701e0e HR |
394 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
395 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
396 | self.vm.launch() |
397 | ||
398 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
399 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
400 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
401 | ||
1d701e0e | 402 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
403 | filename=new_img, |
404 | format=iotests.imgfmt, | |
405 | read_only_mode='retain') | |
406 | self.assert_qmp(result, 'return', {}) | |
407 | ||
adfe2030 | 408 | result = self.vm.qmp('query-block') |
adfe2030 HR |
409 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
410 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
411 | ||
412 | def test_ro_rw_retain(self): | |
4803c5cd | 413 | os.chmod(old_img, 0o444) |
1d701e0e HR |
414 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
415 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
416 | self.vm.launch() |
417 | ||
418 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
419 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
420 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
421 | ||
1d701e0e | 422 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
423 | filename=new_img, |
424 | format=iotests.imgfmt, | |
425 | read_only_mode='retain') | |
426 | self.assert_qmp(result, 'return', {}) | |
427 | ||
adfe2030 | 428 | result = self.vm.qmp('query-block') |
adfe2030 HR |
429 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
430 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
431 | ||
d926f4dd | 432 | @iotests.skip_if_user_is_root |
adfe2030 | 433 | def test_rw_ro_retain(self): |
4803c5cd | 434 | os.chmod(new_img, 0o444) |
1d701e0e HR |
435 | self.vm.add_drive(old_img, 'media=disk', 'none') |
436 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
437 | self.vm.launch() |
438 | ||
439 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
440 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
441 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
442 | ||
1d701e0e | 443 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
444 | filename=new_img, |
445 | format=iotests.imgfmt, | |
446 | read_only_mode='retain') | |
447 | self.assert_qmp(result, 'error/class', 'GenericError') | |
448 | ||
fa1cfb40 | 449 | self.assertEqual(self.vm.get_qmp_events(wait=False), []) |
adfe2030 HR |
450 | |
451 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
452 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
453 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
454 | ||
455 | def test_ro_rw(self): | |
4803c5cd | 456 | os.chmod(old_img, 0o444) |
1d701e0e HR |
457 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
458 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
459 | self.vm.launch() |
460 | ||
461 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
462 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
463 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
464 | ||
465 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 466 | id=self.device_name, |
adfe2030 HR |
467 | filename=new_img, |
468 | format=iotests.imgfmt, | |
469 | read_only_mode='read-write') | |
470 | self.assert_qmp(result, 'return', {}) | |
471 | ||
adfe2030 | 472 | result = self.vm.qmp('query-block') |
adfe2030 HR |
473 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
474 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
475 | ||
476 | def test_rw_ro(self): | |
4803c5cd | 477 | os.chmod(new_img, 0o444) |
1d701e0e HR |
478 | self.vm.add_drive(old_img, 'media=disk', 'none') |
479 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
480 | self.vm.launch() |
481 | ||
482 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
483 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
484 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
485 | ||
486 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 487 | id=self.device_name, |
adfe2030 HR |
488 | filename=new_img, |
489 | format=iotests.imgfmt, | |
490 | read_only_mode='read-only') | |
491 | self.assert_qmp(result, 'return', {}) | |
492 | ||
adfe2030 | 493 | result = self.vm.qmp('query-block') |
adfe2030 HR |
494 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
495 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
496 | ||
497 | def test_make_rw_ro(self): | |
1d701e0e HR |
498 | self.vm.add_drive(old_img, 'media=disk', 'none') |
499 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
500 | self.vm.launch() |
501 | ||
502 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
503 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
504 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
505 | ||
506 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 507 | id=self.device_name, |
adfe2030 HR |
508 | filename=new_img, |
509 | format=iotests.imgfmt, | |
510 | read_only_mode='read-only') | |
511 | self.assert_qmp(result, 'return', {}) | |
512 | ||
adfe2030 | 513 | result = self.vm.qmp('query-block') |
adfe2030 HR |
514 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
515 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
516 | ||
d926f4dd | 517 | @iotests.skip_if_user_is_root |
adfe2030 | 518 | def test_make_ro_rw(self): |
4803c5cd | 519 | os.chmod(new_img, 0o444) |
1d701e0e HR |
520 | self.vm.add_drive(old_img, 'media=disk', 'none') |
521 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
522 | self.vm.launch() |
523 | ||
524 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
525 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
526 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
527 | ||
528 | result = self.vm.qmp('blockdev-change-medium', | |
1d701e0e | 529 | id=self.device_name, |
adfe2030 HR |
530 | filename=new_img, |
531 | format=iotests.imgfmt, | |
532 | read_only_mode='read-write') | |
533 | self.assert_qmp(result, 'error/class', 'GenericError') | |
534 | ||
adfe2030 | 535 | result = self.vm.qmp('query-block') |
adfe2030 HR |
536 | self.assert_qmp(result, 'return[0]/inserted/ro', False) |
537 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
538 | ||
539 | def test_make_rw_ro_by_retain(self): | |
4803c5cd | 540 | os.chmod(old_img, 0o444) |
1d701e0e HR |
541 | self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none') |
542 | self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name) | |
adfe2030 HR |
543 | self.vm.launch() |
544 | ||
545 | result = self.vm.qmp('query-block') | |
adfe2030 HR |
546 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
547 | self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img) | |
548 | ||
1d701e0e | 549 | result = self.vm.qmp('blockdev-change-medium', id=self.device_name, |
adfe2030 HR |
550 | filename=new_img, |
551 | format=iotests.imgfmt, | |
552 | read_only_mode='retain') | |
553 | self.assert_qmp(result, 'return', {}) | |
554 | ||
adfe2030 | 555 | result = self.vm.qmp('query-block') |
adfe2030 HR |
556 | self.assert_qmp(result, 'return[0]/inserted/ro', True) |
557 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
558 | ||
d926f4dd | 559 | @iotests.skip_if_user_is_root |
adfe2030 | 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 | ||
ff3caf5a HR |
669 | # We need backing file support |
670 | @iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw', | |
671 | 'vhdx')) | |
adfe2030 | 672 | def test_snapshot_and_commit(self): |
adfe2030 HR |
673 | result = self.vm.qmp('blockdev-snapshot-sync', device='drive0', |
674 | snapshot_file=new_img, | |
675 | format=iotests.imgfmt) | |
676 | self.assert_qmp(result, 'return', {}) | |
677 | ||
678 | result = self.vm.qmp('query-block') | |
679 | self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img) | |
680 | self.assert_qmp(result, | |
681 | 'return[0]/inserted/image/backing-image/filename', | |
682 | old_img) | |
683 | ||
684 | result = self.vm.qmp('block-commit', device='drive0') | |
685 | self.assert_qmp(result, 'return', {}) | |
686 | ||
687 | self.vm.event_wait(name='BLOCK_JOB_READY') | |
688 | ||
689 | result = self.vm.qmp('query-block-jobs') | |
690 | self.assert_qmp(result, 'return[0]/device', 'drive0') | |
691 | ||
692 | result = self.vm.qmp('block-job-complete', device='drive0') | |
693 | self.assert_qmp(result, 'return', {}) | |
694 | ||
695 | self.vm.event_wait(name='BLOCK_JOB_COMPLETED') | |
696 | ||
697 | ||
698 | if __name__ == '__main__': | |
699 | if iotests.qemu_default_machine != 'pc': | |
700 | # We need floppy and IDE CD-ROM | |
701 | iotests.notrun('not suitable for this machine type: %s' % | |
702 | iotests.qemu_default_machine) | |
cc8c46b7 HR |
703 | # Need to support image creation |
704 | iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2', | |
103cbc77 HR |
705 | 'vmdk', 'raw', 'vhdx', 'qed'], |
706 | supported_protocols=['file']) |