xref: /qemu/tests/qemu-iotests/118 (revision ff3caf5af0fd204133668f26fde39b27f86c5d76)
1903cb1bfSPhilippe Mathieu-Daudé#!/usr/bin/env python3
2adfe2030SMax Reitz#
3adfe2030SMax Reitz# Test case for the QMP 'change' command and all other associated
4adfe2030SMax Reitz# commands
5adfe2030SMax Reitz#
6adfe2030SMax Reitz# Copyright (C) 2015 Red Hat, Inc.
7adfe2030SMax Reitz#
8adfe2030SMax Reitz# This program is free software; you can redistribute it and/or modify
9adfe2030SMax Reitz# it under the terms of the GNU General Public License as published by
10adfe2030SMax Reitz# the Free Software Foundation; either version 2 of the License, or
11adfe2030SMax Reitz# (at your option) any later version.
12adfe2030SMax Reitz#
13adfe2030SMax Reitz# This program is distributed in the hope that it will be useful,
14adfe2030SMax Reitz# but WITHOUT ANY WARRANTY; without even the implied warranty of
15adfe2030SMax Reitz# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16adfe2030SMax Reitz# GNU General Public License for more details.
17adfe2030SMax Reitz#
18adfe2030SMax Reitz# You should have received a copy of the GNU General Public License
19adfe2030SMax Reitz# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20adfe2030SMax Reitz#
21adfe2030SMax Reitz
22adfe2030SMax Reitzimport os
23adfe2030SMax Reitzimport stat
24adfe2030SMax Reitzimport time
25adfe2030SMax Reitzimport iotests
26adfe2030SMax Reitzfrom iotests import qemu_img
27adfe2030SMax Reitz
28adfe2030SMax Reitzold_img = os.path.join(iotests.test_dir, 'test0.img')
29adfe2030SMax Reitznew_img = os.path.join(iotests.test_dir, 'test1.img')
30adfe2030SMax Reitz
311d701e0eSMax Reitzdef interface_to_device_name(interface):
321d701e0eSMax Reitz    if interface == 'ide':
331d701e0eSMax Reitz        return 'ide-cd'
341d701e0eSMax Reitz    elif interface == 'floppy':
351d701e0eSMax Reitz        return 'floppy'
36dfa26a11SKevin Wolf    elif interface == 'scsi':
37dfa26a11SKevin Wolf        return 'scsi-cd'
381d701e0eSMax Reitz    else:
391d701e0eSMax Reitz        return None
401d701e0eSMax Reitz
41adfe2030SMax Reitzclass ChangeBaseClass(iotests.QMPTestCase):
42adfe2030SMax Reitz    has_opened = False
43adfe2030SMax Reitz    has_closed = False
44adfe2030SMax Reitz
4519462c4bSKevin Wolf    device_name = 'qdev0'
4619462c4bSKevin Wolf    use_drive = False
4719462c4bSKevin Wolf
48adfe2030SMax Reitz    def process_events(self):
49adfe2030SMax Reitz        for event in self.vm.get_qmp_events(wait=False):
50adfe2030SMax Reitz            if (event['event'] == 'DEVICE_TRAY_MOVED' and
5119462c4bSKevin Wolf                (event['data']['device'] == 'drive0' or
5219462c4bSKevin Wolf                 event['data']['id'] == self.device_name)):
53adfe2030SMax Reitz                if event['data']['tray-open'] == False:
54adfe2030SMax Reitz                    self.has_closed = True
55adfe2030SMax Reitz                else:
56adfe2030SMax Reitz                    self.has_opened = True
57adfe2030SMax Reitz
58adfe2030SMax Reitz    def wait_for_open(self):
59abb3e55bSMax Reitz        if not self.has_real_tray:
60abb3e55bSMax Reitz            return
61abb3e55bSMax Reitz
62d8336c6bSKevin Wolf        with iotests.Timeout(3, 'Timeout while waiting for the tray to open'):
63d8336c6bSKevin Wolf            while not self.has_opened:
64adfe2030SMax Reitz                self.process_events()
65adfe2030SMax Reitz
66adfe2030SMax Reitz    def wait_for_close(self):
67abb3e55bSMax Reitz        if not self.has_real_tray:
68abb3e55bSMax Reitz            return
69abb3e55bSMax Reitz
70d8336c6bSKevin Wolf        with iotests.Timeout(3, 'Timeout while waiting for the tray to close'):
71d8336c6bSKevin Wolf            while not self.has_closed:
72adfe2030SMax Reitz                self.process_events()
73adfe2030SMax Reitz
74adfe2030SMax Reitzclass GeneralChangeTestsBaseClass(ChangeBaseClass):
75486b88bdSKevin Wolf
76adfe2030SMax Reitz    def test_change(self):
7719462c4bSKevin Wolf        # 'change' requires a drive name, so skip the test for blockdev
7819462c4bSKevin Wolf        if not self.use_drive:
7919462c4bSKevin Wolf            return
8019462c4bSKevin Wolf
81adfe2030SMax Reitz        result = self.vm.qmp('change', device='drive0', target=new_img,
82adfe2030SMax Reitz                                       arg=iotests.imgfmt)
83adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
84adfe2030SMax Reitz
85adfe2030SMax Reitz        self.wait_for_open()
86adfe2030SMax Reitz        self.wait_for_close()
87adfe2030SMax Reitz
88adfe2030SMax Reitz        result = self.vm.qmp('query-block')
89abb3e55bSMax Reitz        if self.has_real_tray:
90adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
91adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
92adfe2030SMax Reitz
93adfe2030SMax Reitz    def test_blockdev_change_medium(self):
94486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-change-medium',
95486b88bdSKevin Wolf                             id=self.device_name, filename=new_img,
96adfe2030SMax Reitz                             format=iotests.imgfmt)
97486b88bdSKevin Wolf
98adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
99adfe2030SMax Reitz
100adfe2030SMax Reitz        self.wait_for_open()
101adfe2030SMax Reitz        self.wait_for_close()
102adfe2030SMax Reitz
103adfe2030SMax Reitz        result = self.vm.qmp('query-block')
104abb3e55bSMax Reitz        if self.has_real_tray:
105adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
106adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
107adfe2030SMax Reitz
108adfe2030SMax Reitz    def test_eject(self):
109486b88bdSKevin Wolf        result = self.vm.qmp('eject', id=self.device_name, force=True)
110adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
111adfe2030SMax Reitz
112adfe2030SMax Reitz        self.wait_for_open()
113adfe2030SMax Reitz
114adfe2030SMax Reitz        result = self.vm.qmp('query-block')
115abb3e55bSMax Reitz        if self.has_real_tray:
116adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
117adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
118adfe2030SMax Reitz
119adfe2030SMax Reitz    def test_tray_eject_change(self):
120486b88bdSKevin Wolf        result = self.vm.qmp('eject', id=self.device_name, force=True)
121adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
122adfe2030SMax Reitz
123adfe2030SMax Reitz        self.wait_for_open()
124adfe2030SMax Reitz
125adfe2030SMax Reitz        result = self.vm.qmp('query-block')
126abb3e55bSMax Reitz        if self.has_real_tray:
127adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
128adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
129adfe2030SMax Reitz
130486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
131486b88bdSKevin Wolf                             filename=new_img, format=iotests.imgfmt)
132adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
133adfe2030SMax Reitz
134adfe2030SMax Reitz        self.wait_for_close()
135adfe2030SMax Reitz
136adfe2030SMax Reitz        result = self.vm.qmp('query-block')
137abb3e55bSMax Reitz        if self.has_real_tray:
138adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
139adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
140adfe2030SMax Reitz
141adfe2030SMax Reitz    def test_tray_open_close(self):
142486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-open-tray',
143486b88bdSKevin Wolf                             id=self.device_name, force=True)
144adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
145adfe2030SMax Reitz
146adfe2030SMax Reitz        self.wait_for_open()
147adfe2030SMax Reitz
148adfe2030SMax Reitz        result = self.vm.qmp('query-block')
149abb3e55bSMax Reitz        if self.has_real_tray:
150adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
151adfe2030SMax Reitz        if self.was_empty == True:
152adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
153adfe2030SMax Reitz        else:
154adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
155adfe2030SMax Reitz
156486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
157adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
158adfe2030SMax Reitz
159adfe2030SMax Reitz        if self.has_real_tray or not self.was_empty:
160adfe2030SMax Reitz            self.wait_for_close()
161adfe2030SMax Reitz
162adfe2030SMax Reitz        result = self.vm.qmp('query-block')
163abb3e55bSMax Reitz        if self.has_real_tray:
164adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
165adfe2030SMax Reitz        if self.was_empty == True:
166adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
167adfe2030SMax Reitz        else:
168adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
169adfe2030SMax Reitz
170adfe2030SMax Reitz    def test_tray_eject_close(self):
1711d701e0eSMax Reitz        result = self.vm.qmp('eject', id=self.device_name, force=True)
172adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
173adfe2030SMax Reitz
174adfe2030SMax Reitz        self.wait_for_open()
175adfe2030SMax Reitz
176adfe2030SMax Reitz        result = self.vm.qmp('query-block')
177abb3e55bSMax Reitz        if self.has_real_tray:
178adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
179adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
180adfe2030SMax Reitz
181486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
182adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
183adfe2030SMax Reitz
184adfe2030SMax Reitz        self.wait_for_close()
185adfe2030SMax Reitz
186adfe2030SMax Reitz        result = self.vm.qmp('query-block')
187adfe2030SMax Reitz        if self.has_real_tray:
188adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
189adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
190adfe2030SMax Reitz
191adfe2030SMax Reitz    def test_tray_open_change(self):
1921d701e0eSMax Reitz        result = self.vm.qmp('blockdev-open-tray', id=self.device_name,
1931d701e0eSMax Reitz                                                   force=True)
194adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
195adfe2030SMax Reitz
196adfe2030SMax Reitz        self.wait_for_open()
197adfe2030SMax Reitz
198adfe2030SMax Reitz        result = self.vm.qmp('query-block')
199abb3e55bSMax Reitz        if self.has_real_tray:
200adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
201adfe2030SMax Reitz        if self.was_empty == True:
202adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
203adfe2030SMax Reitz        else:
204adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
205adfe2030SMax Reitz
2061d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
207adfe2030SMax Reitz                                                       filename=new_img,
208adfe2030SMax Reitz                                                       format=iotests.imgfmt)
209adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
210adfe2030SMax Reitz
211adfe2030SMax Reitz        self.wait_for_close()
212adfe2030SMax Reitz
213adfe2030SMax Reitz        result = self.vm.qmp('query-block')
214abb3e55bSMax Reitz        if self.has_real_tray:
215adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
216adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
217adfe2030SMax Reitz
21868174160SKevin Wolf    def test_cycle(self, read_only_node=False):
219adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
2200153d2f5SKevin Wolf                             node_name='new',
2210153d2f5SKevin Wolf                             driver=iotests.imgfmt,
22268174160SKevin Wolf                             read_only=read_only_node,
2230153d2f5SKevin Wolf                             file={'filename': new_img,
2240153d2f5SKevin Wolf                                    'driver': 'file'})
225adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
226adfe2030SMax Reitz
227486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-open-tray',
228486b88bdSKevin Wolf                             id=self.device_name, force=True)
229adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
230adfe2030SMax Reitz
231adfe2030SMax Reitz        self.wait_for_open()
232adfe2030SMax Reitz
233adfe2030SMax Reitz        result = self.vm.qmp('query-block')
234abb3e55bSMax Reitz        if self.has_real_tray:
235adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
236adfe2030SMax Reitz        if self.was_empty == True:
237adfe2030SMax Reitz            self.assert_qmp_absent(result, 'return[0]/inserted')
238adfe2030SMax Reitz        else:
239adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
240adfe2030SMax Reitz
24134ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium',
242486b88bdSKevin Wolf                             id=self.device_name)
243adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
244adfe2030SMax Reitz
245adfe2030SMax Reitz        result = self.vm.qmp('query-block')
246abb3e55bSMax Reitz        if self.has_real_tray:
247adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
248adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
249adfe2030SMax Reitz
25034ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium',
251486b88bdSKevin Wolf                             id=self.device_name, node_name='new')
252adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
253adfe2030SMax Reitz
254adfe2030SMax Reitz        result = self.vm.qmp('query-block')
255abb3e55bSMax Reitz        if self.has_real_tray:
256adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', True)
257adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
258adfe2030SMax Reitz
259486b88bdSKevin Wolf        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
260adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
261adfe2030SMax Reitz
262adfe2030SMax Reitz        self.wait_for_close()
263adfe2030SMax Reitz
264adfe2030SMax Reitz        result = self.vm.qmp('query-block')
265abb3e55bSMax Reitz        if self.has_real_tray:
266adfe2030SMax Reitz            self.assert_qmp(result, 'return[0]/tray_open', False)
267adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
268adfe2030SMax Reitz
26968174160SKevin Wolf    def test_cycle_read_only_media(self):
27068174160SKevin Wolf        self.test_cycle(True)
27168174160SKevin Wolf
272adfe2030SMax Reitz    def test_close_on_closed(self):
2731d701e0eSMax Reitz        result = self.vm.qmp('blockdev-close-tray', id=self.device_name)
274adfe2030SMax Reitz        # Should be a no-op
275adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
276fa1cfb40SKevin Wolf        self.assertEqual(self.vm.get_qmp_events(wait=False), [])
277adfe2030SMax Reitz
278adfe2030SMax Reitz    def test_remove_on_closed(self):
279abb3e55bSMax Reitz        if not self.has_real_tray:
280adfe2030SMax Reitz            return
281adfe2030SMax Reitz
28234ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
283adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
284adfe2030SMax Reitz
285adfe2030SMax Reitz    def test_insert_on_closed(self):
286abb3e55bSMax Reitz        if not self.has_real_tray:
287adfe2030SMax Reitz            return
288adfe2030SMax Reitz
289adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
2900153d2f5SKevin Wolf                             node_name='new',
2910153d2f5SKevin Wolf                             driver=iotests.imgfmt,
2920153d2f5SKevin Wolf                             file={'filename': new_img,
2930153d2f5SKevin Wolf                                   'driver': 'file'})
294adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
295adfe2030SMax Reitz
29634ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
297adfe2030SMax Reitz                                                       node_name='new')
298adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
299adfe2030SMax Reitz
300adfe2030SMax Reitzclass TestInitiallyFilled(GeneralChangeTestsBaseClass):
301adfe2030SMax Reitz    was_empty = False
302adfe2030SMax Reitz
303dfc82894SKevin Wolf    def setUp(self):
304adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
305adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
306486b88bdSKevin Wolf        self.vm = iotests.VM()
30719462c4bSKevin Wolf        if self.use_drive:
308dfc82894SKevin Wolf            self.vm.add_drive(old_img, 'media=%s' % self.media, 'none')
30919462c4bSKevin Wolf        else:
31019462c4bSKevin Wolf            self.vm.add_blockdev([ 'node-name=drive0',
31119462c4bSKevin Wolf                                   'driver=%s' % iotests.imgfmt,
31219462c4bSKevin Wolf                                   'file.driver=file',
31319462c4bSKevin Wolf                                   'file.filename=%s' % old_img ])
314dfc82894SKevin Wolf        if self.interface == 'scsi':
315dfa26a11SKevin Wolf            self.vm.add_device('virtio-scsi-pci')
3161d701e0eSMax Reitz        self.vm.add_device('%s,drive=drive0,id=%s' %
317dfc82894SKevin Wolf                           (interface_to_device_name(self.interface),
3181d701e0eSMax Reitz                            self.device_name))
319adfe2030SMax Reitz        self.vm.launch()
320adfe2030SMax Reitz
321adfe2030SMax Reitz    def tearDown(self):
322adfe2030SMax Reitz        self.vm.shutdown()
323adfe2030SMax Reitz        os.remove(old_img)
324adfe2030SMax Reitz        os.remove(new_img)
325adfe2030SMax Reitz
326adfe2030SMax Reitz    def test_insert_on_filled(self):
327adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
3280153d2f5SKevin Wolf                             node_name='new',
3290153d2f5SKevin Wolf                             driver=iotests.imgfmt,
3300153d2f5SKevin Wolf                             file={'filename': new_img,
3310153d2f5SKevin Wolf                                   'driver': 'file'})
332adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
333adfe2030SMax Reitz
3341d701e0eSMax Reitz        result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
335adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
336adfe2030SMax Reitz
337adfe2030SMax Reitz        self.wait_for_open()
338adfe2030SMax Reitz
33934ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
340adfe2030SMax Reitz                                                       node_name='new')
341adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
342adfe2030SMax Reitz
343adfe2030SMax Reitzclass TestInitiallyEmpty(GeneralChangeTestsBaseClass):
344adfe2030SMax Reitz    was_empty = True
345adfe2030SMax Reitz
346dfc82894SKevin Wolf    def setUp(self):
347adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
34819462c4bSKevin Wolf        self.vm = iotests.VM()
34919462c4bSKevin Wolf        if self.use_drive:
35019462c4bSKevin Wolf            self.vm.add_drive(None, 'media=%s' % self.media, 'none')
351dfc82894SKevin Wolf        if self.interface == 'scsi':
352dfa26a11SKevin Wolf            self.vm.add_device('virtio-scsi-pci')
35319462c4bSKevin Wolf        self.vm.add_device('%s,%sid=%s' %
354dfc82894SKevin Wolf                           (interface_to_device_name(self.interface),
35519462c4bSKevin Wolf                            'drive=drive0,' if self.use_drive else '',
3561d701e0eSMax Reitz                            self.device_name))
357adfe2030SMax Reitz        self.vm.launch()
358adfe2030SMax Reitz
359adfe2030SMax Reitz    def tearDown(self):
360adfe2030SMax Reitz        self.vm.shutdown()
361adfe2030SMax Reitz        os.remove(new_img)
362adfe2030SMax Reitz
363adfe2030SMax Reitz    def test_remove_on_empty(self):
3641d701e0eSMax Reitz        result = self.vm.qmp('blockdev-open-tray', id=self.device_name)
365adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
366adfe2030SMax Reitz
367adfe2030SMax Reitz        self.wait_for_open()
368adfe2030SMax Reitz
36934ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
370adfe2030SMax Reitz        # Should be a no-op
371adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
372adfe2030SMax Reitz
373dfc82894SKevin Wolf# Do this in a function to avoid leaking variables like case into the global
374dfc82894SKevin Wolf# name space (otherwise tests would be run for the abstract base classes)
375dfc82894SKevin Wolfdef create_basic_test_classes():
376dfc82894SKevin Wolf    for (media, interface, has_real_tray) in [ ('cdrom', 'ide', True),
377dfc82894SKevin Wolf                                               ('cdrom', 'scsi', True),
378dfc82894SKevin Wolf                                               ('disk', 'floppy', False) ]:
379adfe2030SMax Reitz
380dfc82894SKevin Wolf        for case in [ TestInitiallyFilled, TestInitiallyEmpty ]:
38119462c4bSKevin Wolf            for use_drive in [ True, False ]:
382dfc82894SKevin Wolf                attr = { 'media': media,
383dfc82894SKevin Wolf                         'interface': interface,
38419462c4bSKevin Wolf                         'has_real_tray': has_real_tray,
38519462c4bSKevin Wolf                         'use_drive': use_drive }
386adfe2030SMax Reitz
38719462c4bSKevin Wolf                name = '%s_%s_%s_%s' % (case.__name__, media, interface,
38819462c4bSKevin Wolf                                        'drive' if use_drive else 'blockdev')
389dfc82894SKevin Wolf                globals()[name] = type(name, (case, ), attr)
390adfe2030SMax Reitz
391dfc82894SKevin Wolfcreate_basic_test_classes()
392adfe2030SMax Reitz
393adfe2030SMax Reitzclass TestChangeReadOnly(ChangeBaseClass):
3941d701e0eSMax Reitz    device_name = 'qdev0'
3951d701e0eSMax Reitz
396adfe2030SMax Reitz    def setUp(self):
397adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440k')
398adfe2030SMax Reitz        qemu_img('create', '-f', iotests.imgfmt, new_img, '1440k')
399adfe2030SMax Reitz        self.vm = iotests.VM()
400adfe2030SMax Reitz
401adfe2030SMax Reitz    def tearDown(self):
402adfe2030SMax Reitz        self.vm.shutdown()
4034803c5cdSEduardo Habkost        os.chmod(old_img, 0o666)
4044803c5cdSEduardo Habkost        os.chmod(new_img, 0o666)
405adfe2030SMax Reitz        os.remove(old_img)
406adfe2030SMax Reitz        os.remove(new_img)
407adfe2030SMax Reitz
408adfe2030SMax Reitz    def test_ro_ro_retain(self):
4094803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
4104803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
4111d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
4121d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
413adfe2030SMax Reitz        self.vm.launch()
414adfe2030SMax Reitz
415adfe2030SMax Reitz        result = self.vm.qmp('query-block')
416adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
417adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
418adfe2030SMax Reitz
4191d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
420adfe2030SMax Reitz                                                       filename=new_img,
421adfe2030SMax Reitz                                                       format=iotests.imgfmt,
422adfe2030SMax Reitz                                                       read_only_mode='retain')
423adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
424adfe2030SMax Reitz
425adfe2030SMax Reitz        result = self.vm.qmp('query-block')
426adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
427adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
428adfe2030SMax Reitz
429adfe2030SMax Reitz    def test_ro_rw_retain(self):
4304803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
4311d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
4321d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
433adfe2030SMax Reitz        self.vm.launch()
434adfe2030SMax Reitz
435adfe2030SMax Reitz        result = self.vm.qmp('query-block')
436adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
437adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
438adfe2030SMax Reitz
4391d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
440adfe2030SMax Reitz                                                       filename=new_img,
441adfe2030SMax Reitz                                                       format=iotests.imgfmt,
442adfe2030SMax Reitz                                                       read_only_mode='retain')
443adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
444adfe2030SMax Reitz
445adfe2030SMax Reitz        result = self.vm.qmp('query-block')
446adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
447adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
448adfe2030SMax Reitz
449d926f4ddSKevin Wolf    @iotests.skip_if_user_is_root
450adfe2030SMax Reitz    def test_rw_ro_retain(self):
4514803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
4521d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
4531d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
454adfe2030SMax Reitz        self.vm.launch()
455adfe2030SMax Reitz
456adfe2030SMax Reitz        result = self.vm.qmp('query-block')
457adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
458adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
459adfe2030SMax Reitz
4601d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
461adfe2030SMax Reitz                                                       filename=new_img,
462adfe2030SMax Reitz                                                       format=iotests.imgfmt,
463adfe2030SMax Reitz                                                       read_only_mode='retain')
464adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
465adfe2030SMax Reitz
466fa1cfb40SKevin Wolf        self.assertEqual(self.vm.get_qmp_events(wait=False), [])
467adfe2030SMax Reitz
468adfe2030SMax Reitz        result = self.vm.qmp('query-block')
469adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
470adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
471adfe2030SMax Reitz
472adfe2030SMax Reitz    def test_ro_rw(self):
4734803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
4741d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
4751d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
476adfe2030SMax Reitz        self.vm.launch()
477adfe2030SMax Reitz
478adfe2030SMax Reitz        result = self.vm.qmp('query-block')
479adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
480adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
481adfe2030SMax Reitz
482adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
4831d701e0eSMax Reitz                             id=self.device_name,
484adfe2030SMax Reitz                             filename=new_img,
485adfe2030SMax Reitz                             format=iotests.imgfmt,
486adfe2030SMax Reitz                             read_only_mode='read-write')
487adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
488adfe2030SMax Reitz
489adfe2030SMax Reitz        result = self.vm.qmp('query-block')
490adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
491adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
492adfe2030SMax Reitz
493adfe2030SMax Reitz    def test_rw_ro(self):
4944803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
4951d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
4961d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
497adfe2030SMax Reitz        self.vm.launch()
498adfe2030SMax Reitz
499adfe2030SMax Reitz        result = self.vm.qmp('query-block')
500adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
501adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
502adfe2030SMax Reitz
503adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
5041d701e0eSMax Reitz                             id=self.device_name,
505adfe2030SMax Reitz                             filename=new_img,
506adfe2030SMax Reitz                             format=iotests.imgfmt,
507adfe2030SMax Reitz                             read_only_mode='read-only')
508adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
509adfe2030SMax Reitz
510adfe2030SMax Reitz        result = self.vm.qmp('query-block')
511adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
512adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
513adfe2030SMax Reitz
514adfe2030SMax Reitz    def test_make_rw_ro(self):
5151d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
5161d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
517adfe2030SMax Reitz        self.vm.launch()
518adfe2030SMax Reitz
519adfe2030SMax Reitz        result = self.vm.qmp('query-block')
520adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
521adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
522adfe2030SMax Reitz
523adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
5241d701e0eSMax Reitz                             id=self.device_name,
525adfe2030SMax Reitz                             filename=new_img,
526adfe2030SMax Reitz                             format=iotests.imgfmt,
527adfe2030SMax Reitz                             read_only_mode='read-only')
528adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
529adfe2030SMax Reitz
530adfe2030SMax Reitz        result = self.vm.qmp('query-block')
531adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
532adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
533adfe2030SMax Reitz
534d926f4ddSKevin Wolf    @iotests.skip_if_user_is_root
535adfe2030SMax Reitz    def test_make_ro_rw(self):
5364803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
5371d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
5381d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
539adfe2030SMax Reitz        self.vm.launch()
540adfe2030SMax Reitz
541adfe2030SMax Reitz        result = self.vm.qmp('query-block')
542adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
543adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
544adfe2030SMax Reitz
545adfe2030SMax Reitz        result = self.vm.qmp('blockdev-change-medium',
5461d701e0eSMax Reitz                             id=self.device_name,
547adfe2030SMax Reitz                             filename=new_img,
548adfe2030SMax Reitz                             format=iotests.imgfmt,
549adfe2030SMax Reitz                             read_only_mode='read-write')
550adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
551adfe2030SMax Reitz
552adfe2030SMax Reitz        result = self.vm.qmp('query-block')
553adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
554adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
555adfe2030SMax Reitz
556adfe2030SMax Reitz    def test_make_rw_ro_by_retain(self):
5574803c5cdSEduardo Habkost        os.chmod(old_img, 0o444)
5581d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk,read-only=on', 'none')
5591d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
560adfe2030SMax Reitz        self.vm.launch()
561adfe2030SMax Reitz
562adfe2030SMax Reitz        result = self.vm.qmp('query-block')
563adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
564adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
565adfe2030SMax Reitz
5661d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
567adfe2030SMax Reitz                                                       filename=new_img,
568adfe2030SMax Reitz                                                       format=iotests.imgfmt,
569adfe2030SMax Reitz                                                       read_only_mode='retain')
570adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
571adfe2030SMax Reitz
572adfe2030SMax Reitz        result = self.vm.qmp('query-block')
573adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
574adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
575adfe2030SMax Reitz
576d926f4ddSKevin Wolf    @iotests.skip_if_user_is_root
577adfe2030SMax Reitz    def test_make_ro_rw_by_retain(self):
5784803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
5791d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
5801d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
581adfe2030SMax Reitz        self.vm.launch()
582adfe2030SMax Reitz
583adfe2030SMax Reitz        result = self.vm.qmp('query-block')
584adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
585adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
586adfe2030SMax Reitz
5871d701e0eSMax Reitz        result = self.vm.qmp('blockdev-change-medium', id=self.device_name,
588adfe2030SMax Reitz                                                       filename=new_img,
589adfe2030SMax Reitz                                                       format=iotests.imgfmt,
590adfe2030SMax Reitz                                                       read_only_mode='retain')
591adfe2030SMax Reitz        self.assert_qmp(result, 'error/class', 'GenericError')
592adfe2030SMax Reitz
593adfe2030SMax Reitz        result = self.vm.qmp('query-block')
594adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
595adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
596adfe2030SMax Reitz
597adfe2030SMax Reitz    def test_rw_ro_cycle(self):
5984803c5cdSEduardo Habkost        os.chmod(new_img, 0o444)
5991d701e0eSMax Reitz        self.vm.add_drive(old_img, 'media=disk', 'none')
6001d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
601adfe2030SMax Reitz        self.vm.launch()
602adfe2030SMax Reitz
603adfe2030SMax Reitz        result = self.vm.qmp('query-block')
604adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
605adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
606adfe2030SMax Reitz
607adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
6080153d2f5SKevin Wolf                             node_name='new',
6090153d2f5SKevin Wolf                             driver=iotests.imgfmt,
6100153d2f5SKevin Wolf                             read_only=True,
6110153d2f5SKevin Wolf                             file={'filename': new_img,
6120153d2f5SKevin Wolf                                    'driver': 'file'})
613adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
614adfe2030SMax Reitz
615adfe2030SMax Reitz        result = self.vm.qmp('query-block')
616adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', False)
617adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
618adfe2030SMax Reitz
61934ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
620adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
621adfe2030SMax Reitz
622adfe2030SMax Reitz        result = self.vm.qmp('query-block')
623adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
624adfe2030SMax Reitz
62534ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
626adfe2030SMax Reitz                                                       node_name='new')
627adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
628adfe2030SMax Reitz
629adfe2030SMax Reitz        result = self.vm.qmp('query-block')
630adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
631adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
632adfe2030SMax Reitz
633adfe2030SMax Reitz        result = self.vm.qmp('query-block')
634adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/ro', True)
635adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
636adfe2030SMax Reitz
637adfe2030SMax ReitzGeneralChangeTestsBaseClass = None
638adfe2030SMax ReitzTestInitiallyFilled = None
639adfe2030SMax ReitzTestInitiallyEmpty = None
640adfe2030SMax Reitz
641adfe2030SMax Reitz
642adfe2030SMax Reitzclass TestBlockJobsAfterCycle(ChangeBaseClass):
6431d701e0eSMax Reitz    device_name = 'qdev0'
6441d701e0eSMax Reitz
645adfe2030SMax Reitz    def setUp(self):
6461d701e0eSMax Reitz        qemu_img('create', '-f', iotests.imgfmt, old_img, '1440K')
647adfe2030SMax Reitz
648adfe2030SMax Reitz        self.vm = iotests.VM()
649e4fd2e9dSKevin Wolf        self.vm.add_drive_raw("id=drive0,driver=null-co,if=none")
6501d701e0eSMax Reitz        self.vm.add_device('floppy,drive=drive0,id=%s' % self.device_name)
651adfe2030SMax Reitz        self.vm.launch()
652adfe2030SMax Reitz
653adfe2030SMax Reitz        result = self.vm.qmp('query-block')
654adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/format', 'null-co')
655adfe2030SMax Reitz
656adfe2030SMax Reitz        # For device-less BBs, calling blockdev-open-tray or blockdev-close-tray
657adfe2030SMax Reitz        # is not necessary
65834ce1111SMax Reitz        result = self.vm.qmp('blockdev-remove-medium', id=self.device_name)
659adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
660adfe2030SMax Reitz
661adfe2030SMax Reitz        result = self.vm.qmp('query-block')
662adfe2030SMax Reitz        self.assert_qmp_absent(result, 'return[0]/inserted')
663adfe2030SMax Reitz
664adfe2030SMax Reitz        result = self.vm.qmp('blockdev-add',
6650153d2f5SKevin Wolf                             node_name='node0',
6660153d2f5SKevin Wolf                             driver=iotests.imgfmt,
6670153d2f5SKevin Wolf                             file={'filename': old_img,
6680153d2f5SKevin Wolf                                   'driver': 'file'})
669adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
670adfe2030SMax Reitz
67134ce1111SMax Reitz        result = self.vm.qmp('blockdev-insert-medium', id=self.device_name,
672adfe2030SMax Reitz                                                       node_name='node0')
673adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
674adfe2030SMax Reitz
675adfe2030SMax Reitz        result = self.vm.qmp('query-block')
676adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', old_img)
677adfe2030SMax Reitz
678adfe2030SMax Reitz    def tearDown(self):
679adfe2030SMax Reitz        self.vm.shutdown()
680adfe2030SMax Reitz        os.remove(old_img)
681adfe2030SMax Reitz        try:
682adfe2030SMax Reitz            os.remove(new_img)
683adfe2030SMax Reitz        except OSError:
684adfe2030SMax Reitz            pass
685adfe2030SMax Reitz
686adfe2030SMax Reitz    # We need backing file support
687*ff3caf5aSMax Reitz    @iotests.skip_for_formats(('vpc', 'parallels', 'qcow', 'vdi', 'vmdk', 'raw',
688*ff3caf5aSMax Reitz                               'vhdx'))
689*ff3caf5aSMax Reitz    def test_snapshot_and_commit(self):
690adfe2030SMax Reitz        result = self.vm.qmp('blockdev-snapshot-sync', device='drive0',
691adfe2030SMax Reitz                                                       snapshot_file=new_img,
692adfe2030SMax Reitz                                                       format=iotests.imgfmt)
693adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
694adfe2030SMax Reitz
695adfe2030SMax Reitz        result = self.vm.qmp('query-block')
696adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/inserted/image/filename', new_img)
697adfe2030SMax Reitz        self.assert_qmp(result,
698adfe2030SMax Reitz                        'return[0]/inserted/image/backing-image/filename',
699adfe2030SMax Reitz                        old_img)
700adfe2030SMax Reitz
701adfe2030SMax Reitz        result = self.vm.qmp('block-commit', device='drive0')
702adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
703adfe2030SMax Reitz
704adfe2030SMax Reitz        self.vm.event_wait(name='BLOCK_JOB_READY')
705adfe2030SMax Reitz
706adfe2030SMax Reitz        result = self.vm.qmp('query-block-jobs')
707adfe2030SMax Reitz        self.assert_qmp(result, 'return[0]/device', 'drive0')
708adfe2030SMax Reitz
709adfe2030SMax Reitz        result = self.vm.qmp('block-job-complete', device='drive0')
710adfe2030SMax Reitz        self.assert_qmp(result, 'return', {})
711adfe2030SMax Reitz
712adfe2030SMax Reitz        self.vm.event_wait(name='BLOCK_JOB_COMPLETED')
713adfe2030SMax Reitz
714adfe2030SMax Reitz
715adfe2030SMax Reitzif __name__ == '__main__':
716adfe2030SMax Reitz    if iotests.qemu_default_machine != 'pc':
717adfe2030SMax Reitz        # We need floppy and IDE CD-ROM
718adfe2030SMax Reitz        iotests.notrun('not suitable for this machine type: %s' %
719adfe2030SMax Reitz                       iotests.qemu_default_machine)
720cc8c46b7SMax Reitz    # Need to support image creation
721cc8c46b7SMax Reitz    iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
722103cbc77SMax Reitz                                 'vmdk', 'raw', 'vhdx', 'qed'],
723103cbc77SMax Reitz                 supported_protocols=['file'])
724