You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.4 KiB
124 lines
4.4 KiB
# 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
|