#!/usr/bin/env python3
#
# Tests for block device statistics
#
# Copyright (C) 2015 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 iotests
import os

interval_length = 10
nsec_per_sec = 1000000000
op_latency = nsec_per_sec // 1000 # See qtest_latency_ns in accounting.c
bad_sector = 8192
bad_offset = bad_sector * 512
blkdebug_file = os.path.join(iotests.test_dir, 'blkdebug.conf')

class BlockDeviceStatsTestCase(iotests.QMPTestCase):
    test_driver = "null-aio"
    total_rd_bytes = 0
    total_rd_ops = 0
    total_wr_bytes = 0
    total_wr_ops = 0
    total_wr_merged = 0
    total_flush_ops = 0
    failed_rd_ops = 0
    failed_wr_ops = 0
    invalid_rd_ops = 0
    invalid_wr_ops = 0
    wr_highest_offset = 0
    account_invalid = False
    account_failed = False

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

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

[inject-error]
event = "write_aio"
errno = "5"
sector = "%d"
''' % (bad_sector, bad_sector))
        file.close()

    def required_drivers(self):
        return [self.test_driver]

    @iotests.skip_if_unsupported(required_drivers)
    def setUp(self):
        drive_args = []
        drive_args.append("stats-intervals.0=%d" % interval_length)
        drive_args.append("stats-account-invalid=%s" %
                          (self.account_invalid and "on" or "off"))
        drive_args.append("stats-account-failed=%s" %
                          (self.account_failed and "on" or "off"))
        drive_args.append("file.image.read-zeroes=on")
        self.create_blkdebug_file()
        self.vm = iotests.VM().add_drive('blkdebug:%s:%s://' %
                                         (blkdebug_file, self.test_driver),
                                         ','.join(drive_args))
        self.vm.launch()
        # Set an initial value for the clock
        self.vm.qtest("clock_step %d" % nsec_per_sec)

    def tearDown(self):
        self.vm.shutdown()
        os.remove(blkdebug_file)

    def accounted_ops(self, read = False, write = False, flush = False):
        ops = 0
        if write:
            ops += self.total_wr_ops
            if self.account_failed:
                ops += self.failed_wr_ops
            if self.account_invalid:
                ops += self.invalid_wr_ops
        if read:
            ops += self.total_rd_ops
            if self.account_failed:
                ops += self.failed_rd_ops
            if self.account_invalid:
                ops += self.invalid_rd_ops
        if flush:
            ops += self.total_flush_ops
        return ops

    def accounted_latency(self, read = False, write = False, flush = False):
        latency = 0
        if write:
            latency += self.total_wr_ops * op_latency
            if self.account_failed:
                latency += self.failed_wr_ops * op_latency
        if read:
            latency += self.total_rd_ops * op_latency
            if self.account_failed:
                latency += self.failed_rd_ops * op_latency
        if flush:
            latency += self.total_flush_ops * op_latency
        return latency

    def check_values(self):
        stats = self.blockstats('drive0')

        # Check that the totals match with what we have calculated
        self.assertEqual(self.total_rd_bytes, stats['rd_bytes'])
        self.assertEqual(self.total_wr_bytes, stats['wr_bytes'])
        self.assertEqual(self.total_rd_ops, stats['rd_operations'])
        self.assertEqual(self.total_wr_ops, stats['wr_operations'])
        self.assertEqual(self.total_flush_ops, stats['flush_operations'])
        self.assertEqual(self.wr_highest_offset, stats['wr_highest_offset'])
        self.assertEqual(self.failed_rd_ops, stats['failed_rd_operations'])
        self.assertEqual(self.failed_wr_ops, stats['failed_wr_operations'])
        self.assertEqual(self.invalid_rd_ops, stats['invalid_rd_operations'])
        self.assertEqual(self.invalid_wr_ops, stats['invalid_wr_operations'])
        self.assertEqual(self.account_invalid, stats['account_invalid'])
        self.assertEqual(self.account_failed, stats['account_failed'])
        self.assertEqual(self.total_wr_merged, stats['wr_merged'])

        # Check that there's exactly one interval with the length we defined
        self.assertEqual(1, len(stats['timed_stats']))
        timed_stats = stats['timed_stats'][0]
        self.assertEqual(interval_length, timed_stats['interval_length'])

        total_rd_latency = self.accounted_latency(read = True)
        if (total_rd_latency != 0):
            self.assertEqual(total_rd_latency, stats['rd_total_time_ns'])
            self.assertEqual(op_latency, timed_stats['min_rd_latency_ns'])
            self.assertEqual(op_latency, timed_stats['max_rd_latency_ns'])
            self.assertEqual(op_latency, timed_stats['avg_rd_latency_ns'])
            self.assertLess(0, timed_stats['avg_rd_queue_depth'])
        else:
            self.assertEqual(0, stats['rd_total_time_ns'])
            self.assertEqual(0, timed_stats['min_rd_latency_ns'])
            self.assertEqual(0, timed_stats['max_rd_latency_ns'])
            self.assertEqual(0, timed_stats['avg_rd_latency_ns'])
            self.assertEqual(0, timed_stats['avg_rd_queue_depth'])

        # min read latency <= avg read latency <= max read latency
        self.assertLessEqual(timed_stats['min_rd_latency_ns'],
                             timed_stats['avg_rd_latency_ns'])
        self.assertLessEqual(timed_stats['avg_rd_latency_ns'],
                             timed_stats['max_rd_latency_ns'])

        total_wr_latency = self.accounted_latency(write = True)
        if (total_wr_latency != 0):
            self.assertEqual(total_wr_latency, stats['wr_total_time_ns'])
            self.assertEqual(op_latency, timed_stats['min_wr_latency_ns'])
            self.assertEqual(op_latency, timed_stats['max_wr_latency_ns'])
            self.assertEqual(op_latency, timed_stats['avg_wr_latency_ns'])
            self.assertLess(0, timed_stats['avg_wr_queue_depth'])
        else:
            self.assertEqual(0, stats['wr_total_time_ns'])
            self.assertEqual(0, timed_stats['min_wr_latency_ns'])
            self.assertEqual(0, timed_stats['max_wr_latency_ns'])
            self.assertEqual(0, timed_stats['avg_wr_latency_ns'])
            self.assertEqual(0, timed_stats['avg_wr_queue_depth'])

        # min write latency <= avg write latency <= max write latency
        self.assertLessEqual(timed_stats['min_wr_latency_ns'],
                             timed_stats['avg_wr_latency_ns'])
        self.assertLessEqual(timed_stats['avg_wr_latency_ns'],
                             timed_stats['max_wr_latency_ns'])

        total_flush_latency = self.accounted_latency(flush = True)
        if (total_flush_latency != 0):
            self.assertEqual(total_flush_latency, stats['flush_total_time_ns'])
            self.assertEqual(op_latency, timed_stats['min_flush_latency_ns'])
            self.assertEqual(op_latency, timed_stats['max_flush_latency_ns'])
            self.assertEqual(op_latency, timed_stats['avg_flush_latency_ns'])
        else:
            self.assertEqual(0, stats['flush_total_time_ns'])
            self.assertEqual(0, timed_stats['min_flush_latency_ns'])
            self.assertEqual(0, timed_stats['max_flush_latency_ns'])
            self.assertEqual(0, timed_stats['avg_flush_latency_ns'])

        # min flush latency <= avg flush latency <= max flush latency
        self.assertLessEqual(timed_stats['min_flush_latency_ns'],
                             timed_stats['avg_flush_latency_ns'])
        self.assertLessEqual(timed_stats['avg_flush_latency_ns'],
                             timed_stats['max_flush_latency_ns'])

        # idle_time_ns must be > 0 if we have performed any operation
        if (self.accounted_ops(read = True, write = True, flush = True) != 0):
            self.assertLess(0, stats['idle_time_ns'])
        else:
            self.assertFalse('idle_time_ns' in stats)

        # This test does not alter these, so they must be all 0
        self.assertEqual(0, stats['rd_merged'])
        self.assertEqual(0, stats['failed_flush_operations'])
        self.assertEqual(0, stats['invalid_flush_operations'])

    def do_test_stats(self, rd_size = 0, rd_ops = 0, wr_size = 0, wr_ops = 0,
                      flush_ops = 0, invalid_rd_ops = 0, invalid_wr_ops = 0,
                      failed_rd_ops = 0, failed_wr_ops = 0, wr_merged = 0):
        # The 'ops' list will contain all the requested I/O operations
        ops = []
        for i in range(rd_ops):
            ops.append("aio_read %d %d" % (i * rd_size, rd_size))

        for i in range(wr_ops):
            ops.append("aio_write %d %d" % (i * wr_size, wr_size))

        for i in range(flush_ops):
            ops.append("aio_flush")

        highest_offset = wr_ops * wr_size

        for i in range(invalid_rd_ops):
            ops.append("aio_read -i 0 512")

        for i in range(invalid_wr_ops):
            ops.append("aio_write -i 0 512")

        for i in range(failed_rd_ops):
            ops.append("aio_read %d 512" % bad_offset)

        for i in range(failed_wr_ops):
            ops.append("aio_write %d 512" % bad_offset)

        # We need an extra aio_flush to settle all outstanding AIO
        # operations before we can advance the virtual clock, so that
        # the last access happens before clock_step and idle_time_ns
        # will be greater than 0
        extra_flush = 0
        if rd_ops + wr_ops + invalid_rd_ops + invalid_wr_ops + \
                failed_rd_ops + failed_wr_ops > 0:
            extra_flush = 1

        if extra_flush > 0:
            ops.append("aio_flush")

        if failed_wr_ops > 0:
            highest_offset = max(highest_offset, bad_offset + 512)

        # Now perform all operations
        for op in ops:
            self.vm.hmp_qemu_io("drive0", op)

        # Update the expected totals
        self.total_rd_bytes += rd_ops * rd_size
        self.total_rd_ops += rd_ops
        self.total_wr_bytes += wr_ops * wr_size
        self.total_wr_ops += wr_ops
        self.total_wr_merged += wr_merged
        self.total_flush_ops += flush_ops + extra_flush
        self.invalid_rd_ops += invalid_rd_ops
        self.invalid_wr_ops += invalid_wr_ops
        self.failed_rd_ops += failed_rd_ops
        self.failed_wr_ops += failed_wr_ops

        self.wr_highest_offset = max(self.wr_highest_offset, highest_offset)

        # Advance the clock so idle_time_ns has a meaningful value
        self.vm.qtest("clock_step %d" % nsec_per_sec)

        # And check that the actual statistics match the expected ones
        self.check_values()

    def test_read_only(self):
        test_values = [[512,    1],
                       [65536,  1],
                       [512,   12],
                       [65536, 12]]
        for i in test_values:
            self.do_test_stats(rd_size = i[0], rd_ops = i[1])

    def test_write_only(self):
        test_values = [[512,    1],
                       [65536,  1],
                       [512,   12],
                       [65536, 12]]
        for i in test_values:
            self.do_test_stats(wr_size = i[0], wr_ops = i[1])

    def test_invalid(self):
        self.do_test_stats(invalid_rd_ops = 7)
        self.do_test_stats(invalid_wr_ops = 3)
        self.do_test_stats(invalid_rd_ops = 4, invalid_wr_ops = 5)

    def test_failed(self):
        self.do_test_stats(failed_rd_ops = 8)
        self.do_test_stats(failed_wr_ops = 6)
        self.do_test_stats(failed_rd_ops = 5, failed_wr_ops = 12)

    def test_flush(self):
        self.do_test_stats(flush_ops = 8)

    def test_all(self):
        # rd_size, rd_ops, wr_size, wr_ops, flush_ops
        # invalid_rd_ops,  invalid_wr_ops,
        # failed_rd_ops,   failed_wr_ops
        # wr_merged
        test_values = [[512,    1, 512,   1, 1, 4, 7, 5, 2, 0],
                       [65536,  1, 2048, 12, 7, 7, 5, 2, 5, 0],
                       [32768,  9, 8192,  1, 4, 3, 2, 4, 6, 0],
                       [16384, 11, 3584, 16, 9, 8, 6, 7, 3, 0]]
        for i in test_values:
            self.do_test_stats(*i)

    def test_no_op(self):
        # All values must be sane before doing any I/O
        self.check_values()


class BlockDeviceStatsTestAccountInvalid(BlockDeviceStatsTestCase):
    account_invalid = True
    account_failed = False

class BlockDeviceStatsTestAccountFailed(BlockDeviceStatsTestCase):
    account_invalid = False
    account_failed = True

class BlockDeviceStatsTestAccountBoth(BlockDeviceStatsTestCase):
    account_invalid = True
    account_failed = True

class BlockDeviceStatsTestCoroutine(BlockDeviceStatsTestCase):
    test_driver = "null-co"

if __name__ == '__main__':
    if 'null-co' not in iotests.supported_formats():
        iotests.notrun('null-co driver support missing')
    iotests.main(supported_fmts=["raw"])
