1903cb1bfSPhilippe Mathieu-Daudé#!/usr/bin/env python3 27223c48cSAlberto Garcia# 37223c48cSAlberto Garcia# Test the rate limit of QMP events 47223c48cSAlberto Garcia# 57223c48cSAlberto Garcia# Copyright (C) 2016 Igalia, S.L. 67223c48cSAlberto Garcia# Author: Alberto Garcia <berto@igalia.com> 77223c48cSAlberto Garcia# 87223c48cSAlberto Garcia# This program is free software; you can redistribute it and/or modify 97223c48cSAlberto Garcia# it under the terms of the GNU General Public License as published by 107223c48cSAlberto Garcia# the Free Software Foundation; either version 2 of the License, or 117223c48cSAlberto Garcia# (at your option) any later version. 127223c48cSAlberto Garcia# 137223c48cSAlberto Garcia# This program is distributed in the hope that it will be useful, 147223c48cSAlberto Garcia# but WITHOUT ANY WARRANTY; without even the implied warranty of 157223c48cSAlberto Garcia# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 167223c48cSAlberto Garcia# GNU General Public License for more details. 177223c48cSAlberto Garcia# 187223c48cSAlberto Garcia# You should have received a copy of the GNU General Public License 197223c48cSAlberto Garcia# along with this program. If not, see <http://www.gnu.org/licenses/>. 207223c48cSAlberto Garcia# 217223c48cSAlberto Garcia 227223c48cSAlberto Garciaimport os 237223c48cSAlberto Garciaimport iotests 247223c48cSAlberto Garcia 257223c48cSAlberto Garciaimgs = (os.path.join(iotests.test_dir, 'quorum0.img'), 267223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum1.img'), 277223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum2.img')) 287223c48cSAlberto Garcia 297223c48cSAlberto Garciaimg_conf = (os.path.join(iotests.test_dir, 'quorum0.conf'), 307223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum1.conf'), 317223c48cSAlberto Garcia os.path.join(iotests.test_dir, 'quorum2.conf')) 327223c48cSAlberto Garcia 337223c48cSAlberto Garciaevent_rate = 1000000000 347223c48cSAlberto Garciasector_size = 512 357223c48cSAlberto Garciaoffset = 10 367223c48cSAlberto Garcia 377223c48cSAlberto Garciaclass TestQuorumEvents(iotests.QMPTestCase): 38509565f3SAlberto Garcia read_pattern = 'quorum' 397223c48cSAlberto Garcia 407223c48cSAlberto Garcia def create_blkdebug_file(self, blkdebug_file, bad_sector): 417223c48cSAlberto Garcia file = open(blkdebug_file, 'w') 427223c48cSAlberto Garcia file.write(''' 437223c48cSAlberto Garcia[inject-error] 447223c48cSAlberto Garciaevent = "read_aio" 457223c48cSAlberto Garciaerrno = "5" 467223c48cSAlberto Garciasector = "%d" 477223c48cSAlberto Garcia''' % bad_sector) 487223c48cSAlberto Garcia file.close() 497223c48cSAlberto Garcia 50*50bb041aSVladimir Sementsov-Ogievskiy @iotests.skip_if_unsupported(['quorum']) 517223c48cSAlberto Garcia def setUp(self): 527223c48cSAlberto Garcia driveopts = ['driver=quorum', 'vote-threshold=2'] 53509565f3SAlberto Garcia driveopts.append('read-pattern=%s' % self.read_pattern) 547223c48cSAlberto Garcia for i in range(len(imgs)): 557223c48cSAlberto Garcia iotests.qemu_img('create', '-f', iotests.imgfmt, imgs[i], '1M') 567223c48cSAlberto Garcia self.create_blkdebug_file(img_conf[i], i + offset) 577223c48cSAlberto Garcia driveopts.append('children.%d.driver=%s' % (i, iotests.imgfmt)) 587223c48cSAlberto Garcia driveopts.append('children.%d.file.driver=blkdebug' % i) 597223c48cSAlberto Garcia driveopts.append('children.%d.file.config=%s' % (i, img_conf[i])) 607223c48cSAlberto Garcia driveopts.append('children.%d.file.image.filename=%s' % (i, imgs[i])) 617223c48cSAlberto Garcia driveopts.append('children.%d.node-name=img%d' % (i, i)) 627223c48cSAlberto Garcia self.vm = iotests.VM() 637223c48cSAlberto Garcia self.vm.add_drive(None, opts = ','.join(driveopts)) 647223c48cSAlberto Garcia self.vm.launch() 657223c48cSAlberto Garcia 667223c48cSAlberto Garcia def tearDown(self): 677223c48cSAlberto Garcia self.vm.shutdown() 687223c48cSAlberto Garcia for i in range(len(imgs)): 697223c48cSAlberto Garcia os.remove(imgs[i]) 707223c48cSAlberto Garcia os.remove(img_conf[i]) 717223c48cSAlberto Garcia 727223c48cSAlberto Garcia def do_check_event(self, node, sector = 0): 737223c48cSAlberto Garcia if node == None: 747223c48cSAlberto Garcia self.assertEqual(self.vm.get_qmp_event(), None) 757223c48cSAlberto Garcia return 767223c48cSAlberto Garcia 777223c48cSAlberto Garcia for event in self.vm.get_qmp_events(wait=True): 787223c48cSAlberto Garcia if event['event'] == 'QUORUM_REPORT_BAD': 797223c48cSAlberto Garcia self.assert_qmp(event, 'data/node-name', node) 807223c48cSAlberto Garcia self.assert_qmp(event, 'data/sector-num', sector) 817223c48cSAlberto Garcia 827223c48cSAlberto Garcia def testQuorum(self): 837223c48cSAlberto Garcia # Generate an error and get an event 847223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 857223c48cSAlberto Garcia (offset * sector_size, sector_size)) 867223c48cSAlberto Garcia self.vm.qtest("clock_step 10") 877223c48cSAlberto Garcia self.do_check_event('img0', offset) 887223c48cSAlberto Garcia 897223c48cSAlberto Garcia # I/O errors in the same child: only one event is emitted 907223c48cSAlberto Garcia delay = 10 917223c48cSAlberto Garcia for i in range(3): 927223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 937223c48cSAlberto Garcia (offset * sector_size, sector_size)) 947223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 957223c48cSAlberto Garcia self.do_check_event(None) 967223c48cSAlberto Garcia 977223c48cSAlberto Garcia # Wait enough so the event is finally emitted 987223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % (2 * event_rate)) 997223c48cSAlberto Garcia self.do_check_event('img0', offset) 1007223c48cSAlberto Garcia 1017223c48cSAlberto Garcia # I/O errors in the same child: all events are emitted 1027223c48cSAlberto Garcia delay = 2 * event_rate 1037223c48cSAlberto Garcia for i in range(3): 1047223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 1057223c48cSAlberto Garcia (offset * sector_size, sector_size)) 1067223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 1077223c48cSAlberto Garcia self.do_check_event('img0', offset) 1087223c48cSAlberto Garcia 1097223c48cSAlberto Garcia # I/O errors in different children: all events are emitted 1107223c48cSAlberto Garcia delay = 10 1117223c48cSAlberto Garcia for i in range(len(imgs)): 1127223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 1137223c48cSAlberto Garcia ((offset + i) * sector_size, sector_size)) 1147223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 115509565f3SAlberto Garcia # In fifo mode only errors in the first child are detected 116509565f3SAlberto Garcia if i > 0 and self.read_pattern == 'fifo': 117509565f3SAlberto Garcia self.do_check_event(None) 118509565f3SAlberto Garcia else: 1197223c48cSAlberto Garcia self.do_check_event('img%d' % i, offset + i) 1207223c48cSAlberto Garcia 1217223c48cSAlberto Garcia # I/O errors in different children: all events are emitted 1227223c48cSAlberto Garcia delay = 2 * event_rate 1237223c48cSAlberto Garcia for i in range(len(imgs)): 1247223c48cSAlberto Garcia self.vm.hmp_qemu_io("drive0", "aio_read %d %d" % 1257223c48cSAlberto Garcia ((offset + i) * sector_size, sector_size)) 1267223c48cSAlberto Garcia self.vm.qtest("clock_step %d" % delay) 127509565f3SAlberto Garcia # In fifo mode only errors in the first child are detected 128509565f3SAlberto Garcia if i > 0 and self.read_pattern == 'fifo': 129509565f3SAlberto Garcia self.do_check_event(None) 130509565f3SAlberto Garcia else: 1317223c48cSAlberto Garcia self.do_check_event('img%d' % i, offset + i) 1327223c48cSAlberto Garcia 1337223c48cSAlberto Garcia # No more pending events 1347223c48cSAlberto Garcia self.do_check_event(None) 1357223c48cSAlberto Garcia 136509565f3SAlberto Garciaclass TestFifoQuorumEvents(TestQuorumEvents): 137509565f3SAlberto Garcia read_pattern = 'fifo' 138509565f3SAlberto Garcia 1397223c48cSAlberto Garciaif __name__ == '__main__': 1403f647b51SSascha Silbe iotests.verify_quorum() 141103cbc77SMax Reitz iotests.main(supported_fmts=["raw"], 142103cbc77SMax Reitz supported_protocols=["file"]) 143