#!/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):
        if not 'quorum' in iotests.qemu_img_pipe('--help'):
            return

        # 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.main(supported_fmts=["raw"])
