1# Lint as: python2, python3 2# Copyright (c) 2021 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7 8from autotest_lib.server.cros.network import iperf_runner 9 10 11class IperfSession(object): 12 """Runs iperf tests and reports average results.""" 13 14 MEASUREMENT_MAX_SAMPLES = 10 15 MEASUREMENT_MAX_FAILURES = 2 16 MEASUREMENT_MIN_SAMPLES = 3 17 MAX_THROUGHPUT_CV = 0.03 18 19 def __init__(self, 20 client_proxy, 21 server_proxy, 22 client_interface=None, 23 server_interface=None, 24 ignore_failures=False): 25 """Construct an IperfSession. 26 27 @param client_proxy: LinuxSystem object. 28 @param server_proxy: LinuxSystem object. 29 @param client_interface Interface object. 30 @param server_interface Interface object. 31 32 """ 33 self._client_proxy = client_proxy 34 self._server_proxy = server_proxy 35 self._client_interface = client_interface 36 self._server_interface = server_interface 37 self._ignore_failures = ignore_failures 38 39 def run(self, config): 40 """Run multiple iperf tests and take the average performance values. 41 42 @param config IperfConfig. 43 44 """ 45 46 logging.info('Performing %s measurements in iperf session.', 47 config.test_type) 48 history = [] 49 failure_count = 0 50 final_result = None 51 with iperf_runner.IperfRunner(self._client_proxy, self._server_proxy, 52 config, self._client_interface, 53 self._server_interface) as runner: 54 while len(history) + failure_count < self.MEASUREMENT_MAX_SAMPLES: 55 result = runner.run(ignore_failures=self._ignore_failures) 56 if result is None: 57 failure_count += 1 58 # Might occur when, e.g., signal strength is too low. 59 if failure_count > self.MEASUREMENT_MAX_FAILURES: 60 logging.error('Too many failures (%d), aborting', 61 failure_count) 62 break 63 continue 64 logging.info('Took iperf %s Measurement: %r', config.test_type, 65 result) 66 67 history.append(result) 68 if len(history) < self.MEASUREMENT_MIN_SAMPLES: 69 continue 70 71 final_result = iperf_runner.IperfResult.from_samples(history) 72 if final_result.throughput_cv_less_than_maximum( 73 self.MAX_THROUGHPUT_CV): 74 break 75 76 if final_result is None: 77 final_result = iperf_runner.IperfResult.from_samples(history) 78 logging.info('Took averaged measurement from %s iperf %s runs: %r.', 79 len(history), config.test_type, final_result) 80 return history or None 81