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