xref: /qemu/tests/qemu-iotests/030 (revision e425306a)
137ce63ebSStefan Hajnoczi#!/usr/bin/env python
237ce63ebSStefan Hajnoczi#
337ce63ebSStefan Hajnoczi# Tests for image streaming.
437ce63ebSStefan Hajnoczi#
537ce63ebSStefan Hajnoczi# Copyright (C) 2012 IBM Corp.
637ce63ebSStefan Hajnoczi#
737ce63ebSStefan Hajnoczi# This program is free software; you can redistribute it and/or modify
837ce63ebSStefan Hajnoczi# it under the terms of the GNU General Public License as published by
937ce63ebSStefan Hajnoczi# the Free Software Foundation; either version 2 of the License, or
1037ce63ebSStefan Hajnoczi# (at your option) any later version.
1137ce63ebSStefan Hajnoczi#
1237ce63ebSStefan Hajnoczi# This program is distributed in the hope that it will be useful,
1337ce63ebSStefan Hajnoczi# but WITHOUT ANY WARRANTY; without even the implied warranty of
1437ce63ebSStefan Hajnoczi# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1537ce63ebSStefan Hajnoczi# GNU General Public License for more details.
1637ce63ebSStefan Hajnoczi#
1737ce63ebSStefan Hajnoczi# You should have received a copy of the GNU General Public License
1837ce63ebSStefan Hajnoczi# along with this program.  If not, see <http://www.gnu.org/licenses/>.
1937ce63ebSStefan Hajnoczi#
2037ce63ebSStefan Hajnoczi
2137ce63ebSStefan Hajnocziimport os
2237ce63ebSStefan Hajnocziimport iotests
2337ce63ebSStefan Hajnoczifrom iotests import qemu_img, qemu_io
2437ce63ebSStefan Hajnoczi
2537ce63ebSStefan Hajnoczibacking_img = os.path.join(iotests.test_dir, 'backing.img')
2637ce63ebSStefan Hajnoczitest_img = os.path.join(iotests.test_dir, 'test.img')
2737ce63ebSStefan Hajnoczi
2837ce63ebSStefan Hajnocziclass ImageStreamingTestCase(iotests.QMPTestCase):
2937ce63ebSStefan Hajnoczi    '''Abstract base class for image streaming test cases'''
3037ce63ebSStefan Hajnoczi
3137ce63ebSStefan Hajnoczi    def assert_no_active_streams(self):
3237ce63ebSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
3337ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', [])
3437ce63ebSStefan Hajnoczi
35*e425306aSStefan Hajnoczi    def cancel_and_wait(self, drive='drive0'):
36*e425306aSStefan Hajnoczi        '''Cancel a block job and wait for it to finish'''
37*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-cancel', device=drive)
38*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
39*e425306aSStefan Hajnoczi
40*e425306aSStefan Hajnoczi        cancelled = False
41*e425306aSStefan Hajnoczi        while not cancelled:
42*e425306aSStefan Hajnoczi            for event in self.vm.get_qmp_events(wait=True):
43*e425306aSStefan Hajnoczi                if event['event'] == 'BLOCK_JOB_CANCELLED':
44*e425306aSStefan Hajnoczi                    self.assert_qmp(event, 'data/type', 'stream')
45*e425306aSStefan Hajnoczi                    self.assert_qmp(event, 'data/device', drive)
46*e425306aSStefan Hajnoczi                    cancelled = True
47*e425306aSStefan Hajnoczi
48*e425306aSStefan Hajnoczi        self.assert_no_active_streams()
49*e425306aSStefan Hajnoczi
5037ce63ebSStefan Hajnocziclass TestSingleDrive(ImageStreamingTestCase):
5137ce63ebSStefan Hajnoczi    image_len = 1 * 1024 * 1024 # MB
5237ce63ebSStefan Hajnoczi
5337ce63ebSStefan Hajnoczi    def setUp(self):
5437ce63ebSStefan Hajnoczi        qemu_img('create', backing_img, str(TestSingleDrive.image_len))
5537ce63ebSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
5637ce63ebSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
5737ce63ebSStefan Hajnoczi        self.vm.launch()
5837ce63ebSStefan Hajnoczi
5937ce63ebSStefan Hajnoczi    def tearDown(self):
6037ce63ebSStefan Hajnoczi        self.vm.shutdown()
6137ce63ebSStefan Hajnoczi        os.remove(test_img)
6237ce63ebSStefan Hajnoczi        os.remove(backing_img)
6337ce63ebSStefan Hajnoczi
6437ce63ebSStefan Hajnoczi    def test_stream(self):
6537ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
6637ce63ebSStefan Hajnoczi
67db58f9c0SStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
6837ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
6937ce63ebSStefan Hajnoczi
7037ce63ebSStefan Hajnoczi        completed = False
7137ce63ebSStefan Hajnoczi        while not completed:
7237ce63ebSStefan Hajnoczi            for event in self.vm.get_qmp_events(wait=True):
7337ce63ebSStefan Hajnoczi                if event['event'] == 'BLOCK_JOB_COMPLETED':
7437ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/type', 'stream')
7537ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/device', 'drive0')
7637ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/offset', self.image_len)
7737ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/len', self.image_len)
7837ce63ebSStefan Hajnoczi                    completed = True
7937ce63ebSStefan Hajnoczi
8037ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
8137ce63ebSStefan Hajnoczi
8237ce63ebSStefan Hajnoczi        self.assertFalse('sectors not allocated' in qemu_io('-c', 'map', test_img),
8337ce63ebSStefan Hajnoczi                         'image file not fully populated after streaming')
8437ce63ebSStefan Hajnoczi
8537ce63ebSStefan Hajnoczi    def test_device_not_found(self):
86db58f9c0SStefan Hajnoczi        result = self.vm.qmp('block-stream', device='nonexistent')
8737ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'DeviceNotFound')
8837ce63ebSStefan Hajnoczi
8937ce63ebSStefan Hajnocziclass TestStreamStop(ImageStreamingTestCase):
9037ce63ebSStefan Hajnoczi    image_len = 8 * 1024 * 1024 * 1024 # GB
9137ce63ebSStefan Hajnoczi
9237ce63ebSStefan Hajnoczi    def setUp(self):
9337ce63ebSStefan Hajnoczi        qemu_img('create', backing_img, str(TestStreamStop.image_len))
9437ce63ebSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
9537ce63ebSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
9637ce63ebSStefan Hajnoczi        self.vm.launch()
9737ce63ebSStefan Hajnoczi
9837ce63ebSStefan Hajnoczi    def tearDown(self):
9937ce63ebSStefan Hajnoczi        self.vm.shutdown()
10037ce63ebSStefan Hajnoczi        os.remove(test_img)
10137ce63ebSStefan Hajnoczi        os.remove(backing_img)
10237ce63ebSStefan Hajnoczi
10337ce63ebSStefan Hajnoczi    def test_stream_stop(self):
10437ce63ebSStefan Hajnoczi        import time
10537ce63ebSStefan Hajnoczi
10637ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
10737ce63ebSStefan Hajnoczi
108db58f9c0SStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
10937ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
11037ce63ebSStefan Hajnoczi
11137ce63ebSStefan Hajnoczi        time.sleep(1)
11237ce63ebSStefan Hajnoczi        events = self.vm.get_qmp_events(wait=False)
11337ce63ebSStefan Hajnoczi        self.assertEqual(events, [], 'unexpected QMP event: %s' % events)
11437ce63ebSStefan Hajnoczi
115*e425306aSStefan Hajnoczi        self.cancel_and_wait()
11637ce63ebSStefan Hajnoczi
11737ce63ebSStefan Hajnocziclass TestSetSpeed(ImageStreamingTestCase):
11837ce63ebSStefan Hajnoczi    image_len = 80 * 1024 * 1024 # MB
11937ce63ebSStefan Hajnoczi
12037ce63ebSStefan Hajnoczi    def setUp(self):
12137ce63ebSStefan Hajnoczi        qemu_img('create', backing_img, str(TestSetSpeed.image_len))
12237ce63ebSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
12337ce63ebSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
12437ce63ebSStefan Hajnoczi        self.vm.launch()
12537ce63ebSStefan Hajnoczi
12637ce63ebSStefan Hajnoczi    def tearDown(self):
12737ce63ebSStefan Hajnoczi        self.vm.shutdown()
12837ce63ebSStefan Hajnoczi        os.remove(test_img)
12937ce63ebSStefan Hajnoczi        os.remove(backing_img)
13037ce63ebSStefan Hajnoczi
131*e425306aSStefan Hajnoczi    # This is a short performance test which is not run by default.
132*e425306aSStefan Hajnoczi    # Invoke "IMGFMT=qed ./030 TestSetSpeed.perf_test_throughput"
133*e425306aSStefan Hajnoczi    def perf_test_throughput(self):
13437ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
13537ce63ebSStefan Hajnoczi
136db58f9c0SStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
13737ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
13837ce63ebSStefan Hajnoczi
139*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
14037ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
14137ce63ebSStefan Hajnoczi
14237ce63ebSStefan Hajnoczi        completed = False
14337ce63ebSStefan Hajnoczi        while not completed:
14437ce63ebSStefan Hajnoczi            for event in self.vm.get_qmp_events(wait=True):
14537ce63ebSStefan Hajnoczi                if event['event'] == 'BLOCK_JOB_COMPLETED':
14637ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/type', 'stream')
14737ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/device', 'drive0')
14837ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/offset', self.image_len)
14937ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/len', self.image_len)
15037ce63ebSStefan Hajnoczi                    completed = True
15137ce63ebSStefan Hajnoczi
15237ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
15337ce63ebSStefan Hajnoczi
154*e425306aSStefan Hajnoczi    def test_set_speed(self):
155*e425306aSStefan Hajnoczi        self.assert_no_active_streams()
156*e425306aSStefan Hajnoczi
157*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
158*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
159*e425306aSStefan Hajnoczi
160*e425306aSStefan Hajnoczi        # Default speed is 0
161*e425306aSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
162*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
163*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 0)
164*e425306aSStefan Hajnoczi
165*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
166*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
167*e425306aSStefan Hajnoczi
168*e425306aSStefan Hajnoczi        # Ensure the speed we set was accepted
169*e425306aSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
170*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
171*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
172*e425306aSStefan Hajnoczi
173*e425306aSStefan Hajnoczi        self.cancel_and_wait()
174*e425306aSStefan Hajnoczi
175*e425306aSStefan Hajnoczi        # Check setting speed in block-stream works
176*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0', speed=4 * 1024 * 1024)
177*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
178*e425306aSStefan Hajnoczi
179*e425306aSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
180*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
181*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
182*e425306aSStefan Hajnoczi
183*e425306aSStefan Hajnoczi        self.cancel_and_wait()
184*e425306aSStefan Hajnoczi
185*e425306aSStefan Hajnoczi    def test_set_speed_invalid(self):
186*e425306aSStefan Hajnoczi        self.assert_no_active_streams()
187*e425306aSStefan Hajnoczi
188*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0', speed=-1)
189*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'InvalidParameter')
190*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/data/name', 'speed')
191*e425306aSStefan Hajnoczi
192*e425306aSStefan Hajnoczi        self.assert_no_active_streams()
193*e425306aSStefan Hajnoczi
194*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
195*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
196*e425306aSStefan Hajnoczi
197*e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
198*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'InvalidParameter')
199*e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/data/name', 'speed')
200*e425306aSStefan Hajnoczi
201*e425306aSStefan Hajnoczi        self.cancel_and_wait()
202*e425306aSStefan Hajnoczi
20337ce63ebSStefan Hajnocziif __name__ == '__main__':
20437ce63ebSStefan Hajnoczi    iotests.main(supported_fmts=['qcow2', 'qed'])
205