1*7223c48cSAlberto Garcia#!/usr/bin/env python 2*7223c48cSAlberto Garcia# 3*7223c48cSAlberto Garcia# Test the rate limit of QMP events 4*7223c48cSAlberto Garcia# 5*7223c48cSAlberto Garcia# Copyright (C) 2016 Igalia, S.L. 6*7223c48cSAlberto Garcia# Author: Alberto Garcia <berto@igalia.com> 7*7223c48cSAlberto Garcia# 8*7223c48cSAlberto Garcia# This program is free software; you can redistribute it and/or modify 9*7223c48cSAlberto Garcia# it under the terms of the GNU General Public License as published by 10*7223c48cSAlberto Garcia# the Free Software Foundation; either version 2 of the License, or 11*7223c48cSAlberto Garcia# (at your option) any later version. 12*7223c48cSAlberto Garcia# 13*7223c48cSAlberto Garcia# This program is distributed in the hope that it will be useful, 14*7223c48cSAlberto Garcia# but WITHOUT ANY WARRANTY; without even the implied warranty of 15*7223c48cSAlberto Garcia# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*7223c48cSAlberto Garcia# GNU General Public License for more details. 17*7223c48cSAlberto Garcia# 18*7223c48cSAlberto Garcia# You should have received a copy of the GNU General Public License 19*7223c48cSAlberto Garcia# along with this program. If not, see <http://www.gnu.org/licenses/>. 20*7223c48cSAlberto Garcia# 21*7223c48cSAlberto Garcia 22*7223c48cSAlberto Garciaimport os 23*7223c48cSAlberto Garciaimport iotests 24*7223c48cSAlberto Garcia 25*7223c48cSAlberto Garciaimgs = (os.path.join(iotests.test_dir, 'quorum0.img'), 26*7223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum1.img'), 27*7223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum2.img')) 28*7223c48cSAlberto Garcia 29*7223c48cSAlberto Garciaimg_conf = (os.path.join(iotests.test_dir, 'quorum0.conf'), 30*7223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum1.conf'), 31*7223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum2.conf')) 32*7223c48cSAlberto Garcia 33*7223c48cSAlberto Garciaevent_rate = 1000000000 34*7223c48cSAlberto Garciasector_size = 512 35*7223c48cSAlberto Garciaoffset = 10 36*7223c48cSAlberto Garcia 37*7223c48cSAlberto Garciaclass TestQuorumEvents(iotests.QMPTestCase): 38*7223c48cSAlberto Garcia 39*7223c48cSAlberto Garcia def create_blkdebug_file(self, blkdebug_file, bad_sector): 40*7223c48cSAlberto Garcia file = open(blkdebug_file, 'w') 41*7223c48cSAlberto Garcia file.write(''' 42*7223c48cSAlberto Garcia[inject-error] 43*7223c48cSAlberto Garciaevent = "read_aio" 44*7223c48cSAlberto Garciaerrno = "5" 45*7223c48cSAlberto Garciasector = "%d" 46*7223c48cSAlberto Garcia''' % bad_sector) 47*7223c48cSAlberto Garcia file.close() 48*7223c48cSAlberto Garcia 49*7223c48cSAlberto Garcia def setUp(self): 50*7223c48cSAlberto Garcia driveopts = ['driver=quorum', 'vote-threshold=2'] 51*7223c48cSAlberto Garcia for i in range(len(imgs)): 52*7223c48cSAlberto Garcia iotests.qemu_img('create', '-f', iotests.imgfmt, imgs[i], '1M') 53*7223c48cSAlberto Garcia self.create_blkdebug_file(img_conf[i], i + offset) 54*7223c48cSAlberto Garcia driveopts.append('children.%d.driver=%s' % (i, iotests.imgfmt)) 55*7223c48cSAlberto Garcia driveopts.append('children.%d.file.driver=blkdebug' % i) 56*7223c48cSAlberto Garcia driveopts.append('children.%d.file.config=%s' % (i, img_conf[i])) 57*7223c48cSAlberto Garcia driveopts.append('children.%d.file.image.filename=%s' % (i, imgs[i])) 58*7223c48cSAlberto Garcia driveopts.append('children.%d.node-name=img%d' % (i, i)) 59*7223c48cSAlberto Garcia self.vm = iotests.VM() 60*7223c48cSAlberto Garcia self.vm.add_drive(None, opts = ','.join(driveopts)) 61*7223c48cSAlberto Garcia self.vm.launch() 62*7223c48cSAlberto Garcia 63*7223c48cSAlberto Garcia def tearDown(self): 64*7223c48cSAlberto Garcia self.vm.shutdown() 65*7223c48cSAlberto Garcia for i in range(len(imgs)): 66*7223c48cSAlberto Garcia os.remove(imgs[i]) 67*7223c48cSAlberto Garcia os.remove(img_conf[i]) 68*7223c48cSAlberto Garcia 69*7223c48cSAlberto Garcia def do_check_event(self, node, sector = 0): 70*7223c48cSAlberto Garcia if node == None: 71*7223c48cSAlberto Garcia self.assertEqual(self.vm.get_qmp_event(), None) 72*7223c48cSAlberto Garcia return 73*7223c48cSAlberto Garcia 74*7223c48cSAlberto Garcia for event in self.vm.get_qmp_events(wait=True): 75*7223c48cSAlberto Garcia if event['event'] == 'QUORUM_REPORT_BAD': 76*7223c48cSAlberto Garcia self.assert_qmp(event, 'data/node-name', node) 77*7223c48cSAlberto Garcia self.assert_qmp(event, 'data/sector-num', sector) 78*7223c48cSAlberto Garcia 79*7223c48cSAlberto Garcia def testQuorum(self): 80*7223c48cSAlberto Garcia if not 'quorum' in iotests.qemu_img_pipe('--help'): 81*7223c48cSAlberto Garcia return 82*7223c48cSAlberto Garcia 83*7223c48cSAlberto Garcia # Generate an error and get an event 84*7223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 85*7223c48cSAlberto Garcia (offset * sector_size, sector_size)) 86*7223c48cSAlberto Garcia self.vm.qtest("clock_step 10") 87*7223c48cSAlberto Garcia self.do_check_event('img0', offset) 88*7223c48cSAlberto Garcia 89*7223c48cSAlberto Garcia # I/O errors in the same child: only one event is emitted 90*7223c48cSAlberto Garcia delay = 10 91*7223c48cSAlberto Garcia for i in range(3): 92*7223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 93*7223c48cSAlberto Garcia (offset * sector_size, sector_size)) 94*7223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 95*7223c48cSAlberto Garcia self.do_check_event(None) 96*7223c48cSAlberto Garcia 97*7223c48cSAlberto Garcia # Wait enough so the event is finally emitted 98*7223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % (2 * event_rate)) 99*7223c48cSAlberto Garcia self.do_check_event('img0', offset) 100*7223c48cSAlberto Garcia 101*7223c48cSAlberto Garcia # I/O errors in the same child: all events are emitted 102*7223c48cSAlberto Garcia delay = 2 * event_rate 103*7223c48cSAlberto Garcia for i in range(3): 104*7223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 105*7223c48cSAlberto Garcia (offset * sector_size, sector_size)) 106*7223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 107*7223c48cSAlberto Garcia self.do_check_event('img0', offset) 108*7223c48cSAlberto Garcia 109*7223c48cSAlberto Garcia # I/O errors in different children: all events are emitted 110*7223c48cSAlberto Garcia delay = 10 111*7223c48cSAlberto Garcia for i in range(len(imgs)): 112*7223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 113*7223c48cSAlberto Garcia ((offset + i) * sector_size, sector_size)) 114*7223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 115*7223c48cSAlberto Garcia self.do_check_event('img%d' % i, offset + i) 116*7223c48cSAlberto Garcia 117*7223c48cSAlberto Garcia # I/O errors in different children: all events are emitted 118*7223c48cSAlberto Garcia delay = 2 * event_rate 119*7223c48cSAlberto Garcia for i in range(len(imgs)): 120*7223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 121*7223c48cSAlberto Garcia ((offset + i) * sector_size, sector_size)) 122*7223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 123*7223c48cSAlberto Garcia self.do_check_event('img%d' % i, offset + i) 124*7223c48cSAlberto Garcia 125*7223c48cSAlberto Garcia # No more pending events 126*7223c48cSAlberto Garcia self.do_check_event(None) 127*7223c48cSAlberto Garcia 128*7223c48cSAlberto Garciaif __name__ == '__main__': 129*7223c48cSAlberto Garcia iotests.main(supported_fmts=["raw"]) 130