1*37ce63ebSStefan Hajnoczi#!/usr/bin/env python 2*37ce63ebSStefan Hajnoczi# 3*37ce63ebSStefan Hajnoczi# Tests for image streaming. 4*37ce63ebSStefan Hajnoczi# 5*37ce63ebSStefan Hajnoczi# Copyright (C) 2012 IBM Corp. 6*37ce63ebSStefan Hajnoczi# 7*37ce63ebSStefan Hajnoczi# This program is free software; you can redistribute it and/or modify 8*37ce63ebSStefan Hajnoczi# it under the terms of the GNU General Public License as published by 9*37ce63ebSStefan Hajnoczi# the Free Software Foundation; either version 2 of the License, or 10*37ce63ebSStefan Hajnoczi# (at your option) any later version. 11*37ce63ebSStefan Hajnoczi# 12*37ce63ebSStefan Hajnoczi# This program is distributed in the hope that it will be useful, 13*37ce63ebSStefan Hajnoczi# but WITHOUT ANY WARRANTY; without even the implied warranty of 14*37ce63ebSStefan Hajnoczi# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*37ce63ebSStefan Hajnoczi# GNU General Public License for more details. 16*37ce63ebSStefan Hajnoczi# 17*37ce63ebSStefan Hajnoczi# You should have received a copy of the GNU General Public License 18*37ce63ebSStefan Hajnoczi# along with this program. If not, see <http://www.gnu.org/licenses/>. 19*37ce63ebSStefan Hajnoczi# 20*37ce63ebSStefan Hajnoczi 21*37ce63ebSStefan Hajnocziimport os 22*37ce63ebSStefan Hajnocziimport iotests 23*37ce63ebSStefan Hajnoczifrom iotests import qemu_img, qemu_io 24*37ce63ebSStefan Hajnoczi 25*37ce63ebSStefan Hajnoczibacking_img = os.path.join(iotests.test_dir, 'backing.img') 26*37ce63ebSStefan Hajnoczitest_img = os.path.join(iotests.test_dir, 'test.img') 27*37ce63ebSStefan Hajnoczi 28*37ce63ebSStefan Hajnocziclass ImageStreamingTestCase(iotests.QMPTestCase): 29*37ce63ebSStefan Hajnoczi '''Abstract base class for image streaming test cases''' 30*37ce63ebSStefan Hajnoczi 31*37ce63ebSStefan Hajnoczi def assert_no_active_streams(self): 32*37ce63ebSStefan Hajnoczi result = self.vm.qmp('query-block-jobs') 33*37ce63ebSStefan Hajnoczi self.assert_qmp(result, 'return', []) 34*37ce63ebSStefan Hajnoczi 35*37ce63ebSStefan Hajnocziclass TestSingleDrive(ImageStreamingTestCase): 36*37ce63ebSStefan Hajnoczi image_len = 1 * 1024 * 1024 # MB 37*37ce63ebSStefan Hajnoczi 38*37ce63ebSStefan Hajnoczi def setUp(self): 39*37ce63ebSStefan Hajnoczi qemu_img('create', backing_img, str(TestSingleDrive.image_len)) 40*37ce63ebSStefan Hajnoczi qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) 41*37ce63ebSStefan Hajnoczi self.vm = iotests.VM().add_drive(test_img) 42*37ce63ebSStefan Hajnoczi self.vm.launch() 43*37ce63ebSStefan Hajnoczi 44*37ce63ebSStefan Hajnoczi def tearDown(self): 45*37ce63ebSStefan Hajnoczi self.vm.shutdown() 46*37ce63ebSStefan Hajnoczi os.remove(test_img) 47*37ce63ebSStefan Hajnoczi os.remove(backing_img) 48*37ce63ebSStefan Hajnoczi 49*37ce63ebSStefan Hajnoczi def test_stream(self): 50*37ce63ebSStefan Hajnoczi self.assert_no_active_streams() 51*37ce63ebSStefan Hajnoczi 52*37ce63ebSStefan Hajnoczi result = self.vm.qmp('block_stream', device='drive0') 53*37ce63ebSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 54*37ce63ebSStefan Hajnoczi 55*37ce63ebSStefan Hajnoczi completed = False 56*37ce63ebSStefan Hajnoczi while not completed: 57*37ce63ebSStefan Hajnoczi for event in self.vm.get_qmp_events(wait=True): 58*37ce63ebSStefan Hajnoczi if event['event'] == 'BLOCK_JOB_COMPLETED': 59*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'stream') 60*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/device', 'drive0') 61*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/offset', self.image_len) 62*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/len', self.image_len) 63*37ce63ebSStefan Hajnoczi completed = True 64*37ce63ebSStefan Hajnoczi 65*37ce63ebSStefan Hajnoczi self.assert_no_active_streams() 66*37ce63ebSStefan Hajnoczi 67*37ce63ebSStefan Hajnoczi self.assertFalse('sectors not allocated' in qemu_io('-c', 'map', test_img), 68*37ce63ebSStefan Hajnoczi 'image file not fully populated after streaming') 69*37ce63ebSStefan Hajnoczi 70*37ce63ebSStefan Hajnoczi def test_device_not_found(self): 71*37ce63ebSStefan Hajnoczi result = self.vm.qmp('block_stream', device='nonexistent') 72*37ce63ebSStefan Hajnoczi self.assert_qmp(result, 'error/class', 'DeviceNotFound') 73*37ce63ebSStefan Hajnoczi 74*37ce63ebSStefan Hajnocziclass TestStreamStop(ImageStreamingTestCase): 75*37ce63ebSStefan Hajnoczi image_len = 8 * 1024 * 1024 * 1024 # GB 76*37ce63ebSStefan Hajnoczi 77*37ce63ebSStefan Hajnoczi def setUp(self): 78*37ce63ebSStefan Hajnoczi qemu_img('create', backing_img, str(TestStreamStop.image_len)) 79*37ce63ebSStefan Hajnoczi qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) 80*37ce63ebSStefan Hajnoczi self.vm = iotests.VM().add_drive(test_img) 81*37ce63ebSStefan Hajnoczi self.vm.launch() 82*37ce63ebSStefan Hajnoczi 83*37ce63ebSStefan Hajnoczi def tearDown(self): 84*37ce63ebSStefan Hajnoczi self.vm.shutdown() 85*37ce63ebSStefan Hajnoczi os.remove(test_img) 86*37ce63ebSStefan Hajnoczi os.remove(backing_img) 87*37ce63ebSStefan Hajnoczi 88*37ce63ebSStefan Hajnoczi def test_stream_stop(self): 89*37ce63ebSStefan Hajnoczi import time 90*37ce63ebSStefan Hajnoczi 91*37ce63ebSStefan Hajnoczi self.assert_no_active_streams() 92*37ce63ebSStefan Hajnoczi 93*37ce63ebSStefan Hajnoczi result = self.vm.qmp('block_stream', device='drive0') 94*37ce63ebSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 95*37ce63ebSStefan Hajnoczi 96*37ce63ebSStefan Hajnoczi time.sleep(1) 97*37ce63ebSStefan Hajnoczi events = self.vm.get_qmp_events(wait=False) 98*37ce63ebSStefan Hajnoczi self.assertEqual(events, [], 'unexpected QMP event: %s' % events) 99*37ce63ebSStefan Hajnoczi 100*37ce63ebSStefan Hajnoczi self.vm.qmp('block_job_cancel', device='drive0') 101*37ce63ebSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 102*37ce63ebSStefan Hajnoczi 103*37ce63ebSStefan Hajnoczi cancelled = False 104*37ce63ebSStefan Hajnoczi while not cancelled: 105*37ce63ebSStefan Hajnoczi for event in self.vm.get_qmp_events(wait=True): 106*37ce63ebSStefan Hajnoczi if event['event'] == 'BLOCK_JOB_CANCELLED': 107*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'stream') 108*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/device', 'drive0') 109*37ce63ebSStefan Hajnoczi cancelled = True 110*37ce63ebSStefan Hajnoczi 111*37ce63ebSStefan Hajnoczi self.assert_no_active_streams() 112*37ce63ebSStefan Hajnoczi 113*37ce63ebSStefan Hajnoczi# This is a short performance test which is not run by default. 114*37ce63ebSStefan Hajnoczi# Invoke "IMGFMT=qed ./030 TestSetSpeed.perf_test_set_speed" 115*37ce63ebSStefan Hajnocziclass TestSetSpeed(ImageStreamingTestCase): 116*37ce63ebSStefan Hajnoczi image_len = 80 * 1024 * 1024 # MB 117*37ce63ebSStefan Hajnoczi 118*37ce63ebSStefan Hajnoczi def setUp(self): 119*37ce63ebSStefan Hajnoczi qemu_img('create', backing_img, str(TestSetSpeed.image_len)) 120*37ce63ebSStefan Hajnoczi qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) 121*37ce63ebSStefan Hajnoczi self.vm = iotests.VM().add_drive(test_img) 122*37ce63ebSStefan Hajnoczi self.vm.launch() 123*37ce63ebSStefan Hajnoczi 124*37ce63ebSStefan Hajnoczi def tearDown(self): 125*37ce63ebSStefan Hajnoczi self.vm.shutdown() 126*37ce63ebSStefan Hajnoczi os.remove(test_img) 127*37ce63ebSStefan Hajnoczi os.remove(backing_img) 128*37ce63ebSStefan Hajnoczi 129*37ce63ebSStefan Hajnoczi def perf_test_set_speed(self): 130*37ce63ebSStefan Hajnoczi self.assert_no_active_streams() 131*37ce63ebSStefan Hajnoczi 132*37ce63ebSStefan Hajnoczi result = self.vm.qmp('block_stream', device='drive0') 133*37ce63ebSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 134*37ce63ebSStefan Hajnoczi 135*37ce63ebSStefan Hajnoczi result = self.vm.qmp('block_job_set_speed', device='drive0', value=8 * 1024 * 1024) 136*37ce63ebSStefan Hajnoczi self.assert_qmp(result, 'return', {}) 137*37ce63ebSStefan Hajnoczi 138*37ce63ebSStefan Hajnoczi completed = False 139*37ce63ebSStefan Hajnoczi while not completed: 140*37ce63ebSStefan Hajnoczi for event in self.vm.get_qmp_events(wait=True): 141*37ce63ebSStefan Hajnoczi if event['event'] == 'BLOCK_JOB_COMPLETED': 142*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/type', 'stream') 143*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/device', 'drive0') 144*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/offset', self.image_len) 145*37ce63ebSStefan Hajnoczi self.assert_qmp(event, 'data/len', self.image_len) 146*37ce63ebSStefan Hajnoczi completed = True 147*37ce63ebSStefan Hajnoczi 148*37ce63ebSStefan Hajnoczi self.assert_no_active_streams() 149*37ce63ebSStefan Hajnoczi 150*37ce63ebSStefan Hajnocziif __name__ == '__main__': 151*37ce63ebSStefan Hajnoczi iotests.main(supported_fmts=['qcow2', 'qed']) 152