xref: /openbmc/qemu/tests/qemu-iotests/055 (revision e5ca8fdd407431e281c6f303dc9f45f63a28048f)
1*e5ca8fddSStefan Hajnoczi#!/usr/bin/env python
2*e5ca8fddSStefan Hajnoczi#
3*e5ca8fddSStefan Hajnoczi# Tests for drive-backup
4*e5ca8fddSStefan Hajnoczi#
5*e5ca8fddSStefan Hajnoczi# Copyright (C) 2013 Red Hat, Inc.
6*e5ca8fddSStefan Hajnoczi#
7*e5ca8fddSStefan Hajnoczi# Based on 041.
8*e5ca8fddSStefan Hajnoczi#
9*e5ca8fddSStefan Hajnoczi# This program is free software; you can redistribute it and/or modify
10*e5ca8fddSStefan Hajnoczi# it under the terms of the GNU General Public License as published by
11*e5ca8fddSStefan Hajnoczi# the Free Software Foundation; either version 2 of the License, or
12*e5ca8fddSStefan Hajnoczi# (at your option) any later version.
13*e5ca8fddSStefan Hajnoczi#
14*e5ca8fddSStefan Hajnoczi# This program is distributed in the hope that it will be useful,
15*e5ca8fddSStefan Hajnoczi# but WITHOUT ANY WARRANTY; without even the implied warranty of
16*e5ca8fddSStefan Hajnoczi# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*e5ca8fddSStefan Hajnoczi# GNU General Public License for more details.
18*e5ca8fddSStefan Hajnoczi#
19*e5ca8fddSStefan Hajnoczi# You should have received a copy of the GNU General Public License
20*e5ca8fddSStefan Hajnoczi# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21*e5ca8fddSStefan Hajnoczi#
22*e5ca8fddSStefan Hajnoczi
23*e5ca8fddSStefan Hajnocziimport time
24*e5ca8fddSStefan Hajnocziimport os
25*e5ca8fddSStefan Hajnocziimport iotests
26*e5ca8fddSStefan Hajnoczifrom iotests import qemu_img, qemu_io
27*e5ca8fddSStefan Hajnoczi
28*e5ca8fddSStefan Hajnoczitest_img = os.path.join(iotests.test_dir, 'test.img')
29*e5ca8fddSStefan Hajnoczitarget_img = os.path.join(iotests.test_dir, 'target.img')
30*e5ca8fddSStefan Hajnoczi
31*e5ca8fddSStefan Hajnocziclass TestSingleDrive(iotests.QMPTestCase):
32*e5ca8fddSStefan Hajnoczi    image_len = 64 * 1024 * 1024 # MB
33*e5ca8fddSStefan Hajnoczi
34*e5ca8fddSStefan Hajnoczi    def setUp(self):
35*e5ca8fddSStefan Hajnoczi        # Write data to the image so we can compare later
36*e5ca8fddSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleDrive.image_len))
37*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0x5d 0 64k', test_img)
38*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0xd5 1M 32k', test_img)
39*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0xdc 32M 124k', test_img)
40*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0xdc 67043328 64k', test_img)
41*e5ca8fddSStefan Hajnoczi
42*e5ca8fddSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
43*e5ca8fddSStefan Hajnoczi        self.vm.launch()
44*e5ca8fddSStefan Hajnoczi
45*e5ca8fddSStefan Hajnoczi    def tearDown(self):
46*e5ca8fddSStefan Hajnoczi        self.vm.shutdown()
47*e5ca8fddSStefan Hajnoczi        os.remove(test_img)
48*e5ca8fddSStefan Hajnoczi        try:
49*e5ca8fddSStefan Hajnoczi            os.remove(target_img)
50*e5ca8fddSStefan Hajnoczi        except OSError:
51*e5ca8fddSStefan Hajnoczi            pass
52*e5ca8fddSStefan Hajnoczi
53*e5ca8fddSStefan Hajnoczi    def test_cancel(self):
54*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
55*e5ca8fddSStefan Hajnoczi
56*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='drive0',
57*e5ca8fddSStefan Hajnoczi                             target=target_img)
58*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
59*e5ca8fddSStefan Hajnoczi
60*e5ca8fddSStefan Hajnoczi        event = self.cancel_and_wait()
61*e5ca8fddSStefan Hajnoczi        self.assert_qmp(event, 'data/type', 'backup')
62*e5ca8fddSStefan Hajnoczi
63*e5ca8fddSStefan Hajnoczi    def test_pause(self):
64*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
65*e5ca8fddSStefan Hajnoczi
66*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='drive0',
67*e5ca8fddSStefan Hajnoczi                             target=target_img)
68*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
69*e5ca8fddSStefan Hajnoczi
70*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('block-job-pause', device='drive0')
71*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
72*e5ca8fddSStefan Hajnoczi
73*e5ca8fddSStefan Hajnoczi        time.sleep(1)
74*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
75*e5ca8fddSStefan Hajnoczi        offset = self.dictpath(result, 'return[0]/offset')
76*e5ca8fddSStefan Hajnoczi
77*e5ca8fddSStefan Hajnoczi        time.sleep(1)
78*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
79*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/offset', offset)
80*e5ca8fddSStefan Hajnoczi
81*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('block-job-resume', device='drive0')
82*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
83*e5ca8fddSStefan Hajnoczi
84*e5ca8fddSStefan Hajnoczi        self.wait_until_completed()
85*e5ca8fddSStefan Hajnoczi
86*e5ca8fddSStefan Hajnoczi        self.vm.shutdown()
87*e5ca8fddSStefan Hajnoczi        self.assertTrue(iotests.compare_images(test_img, target_img),
88*e5ca8fddSStefan Hajnoczi                        'target image does not match source after backup')
89*e5ca8fddSStefan Hajnoczi
90*e5ca8fddSStefan Hajnoczi    def test_medium_not_found(self):
91*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='ide1-cd0',
92*e5ca8fddSStefan Hajnoczi                             target=target_img)
93*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'GenericError')
94*e5ca8fddSStefan Hajnoczi
95*e5ca8fddSStefan Hajnoczi    def test_image_not_found(self):
96*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='drive0',
97*e5ca8fddSStefan Hajnoczi                             mode='existing', target=target_img)
98*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'GenericError')
99*e5ca8fddSStefan Hajnoczi
100*e5ca8fddSStefan Hajnoczi    def test_device_not_found(self):
101*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='nonexistent',
102*e5ca8fddSStefan Hajnoczi                             target=target_img)
103*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'DeviceNotFound')
104*e5ca8fddSStefan Hajnoczi
105*e5ca8fddSStefan Hajnocziclass TestSetSpeed(iotests.QMPTestCase):
106*e5ca8fddSStefan Hajnoczi    image_len = 80 * 1024 * 1024 # MB
107*e5ca8fddSStefan Hajnoczi
108*e5ca8fddSStefan Hajnoczi    def setUp(self):
109*e5ca8fddSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSetSpeed.image_len))
110*e5ca8fddSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
111*e5ca8fddSStefan Hajnoczi        self.vm.launch()
112*e5ca8fddSStefan Hajnoczi
113*e5ca8fddSStefan Hajnoczi    def tearDown(self):
114*e5ca8fddSStefan Hajnoczi        self.vm.shutdown()
115*e5ca8fddSStefan Hajnoczi        os.remove(test_img)
116*e5ca8fddSStefan Hajnoczi        os.remove(target_img)
117*e5ca8fddSStefan Hajnoczi
118*e5ca8fddSStefan Hajnoczi    def test_set_speed(self):
119*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
120*e5ca8fddSStefan Hajnoczi
121*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='drive0',
122*e5ca8fddSStefan Hajnoczi                             target=target_img)
123*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
124*e5ca8fddSStefan Hajnoczi
125*e5ca8fddSStefan Hajnoczi        # Default speed is 0
126*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
127*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
128*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 0)
129*e5ca8fddSStefan Hajnoczi
130*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
131*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
132*e5ca8fddSStefan Hajnoczi
133*e5ca8fddSStefan Hajnoczi        # Ensure the speed we set was accepted
134*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
135*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
136*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
137*e5ca8fddSStefan Hajnoczi
138*e5ca8fddSStefan Hajnoczi        event = self.cancel_and_wait()
139*e5ca8fddSStefan Hajnoczi        self.assert_qmp(event, 'data/type', 'backup')
140*e5ca8fddSStefan Hajnoczi
141*e5ca8fddSStefan Hajnoczi        # Check setting speed in drive-backup works
142*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='drive0',
143*e5ca8fddSStefan Hajnoczi                             target=target_img, speed=4*1024*1024)
144*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
145*e5ca8fddSStefan Hajnoczi
146*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
147*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
148*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
149*e5ca8fddSStefan Hajnoczi
150*e5ca8fddSStefan Hajnoczi        event = self.cancel_and_wait()
151*e5ca8fddSStefan Hajnoczi        self.assert_qmp(event, 'data/type', 'backup')
152*e5ca8fddSStefan Hajnoczi
153*e5ca8fddSStefan Hajnoczi    def test_set_speed_invalid(self):
154*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
155*e5ca8fddSStefan Hajnoczi
156*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='drive0',
157*e5ca8fddSStefan Hajnoczi                             target=target_img, speed=-1)
158*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'GenericError')
159*e5ca8fddSStefan Hajnoczi
160*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
161*e5ca8fddSStefan Hajnoczi
162*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('drive-backup', device='drive0',
163*e5ca8fddSStefan Hajnoczi                             target=target_img)
164*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
165*e5ca8fddSStefan Hajnoczi
166*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
167*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'GenericError')
168*e5ca8fddSStefan Hajnoczi
169*e5ca8fddSStefan Hajnoczi        event = self.cancel_and_wait()
170*e5ca8fddSStefan Hajnoczi        self.assert_qmp(event, 'data/type', 'backup')
171*e5ca8fddSStefan Hajnoczi
172*e5ca8fddSStefan Hajnocziclass TestSingleTransaction(iotests.QMPTestCase):
173*e5ca8fddSStefan Hajnoczi    image_len = 64 * 1024 * 1024 # MB
174*e5ca8fddSStefan Hajnoczi
175*e5ca8fddSStefan Hajnoczi    def setUp(self):
176*e5ca8fddSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleTransaction.image_len))
177*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0x5d 0 64k', test_img)
178*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0xd5 1M 32k', test_img)
179*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0xdc 32M 124k', test_img)
180*e5ca8fddSStefan Hajnoczi        qemu_io('-c', 'write -P0xdc 67043328 64k', test_img)
181*e5ca8fddSStefan Hajnoczi
182*e5ca8fddSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
183*e5ca8fddSStefan Hajnoczi        self.vm.launch()
184*e5ca8fddSStefan Hajnoczi
185*e5ca8fddSStefan Hajnoczi    def tearDown(self):
186*e5ca8fddSStefan Hajnoczi        self.vm.shutdown()
187*e5ca8fddSStefan Hajnoczi        os.remove(test_img)
188*e5ca8fddSStefan Hajnoczi        try:
189*e5ca8fddSStefan Hajnoczi            os.remove(target_img)
190*e5ca8fddSStefan Hajnoczi        except OSError:
191*e5ca8fddSStefan Hajnoczi            pass
192*e5ca8fddSStefan Hajnoczi
193*e5ca8fddSStefan Hajnoczi    def test_cancel(self):
194*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
195*e5ca8fddSStefan Hajnoczi
196*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('transaction', actions=[{
197*e5ca8fddSStefan Hajnoczi                'type': 'drive-backup',
198*e5ca8fddSStefan Hajnoczi                'data': { 'device': 'drive0',
199*e5ca8fddSStefan Hajnoczi                          'target': target_img },
200*e5ca8fddSStefan Hajnoczi            }
201*e5ca8fddSStefan Hajnoczi        ])
202*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
203*e5ca8fddSStefan Hajnoczi
204*e5ca8fddSStefan Hajnoczi        event = self.cancel_and_wait()
205*e5ca8fddSStefan Hajnoczi        self.assert_qmp(event, 'data/type', 'backup')
206*e5ca8fddSStefan Hajnoczi
207*e5ca8fddSStefan Hajnoczi    def test_pause(self):
208*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
209*e5ca8fddSStefan Hajnoczi
210*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('transaction', actions=[{
211*e5ca8fddSStefan Hajnoczi                'type': 'drive-backup',
212*e5ca8fddSStefan Hajnoczi                'data': { 'device': 'drive0',
213*e5ca8fddSStefan Hajnoczi                          'target': target_img },
214*e5ca8fddSStefan Hajnoczi            }
215*e5ca8fddSStefan Hajnoczi        ])
216*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
217*e5ca8fddSStefan Hajnoczi
218*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('block-job-pause', device='drive0')
219*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
220*e5ca8fddSStefan Hajnoczi
221*e5ca8fddSStefan Hajnoczi        time.sleep(1)
222*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
223*e5ca8fddSStefan Hajnoczi        offset = self.dictpath(result, 'return[0]/offset')
224*e5ca8fddSStefan Hajnoczi
225*e5ca8fddSStefan Hajnoczi        time.sleep(1)
226*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
227*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/offset', offset)
228*e5ca8fddSStefan Hajnoczi
229*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('block-job-resume', device='drive0')
230*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
231*e5ca8fddSStefan Hajnoczi
232*e5ca8fddSStefan Hajnoczi        self.wait_until_completed()
233*e5ca8fddSStefan Hajnoczi
234*e5ca8fddSStefan Hajnoczi        self.vm.shutdown()
235*e5ca8fddSStefan Hajnoczi        self.assertTrue(iotests.compare_images(test_img, target_img),
236*e5ca8fddSStefan Hajnoczi                        'target image does not match source after backup')
237*e5ca8fddSStefan Hajnoczi
238*e5ca8fddSStefan Hajnoczi    def test_medium_not_found(self):
239*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('transaction', actions=[{
240*e5ca8fddSStefan Hajnoczi                'type': 'drive-backup',
241*e5ca8fddSStefan Hajnoczi                'data': { 'device': 'ide1-cd0',
242*e5ca8fddSStefan Hajnoczi                          'target': target_img },
243*e5ca8fddSStefan Hajnoczi            }
244*e5ca8fddSStefan Hajnoczi        ])
245*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'GenericError')
246*e5ca8fddSStefan Hajnoczi
247*e5ca8fddSStefan Hajnoczi    def test_image_not_found(self):
248*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('transaction', actions=[{
249*e5ca8fddSStefan Hajnoczi                'type': 'drive-backup',
250*e5ca8fddSStefan Hajnoczi                'data': { 'device': 'drive0',
251*e5ca8fddSStefan Hajnoczi                          'mode': 'existing',
252*e5ca8fddSStefan Hajnoczi                          'target': target_img },
253*e5ca8fddSStefan Hajnoczi            }
254*e5ca8fddSStefan Hajnoczi        ])
255*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'GenericError')
256*e5ca8fddSStefan Hajnoczi
257*e5ca8fddSStefan Hajnoczi    def test_device_not_found(self):
258*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('transaction', actions=[{
259*e5ca8fddSStefan Hajnoczi                'type': 'drive-backup',
260*e5ca8fddSStefan Hajnoczi                'data': { 'device': 'nonexistent',
261*e5ca8fddSStefan Hajnoczi                          'mode': 'existing',
262*e5ca8fddSStefan Hajnoczi                          'target': target_img },
263*e5ca8fddSStefan Hajnoczi            }
264*e5ca8fddSStefan Hajnoczi        ])
265*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'DeviceNotFound')
266*e5ca8fddSStefan Hajnoczi
267*e5ca8fddSStefan Hajnoczi    def test_abort(self):
268*e5ca8fddSStefan Hajnoczi        result = self.vm.qmp('transaction', actions=[{
269*e5ca8fddSStefan Hajnoczi                'type': 'drive-backup',
270*e5ca8fddSStefan Hajnoczi                'data': { 'device': 'nonexistent',
271*e5ca8fddSStefan Hajnoczi                          'mode': 'existing',
272*e5ca8fddSStefan Hajnoczi                          'target': target_img },
273*e5ca8fddSStefan Hajnoczi            }, {
274*e5ca8fddSStefan Hajnoczi                'type': 'Abort',
275*e5ca8fddSStefan Hajnoczi                'data': {},
276*e5ca8fddSStefan Hajnoczi            }
277*e5ca8fddSStefan Hajnoczi        ])
278*e5ca8fddSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'GenericError')
279*e5ca8fddSStefan Hajnoczi        self.assert_no_active_block_jobs()
280*e5ca8fddSStefan Hajnoczi
281*e5ca8fddSStefan Hajnocziif __name__ == '__main__':
282*e5ca8fddSStefan Hajnoczi    iotests.main(supported_fmts=['raw', 'qcow2'])
283