# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Author: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk>

import datetime
import logging
import os

from autotest_lib.client.cros import storage as storage_mod
from autotest_lib.client.common_lib import autotemp, error
from autotest_lib.client.bin import utils

USECS_IN_SEC = 1000000.0

class hardware_Usb30Throughput(storage_mod.StorageTester):
    version = 1
    preserve_srcdir = True
    _autosrc = None
    _autodst = None
    results = {}


    def cleanup(self):
        if self._autosrc:
            self._autosrc.clean()
        if self._autodst:
            self._autodst.clean()

        self.scanner.unmount_all()

        super(hardware_Usb30Throughput, self).cleanup()


    def run_once(self, measurements=5, size=1, min_speed=300.0):
        """
        @param measurements: (int) the number of measurements to do.
                For the test to fail at least one measurement needs to be
                below |min_speed|
        @param size: (int) size of the file to be copied for testing the
                transfer rate, it represent the size in megabytes.
                Generally speaking, the bigger is the file used for
                |measurements| the slower the test will run and the more
                accurate it will be.
                e.g.: 10 is 10MB, 101 is 101MB
        @param min_speed: (float) in Mbit/sec. It's the min throughput a USB 3.0
                device should perform to be accepted. Conceptually it's the max
                USB 3.0 throughput minus a tollerance.
                Defaults to 300Mbit/sec (ie 350Mbits/sec minus ~15% tollerance)
        """
        volume_filter = {'bus': 'usb'}
        storage = self.wait_for_device(volume_filter, cycles=1,
                                       mount_volume=True)[0]

        # in Megabytes (power of 10, to be consistent with the throughput unit)
        size *= 1000*1000

        self._autosrc = autotemp.tempfile(unique_id='autotest.src',
                                          dir=storage['mountpoint'])
        self._autodst = autotemp.tempfile(unique_id='autotest.dst',
                                          dir=self.tmpdir)

        # Create random file
        storage_mod.create_file(self._autosrc.name, size)

        num_failures = 0
        for measurement in range(measurements):
            xfer_rate = get_xfer_rate(self._autosrc.name, self._autodst.name)
            key = 'Mbit_per_sec_measurement_%d' % measurement
            self.results[key] = xfer_rate
            logging.debug('xfer rate (measurement %d) %.2f (min=%.2f)',
                          measurement, xfer_rate, min_speed)

            if xfer_rate < min_speed:
                num_failures += 1

        # Apparently self.postprocess_iteration is not called on TestFail
        # so we need to process data here in order to have some performance log
        # even on TestFail
        self.results['Mbit_per_sec_average'] = (sum(self.results.values()) /
            len(self.results))
        self.write_perf_keyval(self.results)

        if num_failures > 0:
            msg = ('%d/%d measured transfer rates under performed '
                   '(min_speed=%.2fMbit/sec)' % (num_failures, measurements,
                   min_speed))
            raise error.TestFail(msg)


def get_xfer_rate(src, dst):
    """Compute transfer rate from src to dst as Mbit/sec

    Execute a copy from |src| to |dst| and returns the file copy transfer rate
    in Mbit/sec

    @param src, dst: paths for source and destination

    @return trasfer rate (float) in Mbit/sec
    """
    assert os.path.isfile(src)
    assert os.path.isfile(dst)

    utils.drop_caches()
    start = datetime.datetime.now()
    utils.force_copy(src, dst)
    end = datetime.datetime.now()
    delta = end - start

    # compute seconds (as float) from microsecs
    delta_secs = delta.seconds + (delta.microseconds/USECS_IN_SEC)
    # compute Mbit from bytes
    size_Mbit = (os.path.getsize(src)*8.0)/(1000*1000)

    logging.info('file trasferred: size (Mbits): %f, start: %f, end: %d,'
                 ' delta (secs): %f',
                 size_Mbit,
                 start.second+start.microsecond/USECS_IN_SEC,
                 end.second+end.microsecond/USECS_IN_SEC,
                 delta_secs)

    # return the xfer rate in Mbits/secs having bytes/microsec
    return size_Mbit / delta_secs
