• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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