#!/usr/bin/env python
#
# Tests for IO throttling
#
# Copyright (C) 2015 Red Hat, Inc.
# Copyright (C) 2015-2016 Igalia, S.L.
#
# 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 iotests

nsec_per_sec = 1000000000

class ThrottleTestCase(iotests.QMPTestCase):
    test_img = "null-aio://"
    max_drives = 3

    def blockstats(self, device):
        result = self.vm.qmp("query-blockstats")
        for r in result['return']:
            if r['device'] == device:
                stat = r['stats']
                return stat['rd_bytes'], stat['rd_operations'], stat['wr_bytes'], stat['wr_operations']
        raise Exception("Device not found for blockstats: %s" % device)

    def setUp(self):
        self.vm = iotests.VM()
        for i in range(0, self.max_drives):
            self.vm.add_drive(self.test_img)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()

    def configure_throttle(self, ndrives, params):
        params['group'] = 'test'

        # Set the I/O throttling parameters to all drives
        for i in range(0, ndrives):
            params['device'] = 'drive%d' % i
            result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params)
            self.assert_qmp(result, 'return', {})

    def do_test_throttle(self, ndrives, seconds, params):
        def check_limit(limit, num):
            # IO throttling algorithm is discrete, allow 10% error so the test
            # is more robust
            return limit == 0 or \
                   (num < seconds * limit * 1.1 / ndrives
                   and num > seconds * limit * 0.9 / ndrives)

        # Set vm clock to a known value
        ns = seconds * nsec_per_sec
        self.vm.qtest("clock_step %d" % ns)

        # Submit enough requests so the throttling mechanism kicks
        # in. The throttled requests won't be executed until we
        # advance the virtual clock.
        rq_size = 512
        rd_nr = max(params['bps'] / rq_size / 2,
                    params['bps_rd'] / rq_size,
                    params['iops'] / 2,
                    params['iops_rd'])
        rd_nr *= seconds * 2
        rd_nr /= ndrives
        wr_nr = max(params['bps'] / rq_size / 2,
                    params['bps_wr'] / rq_size,
                    params['iops'] / 2,
                    params['iops_wr'])
        wr_nr *= seconds * 2
        wr_nr /= ndrives

        # Send I/O requests to all drives
        for i in range(rd_nr):
            for drive in range(0, ndrives):
                self.vm.hmp_qemu_io("drive%d" % drive, "aio_read %d %d" %
                                    (i * rq_size, rq_size))

        for i in range(wr_nr):
            for drive in range(0, ndrives):
                self.vm.hmp_qemu_io("drive%d" % drive, "aio_write %d %d" %
                                    (i * rq_size, rq_size))

        # We'll store the I/O stats for each drive in these arrays
        start_rd_bytes = [0] * ndrives
        start_rd_iops  = [0] * ndrives
        start_wr_bytes = [0] * ndrives
        start_wr_iops  = [0] * ndrives
        end_rd_bytes   = [0] * ndrives
        end_rd_iops    = [0] * ndrives
        end_wr_bytes   = [0] * ndrives
        end_wr_iops    = [0] * ndrives

        # Read the stats before advancing the clock
        for i in range(0, ndrives):
            start_rd_bytes[i], start_rd_iops[i], start_wr_bytes[i], \
                start_wr_iops[i] = self.blockstats('drive%d' % i)

        self.vm.qtest("clock_step %d" % ns)

        # Read the stats after advancing the clock
        for i in range(0, ndrives):
            end_rd_bytes[i], end_rd_iops[i], end_wr_bytes[i], \
                end_wr_iops[i] = self.blockstats('drive%d' % i)

        # Check that the I/O is within the limits and evenly distributed
        for i in range(0, ndrives):
            rd_bytes = end_rd_bytes[i] - start_rd_bytes[i]
            rd_iops = end_rd_iops[i] - start_rd_iops[i]
            wr_bytes = end_wr_bytes[i] - start_wr_bytes[i]
            wr_iops = end_wr_iops[i] - start_wr_iops[i]

            self.assertTrue(check_limit(params['bps'], rd_bytes + wr_bytes))
            self.assertTrue(check_limit(params['bps_rd'], rd_bytes))
            self.assertTrue(check_limit(params['bps_wr'], wr_bytes))
            self.assertTrue(check_limit(params['iops'], rd_iops + wr_iops))
            self.assertTrue(check_limit(params['iops_rd'], rd_iops))
            self.assertTrue(check_limit(params['iops_wr'], wr_iops))

    def test_all(self):
        params = {"bps": 4096,
                  "bps_rd": 4096,
                  "bps_wr": 4096,
                  "iops": 10,
                  "iops_rd": 10,
                  "iops_wr": 10,
                 }
        # Repeat the test with different numbers of drives
        for ndrives in range(1, self.max_drives + 1):
            # Pick each out of all possible params and test
            for tk in params:
                limits = dict([(k, 0) for k in params])
                limits[tk] = params[tk] * ndrives
                self.configure_throttle(ndrives, limits)
                self.do_test_throttle(ndrives, 5, limits)

    def test_burst(self):
        params = {"bps": 4096,
                  "bps_rd": 4096,
                  "bps_wr": 4096,
                  "iops": 10,
                  "iops_rd": 10,
                  "iops_wr": 10,
                 }
        ndrives = 1
        # Pick each out of all possible params and test
        for tk in params:
            rate = params[tk] * ndrives
            burst_rate = rate * 7
            burst_length = 4

            # Configure the throttling settings
            settings = dict([(k, 0) for k in params])
            settings[tk] = rate
            settings['%s_max' % tk] = burst_rate
            settings['%s_max_length' % tk] = burst_length
            self.configure_throttle(ndrives, settings)

            # Wait for the bucket to empty so we can do bursts
            wait_ns = nsec_per_sec * burst_length * burst_rate / rate
            self.vm.qtest("clock_step %d" % wait_ns)

            # Test I/O at the max burst rate
            limits = dict([(k, 0) for k in params])
            limits[tk] = burst_rate
            self.do_test_throttle(ndrives, burst_length, limits)

            # Now test I/O at the normal rate
            limits[tk] = rate
            self.do_test_throttle(ndrives, 5, limits)

class ThrottleTestCoroutine(ThrottleTestCase):
    test_img = "null-co://"

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