xref: /qemu/tests/qemu-iotests/030 (revision 863a5d04)
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
35e425306aSStefan Hajnoczi    def cancel_and_wait(self, drive='drive0'):
36e425306aSStefan Hajnoczi        '''Cancel a block job and wait for it to finish'''
37e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-cancel', device=drive)
38e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
39e425306aSStefan Hajnoczi
40e425306aSStefan Hajnoczi        cancelled = False
41e425306aSStefan Hajnoczi        while not cancelled:
42e425306aSStefan Hajnoczi            for event in self.vm.get_qmp_events(wait=True):
43e425306aSStefan Hajnoczi                if event['event'] == 'BLOCK_JOB_CANCELLED':
44e425306aSStefan Hajnoczi                    self.assert_qmp(event, 'data/type', 'stream')
45e425306aSStefan Hajnoczi                    self.assert_qmp(event, 'data/device', drive)
46e425306aSStefan Hajnoczi                    cancelled = True
47e425306aSStefan Hajnoczi
48e425306aSStefan Hajnoczi        self.assert_no_active_streams()
49e425306aSStefan 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()
81*863a5d04SPaolo Bonzini        self.vm.shutdown()
8237ce63ebSStefan Hajnoczi
8337ce63ebSStefan Hajnoczi        self.assertFalse('sectors not allocated' in qemu_io('-c', 'map', test_img),
8437ce63ebSStefan Hajnoczi                         'image file not fully populated after streaming')
8537ce63ebSStefan Hajnoczi
8637ce63ebSStefan Hajnoczi    def test_device_not_found(self):
87db58f9c0SStefan Hajnoczi        result = self.vm.qmp('block-stream', device='nonexistent')
8837ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'DeviceNotFound')
8937ce63ebSStefan Hajnoczi
9037ce63ebSStefan Hajnocziclass TestStreamStop(ImageStreamingTestCase):
9137ce63ebSStefan Hajnoczi    image_len = 8 * 1024 * 1024 * 1024 # GB
9237ce63ebSStefan Hajnoczi
9337ce63ebSStefan Hajnoczi    def setUp(self):
9437ce63ebSStefan Hajnoczi        qemu_img('create', backing_img, str(TestStreamStop.image_len))
9537ce63ebSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
9637ce63ebSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
9737ce63ebSStefan Hajnoczi        self.vm.launch()
9837ce63ebSStefan Hajnoczi
9937ce63ebSStefan Hajnoczi    def tearDown(self):
10037ce63ebSStefan Hajnoczi        self.vm.shutdown()
10137ce63ebSStefan Hajnoczi        os.remove(test_img)
10237ce63ebSStefan Hajnoczi        os.remove(backing_img)
10337ce63ebSStefan Hajnoczi
10437ce63ebSStefan Hajnoczi    def test_stream_stop(self):
10537ce63ebSStefan Hajnoczi        import time
10637ce63ebSStefan Hajnoczi
10737ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
10837ce63ebSStefan Hajnoczi
109db58f9c0SStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
11037ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
11137ce63ebSStefan Hajnoczi
11237ce63ebSStefan Hajnoczi        time.sleep(1)
11337ce63ebSStefan Hajnoczi        events = self.vm.get_qmp_events(wait=False)
11437ce63ebSStefan Hajnoczi        self.assertEqual(events, [], 'unexpected QMP event: %s' % events)
11537ce63ebSStefan Hajnoczi
116e425306aSStefan Hajnoczi        self.cancel_and_wait()
11737ce63ebSStefan Hajnoczi
11837ce63ebSStefan Hajnocziclass TestSetSpeed(ImageStreamingTestCase):
11937ce63ebSStefan Hajnoczi    image_len = 80 * 1024 * 1024 # MB
12037ce63ebSStefan Hajnoczi
12137ce63ebSStefan Hajnoczi    def setUp(self):
12237ce63ebSStefan Hajnoczi        qemu_img('create', backing_img, str(TestSetSpeed.image_len))
12337ce63ebSStefan Hajnoczi        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
12437ce63ebSStefan Hajnoczi        self.vm = iotests.VM().add_drive(test_img)
12537ce63ebSStefan Hajnoczi        self.vm.launch()
12637ce63ebSStefan Hajnoczi
12737ce63ebSStefan Hajnoczi    def tearDown(self):
12837ce63ebSStefan Hajnoczi        self.vm.shutdown()
12937ce63ebSStefan Hajnoczi        os.remove(test_img)
13037ce63ebSStefan Hajnoczi        os.remove(backing_img)
13137ce63ebSStefan Hajnoczi
132e425306aSStefan Hajnoczi    # This is a short performance test which is not run by default.
133e425306aSStefan Hajnoczi    # Invoke "IMGFMT=qed ./030 TestSetSpeed.perf_test_throughput"
134e425306aSStefan Hajnoczi    def perf_test_throughput(self):
13537ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
13637ce63ebSStefan Hajnoczi
137db58f9c0SStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
13837ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
13937ce63ebSStefan Hajnoczi
140e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
14137ce63ebSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
14237ce63ebSStefan Hajnoczi
14337ce63ebSStefan Hajnoczi        completed = False
14437ce63ebSStefan Hajnoczi        while not completed:
14537ce63ebSStefan Hajnoczi            for event in self.vm.get_qmp_events(wait=True):
14637ce63ebSStefan Hajnoczi                if event['event'] == 'BLOCK_JOB_COMPLETED':
14737ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/type', 'stream')
14837ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/device', 'drive0')
14937ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/offset', self.image_len)
15037ce63ebSStefan Hajnoczi                    self.assert_qmp(event, 'data/len', self.image_len)
15137ce63ebSStefan Hajnoczi                    completed = True
15237ce63ebSStefan Hajnoczi
15337ce63ebSStefan Hajnoczi        self.assert_no_active_streams()
15437ce63ebSStefan Hajnoczi
155e425306aSStefan Hajnoczi    def test_set_speed(self):
156e425306aSStefan Hajnoczi        self.assert_no_active_streams()
157e425306aSStefan Hajnoczi
158e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
159e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
160e425306aSStefan Hajnoczi
161e425306aSStefan Hajnoczi        # Default speed is 0
162e425306aSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
163e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
164e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 0)
165e425306aSStefan Hajnoczi
166e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=8 * 1024 * 1024)
167e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
168e425306aSStefan Hajnoczi
169e425306aSStefan Hajnoczi        # Ensure the speed we set was accepted
170e425306aSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
171e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
172e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 8 * 1024 * 1024)
173e425306aSStefan Hajnoczi
174e425306aSStefan Hajnoczi        self.cancel_and_wait()
175e425306aSStefan Hajnoczi
176e425306aSStefan Hajnoczi        # Check setting speed in block-stream works
177e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0', speed=4 * 1024 * 1024)
178e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
179e425306aSStefan Hajnoczi
180e425306aSStefan Hajnoczi        result = self.vm.qmp('query-block-jobs')
181e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/device', 'drive0')
182e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return[0]/speed', 4 * 1024 * 1024)
183e425306aSStefan Hajnoczi
184e425306aSStefan Hajnoczi        self.cancel_and_wait()
185e425306aSStefan Hajnoczi
186e425306aSStefan Hajnoczi    def test_set_speed_invalid(self):
187e425306aSStefan Hajnoczi        self.assert_no_active_streams()
188e425306aSStefan Hajnoczi
189e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0', speed=-1)
190e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'InvalidParameter')
191e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/data/name', 'speed')
192e425306aSStefan Hajnoczi
193e425306aSStefan Hajnoczi        self.assert_no_active_streams()
194e425306aSStefan Hajnoczi
195e425306aSStefan Hajnoczi        result = self.vm.qmp('block-stream', device='drive0')
196e425306aSStefan Hajnoczi        self.assert_qmp(result, 'return', {})
197e425306aSStefan Hajnoczi
198e425306aSStefan Hajnoczi        result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
199e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/class', 'InvalidParameter')
200e425306aSStefan Hajnoczi        self.assert_qmp(result, 'error/data/name', 'speed')
201e425306aSStefan Hajnoczi
202e425306aSStefan Hajnoczi        self.cancel_and_wait()
203e425306aSStefan Hajnoczi
20437ce63ebSStefan Hajnocziif __name__ == '__main__':
20537ce63ebSStefan Hajnoczi    iotests.main(supported_fmts=['qcow2', 'qed'])
206