#!/usr/bin/env python
#
# Test the rate limit of QMP events
#
# Copyright (C) 2016 Igalia, S.L.
# Author: Alberto Garcia <berto@igalia.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import os
import iotests

imgs = (os.path.join(iotests.test_dir, 'quorum0.img'),
        os.path.join(iotests.test_dir, 'quorum1.img'),
        os.path.join(iotests.test_dir, 'quorum2.img'))

img_conf = (os.path.join(iotests.test_dir, 'quorum0.conf'),
            os.path.join(iotests.test_dir, 'quorum1.conf'),
            os.path.join(iotests.test_dir, 'quorum2.conf'))

event_rate = 1000000000
sector_size = 512
offset = 10

class TestQuorumEvents(iotests.QMPTestCase):
    read_pattern = 'quorum'

    def create_blkdebug_file(self, blkdebug_file, bad_sector):
        file = open(blkdebug_file, 'w')
        file.write('''
[inject-error]
event = "read_aio"
errno = "5"
sector = "%d"
''' % bad_sector)
        file.close()

    def setUp(self):
        driveopts = ['driver=quorum', 'vote-threshold=2']
        driveopts.append('read-pattern=%s' % self.read_pattern)
        for i in range(len(imgs)):
            iotests.qemu_img('create', '-f', iotests.imgfmt, imgs[i], '1M')
            self.create_blkdebug_file(img_conf[i], i + offset)
            driveopts.append('children.%d.driver=%s' % (i, iotests.imgfmt))
            driveopts.append('children.%d.file.driver=blkdebug' % i)
            driveopts.append('children.%d.file.config=%s' % (i, img_conf[i]))
            driveopts.append('children.%d.file.image.filename=%s' % (i, imgs[i]))
            driveopts.append('children.%d.node-name=img%d' % (i, i))
        self.vm = iotests.VM()
        self.vm.add_drive(None, opts = ','.join(driveopts))
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        for i in range(len(imgs)):
            os.remove(imgs[i])
            os.remove(img_conf[i])

    def do_check_event(self, node, sector = 0):
        if node == None:
            self.assertEqual(self.vm.get_qmp_event(), None)
            return

        for event in self.vm.get_qmp_events(wait=True):
            if event['event'] == 'QUORUM_REPORT_BAD':
                self.assert_qmp(event, 'data/node-name', node)
                self.assert_qmp(event, 'data/sector-num', sector)

    def testQuorum(self):
        # Generate an error and get an event
        self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
                            (offset * sector_size, sector_size))
        self.vm.qtest("clock_step 10")
        self.do_check_event('img0', offset)

        # I/O errors in the same child: only one event is emitted
        delay = 10
        for i in range(3):
            self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
                                (offset * sector_size, sector_size))
            self.vm.qtest("clock_step %d" % delay)
            self.do_check_event(None)

        # Wait enough so the event is finally emitted
        self.vm.qtest("clock_step %d" % (2 * event_rate))
        self.do_check_event('img0', offset)

        # I/O errors in the same child: all events are emitted
        delay = 2 * event_rate
        for i in range(3):
            self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
                                (offset * sector_size, sector_size))
            self.vm.qtest("clock_step %d" % delay)
            self.do_check_event('img0', offset)

        # I/O errors in different children: all events are emitted
        delay = 10
        for i in range(len(imgs)):
            self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
                                ((offset + i) * sector_size, sector_size))
            self.vm.qtest("clock_step %d" % delay)
            # In fifo mode only errors in the first child are detected
            if i > 0 and self.read_pattern == 'fifo':
                self.do_check_event(None)
            else:
                self.do_check_event('img%d' % i, offset + i)

        # I/O errors in different children: all events are emitted
        delay = 2 * event_rate
        for i in range(len(imgs)):
            self.vm.hmp_qemu_io("drive0", "aio_read %d %d" %
                                ((offset + i) * sector_size, sector_size))
            self.vm.qtest("clock_step %d" % delay)
            # In fifo mode only errors in the first child are detected
            if i > 0 and self.read_pattern == 'fifo':
                self.do_check_event(None)
            else:
                self.do_check_event('img%d' % i, offset + i)

        # No more pending events
        self.do_check_event(None)

class TestFifoQuorumEvents(TestQuorumEvents):
    read_pattern = 'fifo'

if __name__ == '__main__':
    iotests.verify_quorum()
    iotests.main(supported_fmts=["raw"])
