xref: /openbmc/qemu/tests/qemu-iotests/118 (revision 9dd003a99842d1d82c336e45c5cce656149de382)
1903cb1bfSPhilippe Mathieu-Daudé#!/usr/bin/env python3
2*9dd003a9SVladimir Sementsov-Ogievskiy# group: rw
3adfe2030SMax Reitz#
4adfe2030SMax Reitz# Test case for the QMP 'change' command and all other associated
5adfe2030SMax Reitz# commands
6adfe2030SMax Reitz#
7adfe2030SMax Reitz# Copyright (C) 2015 Red Hat, Inc.
8adfe2030SMax Reitz#
9adfe2030SMax Reitz# This program is free software; you can redistribute it and/or modify
10adfe2030SMax Reitz# it under the terms of the GNU General Public License as published by
11adfe2030SMax Reitz# the Free Software Foundation; either version 2 of the License, or
12adfe2030SMax Reitz# (at your option) any later version.
13adfe2030SMax Reitz#
14adfe2030SMax Reitz# This program is distributed in the hope that it will be useful,
15adfe2030SMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of
16adfe2030SMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17adfe2030SMax Reitz# GNU General Public License for more details.
18adfe2030SMax Reitz#
19adfe2030SMax Reitz# You should have received a copy of the GNU General Public License
20adfe2030SMax Reitz# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21adfe2030SMax Reitz#
22adfe2030SMax Reitz
23adfe2030SMax Reitzimport os
24adfe2030SMax Reitzimport stat
25adfe2030SMax Reitzimport time
26adfe2030SMax Reitzimport iotests
27adfe2030SMax Reitzfrom iotests import qemu_img
28adfe2030SMax Reitz
29adfe2030SMax Reitzold_img = os.path.join(iotests.test_dir, 'test0.img')
30adfe2030SMax Reitznew_img = os.path.join(iotests.test_dir, 'test1.img')
31adfe2030SMax Reitz
321d701e0eSMax Reitzdef interface_to_device_name(interface):
331d701e0eSMax Reitz    if interface == 'ide':
341d701e0eSMax Reitz        return 'ide-cd'
351d701e0eSMax Reitz    elif interface == 'floppy':
361d701e0eSMax Reitz        return 'floppy'
37dfa26a11SKevin Wolf    elif interface == 'scsi':
38dfa26a11SKevin Wolf        return 'scsi-cd'
391d701e0eSMax Reitz    else:
401d701e0eSMax Reitz        return None
411d701e0eSMax Reitz
42adfe2030SMax Reitzclass ChangeBaseClass(iotests.QMPTestCase):
43adfe2030SMax Reitz    has_opened = False
44adfe2030SMax Reitz    has_closed = False
45adfe2030SMax Reitz
4619462c4bSKevin Wolf    device_name = 'qdev0'
4719462c4bSKevin Wolf    use_drive = False
4819462c4bSKevin Wolf
49adfe2030SMax Reitz    def process_events(self):
50adfe2030SMax Reitz        for event in self.vm.get_qmp_events(wait=False):
51adfe2030SMax Reitz            if (event['event'] == 'DEVICE_TRAY_MOVED' and
5219462c4bSKevin Wolf                (event['data']['device'] == 'drive0' or
5319462c4bSKevin Wolf                 event['data']['id'] == self.device_name)):
54adfe2030SMax Reitz                if event['data']['tray-open'] == False:
55adfe2030SMax Reitz                    self.has_closed = True
56adfe2030SMax Reitz                else:
57adfe2030SMax Reitz                    self.has_opened = True
58adfe2030SMax Reitz
59adfe2030SMax Reitz    def wait_for_open(self):
60abb3e55bSMax Reitz        if not self.has_real_tray:
61abb3e55bSMax Reitz            return
62abb3e55bSMax Reitz
63d8336c6bSKevin Wolf        with iotests.Timeout(3, 'Timeout while waiting for the tray to open'):
64d8336c6bSKevin Wolf            while not self.has_opened:
65adfe2030SMax Reitz                self.process_events()
66adfe2030SMax Reitz
67adfe2030SMax Reitz    def wait_for_close(self):
68abb3e55bSMax Reitz        if not self.has_real_tray:
69abb3e55bSMax Reitz            return
70abb3e55bSMax Reitz
71d8336c6bSKevin Wolf        with iotests.Timeout(3, 'Timeout while waiting for the tray to close'):
72d8336c6bSKevin Wolf            while not self.has_closed:
73adfe2030SMax Reitz                self.process_events()
74adfe2030SMax Reitz
75adfe2030SMax Reitzclass GeneralChangeTestsBaseClass(ChangeBaseClass):
76486b88bdSKevin Wolf
77adfe2030SMax Reitz    def test_change(self):
7819462c4bSKevin Wolf        # 'change' requires a drive name, so skip the test for blockdev
7919462c4bSKevin Wolf        if not self.use_drive:
8019462c4bSKevin Wolf            return
8119462c4bSKevin Wolf
82adfe2030SMax Reitz        result = self.vm.qmp('change', device='drive0', target=new_img,
83adfe2030SMax Reitz                                       arg=iotests.imgfmt)
84adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
85adfe2030SMax Reitz
86adfe2030SMax Reitz        self.wait_for_open()
87adfe2030SMax Reitz        self.wait_for_close()
88adfe2030SMax Reitz
89adfe2030SMax Reitz        result = self.vm.qmp('query-block')
90abb3e55bSMax Reitz        if self.has_real_tray:
91adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
92adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
93adfe2030SMax Reitz
94adfe2030SMax Reitz    def test_blockdev_change_medium(self):
95486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-change-medium',
96486b88bdSKevin Wolf                             id=self.device_name, filename=new_img,
97adfe2030SMax Reitz                             format=iotests.imgfmt)
98486b88bdSKevin Wolf
99adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
100adfe2030SMax Reitz
101adfe2030SMax Reitz        self.wait_for_open()
102adfe2030SMax Reitz        self.wait_for_close()
103adfe2030SMax Reitz
104adfe2030SMax Reitz        result = self.vm.qmp('query-block')
105abb3e55bSMax Reitz        if self.has_real_tray:
106adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
107adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
108adfe2030SMax Reitz
109adfe2030SMax Reitz    def test_eject(self):
110486b88bdSKevin Wolf        result = self.vm.qmp('eject', id=self.device_name, force=True)
111adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
112adfe2030SMax Reitz
113adfe2030SMax Reitz        self.wait_for_open()
114adfe2030SMax Reitz
115adfe2030SMax Reitz        result = self.vm.qmp('query-block')
116abb3e55bSMax Reitz        if self.has_real_tray:
117adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
118adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
119adfe2030SMax Reitz
120adfe2030SMax Reitz    def test_tray_eject_change(self):
121486b88bdSKevin Wolf        result = self.vm.qmp('eject', id=self.device_name, force=True)
122adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
123adfe2030SMax Reitz
124adfe2030SMax Reitz        self.wait_for_open()
125adfe2030SMax Reitz
126adfe2030SMax Reitz        result = self.vm.qmp('query-block')
127abb3e55bSMax Reitz        if self.has_real_tray:
128adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
129adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
130adfe2030SMax Reitz
131486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
132486b88bdSKevin Wolf                             filename=new_img, format=iotests.imgfmt)
133adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
134adfe2030SMax Reitz
135adfe2030SMax Reitz        self.wait_for_close()
136adfe2030SMax Reitz
137adfe2030SMax Reitz        result = self.vm.qmp('query-block')
138abb3e55bSMax Reitz        if self.has_real_tray:
139adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
140adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
141adfe2030SMax Reitz
142adfe2030SMax Reitz    def test_tray_open_close(self):
143486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-open-tray',
144486b88bdSKevin Wolf                             id=self.device_name, force=True)
145adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
146adfe2030SMax Reitz
147adfe2030SMax Reitz        self.wait_for_open()
148adfe2030SMax Reitz
149adfe2030SMax Reitz        result = self.vm.qmp('query-block')
150abb3e55bSMax Reitz        if self.has_real_tray:
151adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
152adfe2030SMax Reitz        if self.was_empty == True:
153adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
154adfe2030SMax Reitz        else:
155adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
156adfe2030SMax Reitz
157486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
158adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
159adfe2030SMax Reitz
160adfe2030SMax Reitz        if self.has_real_tray or not self.was_empty:
161adfe2030SMax Reitz            self.wait_for_close()
162adfe2030SMax Reitz
163adfe2030SMax Reitz        result = self.vm.qmp('query-block')
164abb3e55bSMax Reitz        if self.has_real_tray:
165adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
166adfe2030SMax Reitz        if self.was_empty == True:
167adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
168adfe2030SMax Reitz        else:
169adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
170adfe2030SMax Reitz
171adfe2030SMax Reitz    def test_tray_eject_close(self):
1721d701e0eSMax Reitz        result = self.vm.qmp('eject', id=self.device_name, force=True)
173adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
174adfe2030SMax Reitz
175adfe2030SMax Reitz        self.wait_for_open()
176adfe2030SMax Reitz
177adfe2030SMax Reitz        result = self.vm.qmp('query-block')
178abb3e55bSMax Reitz        if self.has_real_tray:
179adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
180adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
181adfe2030SMax Reitz
182486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
183adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
184adfe2030SMax Reitz
185adfe2030SMax Reitz        self.wait_for_close()
186adfe2030SMax Reitz
187adfe2030SMax Reitz        result = self.vm.qmp('query-block')
188adfe2030SMax Reitz        if self.has_real_tray:
189adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
190adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
191adfe2030SMax Reitz
192adfe2030SMax Reitz    def test_tray_open_change(self):
1931d701e0eSMax Reitz        result = self.vm.qmp('blockdev-open-tray', id=self.device_name,
1941d701e0eSMax Reitz                                                   force=True)
195adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
196adfe2030SMax Reitz
197adfe2030SMax Reitz        self.wait_for_open()
198adfe2030SMax Reitz
199adfe2030SMax Reitz        result = self.vm.qmp('query-block')
200abb3e55bSMax Reitz        if self.has_real_tray:
201adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
202adfe2030SMax Reitz        if self.was_empty == True:
203adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
204adfe2030SMax Reitz        else:
205adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
206adfe2030SMax Reitz
2071d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
208adfe2030SMax Reitz                                                       filename=new_img,
209adfe2030SMax Reitz                                                       format=iotests.imgfmt)
210adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
211adfe2030SMax Reitz
212adfe2030SMax Reitz        self.wait_for_close()
213adfe2030SMax Reitz
214adfe2030SMax Reitz        result = self.vm.qmp('query-block')
215abb3e55bSMax Reitz        if self.has_real_tray:
216adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
217adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
218adfe2030SMax Reitz
21968174160SKevin Wolf    def test_cycle(self, read_only_node=False):
220adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
2210153d2f5SKevin Wolf                             node_name='new',
2220153d2f5SKevin Wolf                             driver=iotests.imgfmt,
22368174160SKevin Wolf                             read_only=read_only_node,
2240153d2f5SKevin Wolf                             file={'filename': new_img,
2250153d2f5SKevin Wolf                                    'driver': 'file'})
226adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
227adfe2030SMax Reitz
228486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-open-tray',
229486b88bdSKevin Wolf                             id=self.device_name, force=True)
230adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
231adfe2030SMax Reitz
232adfe2030SMax Reitz        self.wait_for_open()
233adfe2030SMax Reitz
234adfe2030SMax Reitz        result = self.vm.qmp('query-block')
235abb3e55bSMax Reitz        if self.has_real_tray:
236adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
237adfe2030SMax Reitz        if self.was_empty == True:
238adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
239adfe2030SMax Reitz        else:
240adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
241adfe2030SMax Reitz
24234ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium',
243486b88bdSKevin Wolf                             id=self.device_name)
244adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
245adfe2030SMax Reitz
246adfe2030SMax Reitz        result = self.vm.qmp('query-block')
247abb3e55bSMax Reitz        if self.has_real_tray:
248adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
249adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
250adfe2030SMax Reitz
25134ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium',
252486b88bdSKevin Wolf                             id=self.device_name, node_name='new')
253adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
254adfe2030SMax Reitz
255adfe2030SMax Reitz        result = self.vm.qmp('query-block')
256abb3e55bSMax Reitz        if self.has_real_tray:
257adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
258adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
259adfe2030SMax Reitz
260486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
261adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
262adfe2030SMax Reitz
263adfe2030SMax Reitz        self.wait_for_close()
264adfe2030SMax Reitz
265adfe2030SMax Reitz        result = self.vm.qmp('query-block')
266abb3e55bSMax Reitz        if self.has_real_tray:
267adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
268adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
269adfe2030SMax Reitz
27068174160SKevin Wolf    def test_cycle_read_only_media(self):
27168174160SKevin Wolf        self.test_cycle(True)
27268174160SKevin Wolf
273adfe2030SMax Reitz    def test_close_on_closed(self):
2741d701e0eSMax Reitz        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
275adfe2030SMax Reitz        # Should be a no-op
276adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
277fa1cfb40SKevin Wolf        self.assertEqual(self.vm.get_qmp_events(wait=False), [])
278adfe2030SMax Reitz
279adfe2030SMax Reitz    def test_remove_on_closed(self):
280abb3e55bSMax Reitz        if not self.has_real_tray:
281adfe2030SMax Reitz            return
282adfe2030SMax Reitz
28334ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
284adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
285adfe2030SMax Reitz
286adfe2030SMax Reitz    def test_insert_on_closed(self):
287abb3e55bSMax Reitz        if not self.has_real_tray:
288adfe2030SMax Reitz            return
289adfe2030SMax Reitz
290adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
2910153d2f5SKevin Wolf                             node_name='new',
2920153d2f5SKevin Wolf                             driver=iotests.imgfmt,
2930153d2f5SKevin Wolf                             file={'filename': new_img,
2940153d2f5SKevin Wolf                                   'driver': 'file'})
295adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
296adfe2030SMax Reitz
29734ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
298adfe2030SMax Reitz                                                       node_name='new')
299adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
300adfe2030SMax Reitz
301adfe2030SMax Reitzclass TestInitiallyFilled(GeneralChangeTestsBaseClass):
302adfe2030SMax Reitz    was_empty = False
303adfe2030SMax Reitz
304dfc82894SKevin Wolf    def setUp(self):
305adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
306adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
307486b88bdSKevin Wolf        self.vm = iotests.VM()
30819462c4bSKevin Wolf        if self.use_drive:
309dfc82894SKevin Wolf            self.vm.add_drive(old_img, 'media=%s' % self.media, 'none')
31019462c4bSKevin Wolf        else:
31119462c4bSKevin Wolf            self.vm.add_blockdev([ 'node-name=drive0',
31219462c4bSKevin Wolf                                   'driver=%s' % iotests.imgfmt,
31319462c4bSKevin Wolf                                   'file.driver=file',
31419462c4bSKevin Wolf                                   'file.filename=%s' % old_img ])
315dfc82894SKevin Wolf        if self.interface == 'scsi':
316dfa26a11SKevin Wolf            self.vm.add_device('virtio-scsi-pci')
3171d701e0eSMax Reitz        self.vm.add_device('%s,drive=drive0,id=%s' %
318dfc82894SKevin Wolf                           (interface_to_device_name(self.interface),
3191d701e0eSMax Reitz                            self.device_name))
320adfe2030SMax Reitz        self.vm.launch()
321adfe2030SMax Reitz
322adfe2030SMax Reitz    def tearDown(self):
323adfe2030SMax Reitz        self.vm.shutdown()
324adfe2030SMax Reitz        os.remove(old_img)
325adfe2030SMax Reitz        os.remove(new_img)
326adfe2030SMax Reitz
327adfe2030SMax Reitz    def test_insert_on_filled(self):
328adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
3290153d2f5SKevin Wolf                             node_name='new',
3300153d2f5SKevin Wolf                             driver=iotests.imgfmt,
3310153d2f5SKevin Wolf                             file={'filename': new_img,
3320153d2f5SKevin Wolf                                   'driver': 'file'})
333adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
334adfe2030SMax Reitz
3351d701e0eSMax Reitz        result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
336adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
337adfe2030SMax Reitz
338adfe2030SMax Reitz        self.wait_for_open()
339adfe2030SMax Reitz
34034ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
341adfe2030SMax Reitz                                                       node_name='new')
342adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
343adfe2030SMax Reitz
344adfe2030SMax Reitzclass TestInitiallyEmpty(GeneralChangeTestsBaseClass):
345adfe2030SMax Reitz    was_empty = True
346adfe2030SMax Reitz
347dfc82894SKevin Wolf    def setUp(self):
348adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
34919462c4bSKevin Wolf        self.vm = iotests.VM()
35019462c4bSKevin Wolf        if self.use_drive:
35119462c4bSKevin Wolf            self.vm.add_drive(None, 'media=%s' % self.media, 'none')
352dfc82894SKevin Wolf        if self.interface == 'scsi':
353dfa26a11SKevin Wolf            self.vm.add_device('virtio-scsi-pci')
35419462c4bSKevin Wolf        self.vm.add_device('%s,%sid=%s' %
355dfc82894SKevin Wolf                           (interface_to_device_name(self.interface),
35619462c4bSKevin Wolf                            'drive=drive0,' if self.use_drive else '',
3571d701e0eSMax Reitz                            self.device_name))
358adfe2030SMax Reitz        self.vm.launch()
359adfe2030SMax Reitz
360adfe2030SMax Reitz    def tearDown(self):
361adfe2030SMax Reitz        self.vm.shutdown()
362adfe2030SMax Reitz        os.remove(new_img)
363adfe2030SMax Reitz
364adfe2030SMax Reitz    def test_remove_on_empty(self):
3651d701e0eSMax Reitz        result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
366adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
367adfe2030SMax Reitz
368adfe2030SMax Reitz        self.wait_for_open()
369adfe2030SMax Reitz
37034ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
371adfe2030SMax Reitz        # Should be a no-op
372adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
373adfe2030SMax Reitz
374dfc82894SKevin Wolf# Do this in a function to avoid leaking variables like case into the global
375dfc82894SKevin Wolf# name space (otherwise tests would be run for the abstract base classes)
376dfc82894SKevin Wolfdef create_basic_test_classes():
377dfc82894SKevin Wolf    for (media, interface, has_real_tray) in [ ('cdrom', 'ide', True),
378dfc82894SKevin Wolf                                               ('cdrom', 'scsi', True),
379dfc82894SKevin Wolf                                               ('disk', 'floppy', False) ]:
380adfe2030SMax Reitz
381dfc82894SKevin Wolf        for case in [ TestInitiallyFilled, TestInitiallyEmpty ]:
38219462c4bSKevin Wolf            for use_drive in [ True, False ]:
383dfc82894SKevin Wolf                attr = { 'media': media,
384dfc82894SKevin Wolf                         'interface': interface,
38519462c4bSKevin Wolf                         'has_real_tray': has_real_tray,
38619462c4bSKevin Wolf                         'use_drive': use_drive }
387adfe2030SMax Reitz
38819462c4bSKevin Wolf                name = '%s_%s_%s_%s' % (case.__name__, media, interface,
38919462c4bSKevin Wolf                                        'drive' if use_drive else 'blockdev')
390dfc82894SKevin Wolf                globals()[name] = type(name, (case, ), attr)
391adfe2030SMax Reitz
392dfc82894SKevin Wolfcreate_basic_test_classes()
393adfe2030SMax Reitz
394adfe2030SMax Reitzclass TestChangeReadOnly(ChangeBaseClass):
3951d701e0eSMax Reitz    device_name = 'qdev0'
3961d701e0eSMax Reitz
397adfe2030SMax Reitz    def setUp(self):
398adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
399adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
400adfe2030SMax Reitz        self.vm = iotests.VM()
401adfe2030SMax Reitz
402adfe2030SMax Reitz    def tearDown(self):
403adfe2030SMax Reitz        self.vm.shutdown()
4044803c5cdSEduardo Habkost        os.chmod(old_img, 0o666)
4054803c5cdSEduardo Habkost        os.chmod(new_img, 0o666)
406adfe2030SMax Reitz        os.remove(old_img)
407adfe2030SMax Reitz        os.remove(new_img)
408adfe2030SMax Reitz
409adfe2030SMax Reitz    def test_ro_ro_retain(self):
4104803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
4114803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
4121d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
4131d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
414adfe2030SMax Reitz        self.vm.launch()
415adfe2030SMax Reitz
416adfe2030SMax Reitz        result = self.vm.qmp('query-block')
417adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
418adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
419adfe2030SMax Reitz
4201d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
421adfe2030SMax Reitz                                                       filename=new_img,
422adfe2030SMax Reitz                                                       format=iotests.imgfmt,
423adfe2030SMax Reitz                                                       read_only_mode='retain')
424adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
425adfe2030SMax Reitz
426adfe2030SMax Reitz        result = self.vm.qmp('query-block')
427adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
428adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
429adfe2030SMax Reitz
430adfe2030SMax Reitz    def test_ro_rw_retain(self):
4314803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
4321d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
4331d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
434adfe2030SMax Reitz        self.vm.launch()
435adfe2030SMax Reitz
436adfe2030SMax Reitz        result = self.vm.qmp('query-block')
437adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
438adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
439adfe2030SMax Reitz
4401d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
441adfe2030SMax Reitz                                                       filename=new_img,
442adfe2030SMax Reitz                                                       format=iotests.imgfmt,
443adfe2030SMax Reitz                                                       read_only_mode='retain')
444adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
445adfe2030SMax Reitz
446adfe2030SMax Reitz        result = self.vm.qmp('query-block')
447adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
448adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
449adfe2030SMax Reitz
450d926f4ddSKevin Wolf    @iotests.skip_if_user_is_root
451adfe2030SMax Reitz    def test_rw_ro_retain(self):
4524803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
4531d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
4541d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
455adfe2030SMax Reitz        self.vm.launch()
456adfe2030SMax Reitz
457adfe2030SMax Reitz        result = self.vm.qmp('query-block')
458adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
459adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
460adfe2030SMax Reitz
4611d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
462adfe2030SMax Reitz                                                       filename=new_img,
463adfe2030SMax Reitz                                                       format=iotests.imgfmt,
464adfe2030SMax Reitz                                                       read_only_mode='retain')
465adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
466adfe2030SMax Reitz
467fa1cfb40SKevin Wolf        self.assertEqual(self.vm.get_qmp_events(wait=False), [])
468adfe2030SMax Reitz
469adfe2030SMax Reitz        result = self.vm.qmp('query-block')
470adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
471adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
472adfe2030SMax Reitz
473adfe2030SMax Reitz    def test_ro_rw(self):
4744803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
4751d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
4761d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
477adfe2030SMax Reitz        self.vm.launch()
478adfe2030SMax Reitz
479adfe2030SMax Reitz        result = self.vm.qmp('query-block')
480adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
481adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
482adfe2030SMax Reitz
483adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
4841d701e0eSMax Reitz                             id=self.device_name,
485adfe2030SMax Reitz                             filename=new_img,
486adfe2030SMax Reitz                             format=iotests.imgfmt,
487adfe2030SMax Reitz                             read_only_mode='read-write')
488adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
489adfe2030SMax Reitz
490adfe2030SMax Reitz        result = self.vm.qmp('query-block')
491adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
492adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
493adfe2030SMax Reitz
494adfe2030SMax Reitz    def test_rw_ro(self):
4954803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
4961d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
4971d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
498adfe2030SMax Reitz        self.vm.launch()
499adfe2030SMax Reitz
500adfe2030SMax Reitz        result = self.vm.qmp('query-block')
501adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
502adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
503adfe2030SMax Reitz
504adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
5051d701e0eSMax Reitz                             id=self.device_name,
506adfe2030SMax Reitz                             filename=new_img,
507adfe2030SMax Reitz                             format=iotests.imgfmt,
508adfe2030SMax Reitz                             read_only_mode='read-only')
509adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
510adfe2030SMax Reitz
511adfe2030SMax Reitz        result = self.vm.qmp('query-block')
512adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
513adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
514adfe2030SMax Reitz
515adfe2030SMax Reitz    def test_make_rw_ro(self):
5161d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
5171d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
518adfe2030SMax Reitz        self.vm.launch()
519adfe2030SMax Reitz
520adfe2030SMax Reitz        result = self.vm.qmp('query-block')
521adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
522adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
523adfe2030SMax Reitz
524adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
5251d701e0eSMax Reitz                             id=self.device_name,
526adfe2030SMax Reitz                             filename=new_img,
527adfe2030SMax Reitz                             format=iotests.imgfmt,
528adfe2030SMax Reitz                             read_only_mode='read-only')
529adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
530adfe2030SMax Reitz
531adfe2030SMax Reitz        result = self.vm.qmp('query-block')
532adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
533adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
534adfe2030SMax Reitz
535d926f4ddSKevin Wolf    @iotests.skip_if_user_is_root
536adfe2030SMax Reitz    def test_make_ro_rw(self):
5374803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
5381d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
5391d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
540adfe2030SMax Reitz        self.vm.launch()
541adfe2030SMax Reitz
542adfe2030SMax Reitz        result = self.vm.qmp('query-block')
543adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
544adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
545adfe2030SMax Reitz
546adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
5471d701e0eSMax Reitz                             id=self.device_name,
548adfe2030SMax Reitz                             filename=new_img,
549adfe2030SMax Reitz                             format=iotests.imgfmt,
550adfe2030SMax Reitz                             read_only_mode='read-write')
551adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
552adfe2030SMax Reitz
553adfe2030SMax Reitz        result = self.vm.qmp('query-block')
554adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
555adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
556adfe2030SMax Reitz
557adfe2030SMax Reitz    def test_make_rw_ro_by_retain(self):
5584803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
5591d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
5601d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
561adfe2030SMax Reitz        self.vm.launch()
562adfe2030SMax Reitz
563adfe2030SMax Reitz        result = self.vm.qmp('query-block')
564adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
565adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
566adfe2030SMax Reitz
5671d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
568adfe2030SMax Reitz                                                       filename=new_img,
569adfe2030SMax Reitz                                                       format=iotests.imgfmt,
570adfe2030SMax Reitz                                                       read_only_mode='retain')
571adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
572adfe2030SMax Reitz
573adfe2030SMax Reitz        result = self.vm.qmp('query-block')
574adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
575adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
576adfe2030SMax Reitz
577d926f4ddSKevin Wolf    @iotests.skip_if_user_is_root
578adfe2030SMax Reitz    def test_make_ro_rw_by_retain(self):
5794803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
5801d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
5811d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
582adfe2030SMax Reitz        self.vm.launch()
583adfe2030SMax Reitz
584adfe2030SMax Reitz        result = self.vm.qmp('query-block')
585adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
586adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
587adfe2030SMax Reitz
5881d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
589adfe2030SMax Reitz                                                       filename=new_img,
590adfe2030SMax Reitz                                                       format=iotests.imgfmt,
591adfe2030SMax Reitz                                                       read_only_mode='retain')
592adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
593adfe2030SMax Reitz
594adfe2030SMax Reitz        result = self.vm.qmp('query-block')
595adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
596adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
597adfe2030SMax Reitz
598adfe2030SMax Reitz    def test_rw_ro_cycle(self):
5994803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
6001d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
6011d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
602adfe2030SMax Reitz        self.vm.launch()
603adfe2030SMax Reitz
604adfe2030SMax Reitz        result = self.vm.qmp('query-block')
605adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
606adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
607adfe2030SMax Reitz
608adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
6090153d2f5SKevin Wolf                             node_name='new',
6100153d2f5SKevin Wolf                             driver=iotests.imgfmt,
6110153d2f5SKevin Wolf                             read_only=True,
6120153d2f5SKevin Wolf                             file={'filename': new_img,
6130153d2f5SKevin Wolf                                    'driver': 'file'})
614adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
615adfe2030SMax Reitz
616adfe2030SMax Reitz        result = self.vm.qmp('query-block')
617adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
618adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
619adfe2030SMax Reitz
62034ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
621adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
622adfe2030SMax Reitz
623adfe2030SMax Reitz        result = self.vm.qmp('query-block')
624adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
625adfe2030SMax Reitz
62634ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
627adfe2030SMax Reitz                                                       node_name='new')
628adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
629adfe2030SMax Reitz
630adfe2030SMax Reitz        result = self.vm.qmp('query-block')
631adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
632adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
633adfe2030SMax Reitz
634adfe2030SMax Reitz        result = self.vm.qmp('query-block')
635adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
636adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
637adfe2030SMax Reitz
638adfe2030SMax ReitzGeneralChangeTestsBaseClass = None
639adfe2030SMax ReitzTestInitiallyFilled = None
640adfe2030SMax ReitzTestInitiallyEmpty = None
641adfe2030SMax Reitz
642adfe2030SMax Reitz
643adfe2030SMax Reitzclass TestBlockJobsAfterCycle(ChangeBaseClass):
6441d701e0eSMax Reitz    device_name = 'qdev0'
6451d701e0eSMax Reitz
646adfe2030SMax Reitz    def setUp(self):
6471d701e0eSMax Reitz        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K')
648adfe2030SMax Reitz
649adfe2030SMax Reitz        self.vm = iotests.VM()
650e4fd2e9dSKevin Wolf        self.vm.add_drive_raw("id=drive0,driver=null-co,if=none")
6511d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
652adfe2030SMax Reitz        self.vm.launch()
653adfe2030SMax Reitz
654adfe2030SMax Reitz        result = self.vm.qmp('query-block')
655adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co')
656adfe2030SMax Reitz
657adfe2030SMax Reitz        # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
658adfe2030SMax Reitz        # is not necessary
65934ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
660adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
661adfe2030SMax Reitz
662adfe2030SMax Reitz        result = self.vm.qmp('query-block')
663adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
664adfe2030SMax Reitz
665adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
6660153d2f5SKevin Wolf                             node_name='node0',
6670153d2f5SKevin Wolf                             driver=iotests.imgfmt,
6680153d2f5SKevin Wolf                             file={'filename': old_img,
6690153d2f5SKevin Wolf                                   'driver': 'file'})
670adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
671adfe2030SMax Reitz
67234ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
673adfe2030SMax Reitz                                                       node_name='node0')
674adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
675adfe2030SMax Reitz
676adfe2030SMax Reitz        result = self.vm.qmp('query-block')
677adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
678adfe2030SMax Reitz
679adfe2030SMax Reitz    def tearDown(self):
680adfe2030SMax Reitz        self.vm.shutdown()
681adfe2030SMax Reitz        os.remove(old_img)
682adfe2030SMax Reitz        try:
683adfe2030SMax Reitz            os.remove(new_img)
684adfe2030SMax Reitz        except OSError:
685adfe2030SMax Reitz            pass
686adfe2030SMax Reitz
687adfe2030SMax Reitz    # We need backing file support
688ff3caf5aSMax Reitz    @iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw',
689ff3caf5aSMax Reitz                               'vhdx'))
690ff3caf5aSMax Reitz    def test_snapshot_and_commit(self):
691adfe2030SMax Reitz        result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
692adfe2030SMax Reitz                                                       snapshot_file=new_img,
693adfe2030SMax Reitz                                                       format=iotests.imgfmt)
694adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
695adfe2030SMax Reitz
696adfe2030SMax Reitz        result = self.vm.qmp('query-block')
697adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
698adfe2030SMax Reitz        self.assert_qmp(result,
699adfe2030SMax Reitz                        'return[0]/inserted/image/backing-image/filename',
700adfe2030SMax Reitz                        old_img)
701adfe2030SMax Reitz
702adfe2030SMax Reitz        result = self.vm.qmp('block-commit', device='drive0')
703adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
704adfe2030SMax Reitz
705adfe2030SMax Reitz        self.vm.event_wait(name='BLOCK_JOB_READY')
706adfe2030SMax Reitz
707adfe2030SMax Reitz        result = self.vm.qmp('query-block-jobs')
708adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/device', 'drive0')
709adfe2030SMax Reitz
710adfe2030SMax Reitz        result = self.vm.qmp('block-job-complete', device='drive0')
711adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
712adfe2030SMax Reitz
713adfe2030SMax Reitz        self.vm.event_wait(name='BLOCK_JOB_COMPLETED')
714adfe2030SMax Reitz
715adfe2030SMax Reitz
716adfe2030SMax Reitzif __name__ == '__main__':
717adfe2030SMax Reitz    if iotests.qemu_default_machine != 'pc':
718adfe2030SMax Reitz        # We need floppy and IDE CD-ROM
719adfe2030SMax Reitz        iotests.notrun('not suitable for this machine type: %s' %
720adfe2030SMax Reitz                       iotests.qemu_default_machine)
721cc8c46b7SMax Reitz    # Need to support image creation
722cc8c46b7SMax Reitz    iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
723103cbc77SMax Reitz                                 'vmdk', 'raw', 'vhdx', 'qed'],
724103cbc77SMax Reitz                 supported_protocols=['file'])
725