xref: /aosp_15_r20/external/autotest/server/cros/network/perf_test_manager.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Copyright (c) 2021 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5from autotest_lib.client.common_lib import error
6from autotest_lib.server.cros.network import iperf_runner
7from autotest_lib.server.cros.network import iperf_session
8from autotest_lib.server.cros.network import netperf_runner
9from autotest_lib.server.cros.network import netperf_session
10
11
12class PerfTestTypes(object):
13    """These are the different performance test types that are supported by
14    autotest. The are defined from perspective of the Device Under Test, so for
15    example 'tcp_rx' refers to a performance test of data transfer from a remote
16    server to the DUT using the TCP protocol.
17    """
18    TEST_TYPE_TCP_TX = 'tcp_tx'
19    TEST_TYPE_TCP_RX = 'tcp_rx'
20    TEST_TYPE_TCP_BIDIRECTIONAL = 'tcp_bidirectional'
21    TEST_TYPE_UDP_TX = 'udp_tx'
22    TEST_TYPE_UDP_RX = 'udp_rx'
23    TEST_TYPE_UDP_BIDIRECTIONAL = 'udp_bidirectional'
24
25
26class PerfTestManager(object):
27    """Manager for Performance tests. This class provides a unified API to allow
28    callers run performance tests using the supported tools.
29    """
30
31    # TODO(b:195574472): Add support for iperf in this class.
32
33    DEFAULT_TEST_TIME = 10
34
35    def __init__(self, use_iperf):
36        """Construct a PerfTestManager.
37
38        TODO(b:198343041) iperf2 bidirectional tests are unreliable, so we
39        always use netperf for bidirectional tests.
40
41        @param bool use_iperf True if the tests should use iperf, false if the
42        tests should use netperf.
43        """
44        self._use_iperf = use_iperf
45
46    def get_config(self, test_type, test_time=DEFAULT_TEST_TIME):
47        """Get a config object for a performance tests based on the test
48        type and other parameters. Will return either a NetperfConfig or
49        IperfConfig based on the use_iperf value of the class.
50
51        @param test_type string, test type from performance_test_types.
52        @param test_time int number of seconds to run the test for.
53
54        @return NetperfConfig or IperfConfig object.
55        """
56        # (b:198343041): Always use netperf for bidirectional tests.
57        if self._use_iperf and test_type not in [
58                PerfTestTypes.TEST_TYPE_TCP_BIDIRECTIONAL,
59                PerfTestTypes.TEST_TYPE_UDP_BIDIRECTIONAL
60        ]:
61            return iperf_runner.IperfConfig(
62                    self._iperf_type_from_perf_type(test_type))
63        return netperf_runner.NetperfConfig(
64                self._netperf_type_from_perf_type(test_type),
65                test_time=test_time)
66
67    def get_session(self,
68                    test_type,
69                    test_device_proxy,
70                    peer_device_proxy,
71                    test_device_interface=None,
72                    peer_device_interface=None,
73                    ignore_failures=False):
74        """Get a Session object for a set of performance tests. Will return
75        either a NetperfSession or IperfSession based on the use_iperf value of
76        the class.
77
78        @param test_device_proxy: WiFiClient object for the device-under-test.
79        @param peer_device_proxy: LinuxSystem object for the performance testing
80        peer of the DUT.
81        @param test_device_interface Interface object for the test device.
82        @param peer_device_interface Interface object for the peer device.
83
84        @return NetperfSession object.
85        """
86        # (b:198343041) Always use netperf for bidirectional tests.
87        if self._use_iperf and test_type not in [
88                PerfTestTypes.TEST_TYPE_TCP_BIDIRECTIONAL,
89                PerfTestTypes.TEST_TYPE_UDP_BIDIRECTIONAL
90        ]:
91            if test_type in [
92                    PerfTestTypes.TEST_TYPE_TCP_TX,
93                    PerfTestTypes.TEST_TYPE_UDP_TX
94            ]:
95                return iperf_session.IperfSession(
96                        test_device_proxy,
97                        peer_device_proxy,
98                        client_interface=test_device_interface,
99                        server_interface=peer_device_interface,
100                        ignore_failures=ignore_failures)
101            if test_type in [
102                    PerfTestTypes.TEST_TYPE_TCP_RX,
103                    PerfTestTypes.TEST_TYPE_UDP_RX
104            ]:
105                return iperf_session.IperfSession(
106                        peer_device_proxy,
107                        test_device_proxy,
108                        client_interface=peer_device_interface,
109                        server_interface=test_device_interface,
110                        ignore_failures=ignore_failures)
111
112            raise error.TestFail(
113                    'Test type %s is not supported by this test.' % test_type)
114
115        return netperf_session.NetperfSession(
116                test_device_proxy,
117                peer_device_proxy,
118                client_interface=test_device_interface,
119                server_interface=peer_device_interface,
120                ignore_failures=ignore_failures)
121
122    def get_result(self, results):
123        """Get a single performance result from a list of results.
124
125        @param results list of IperfResults or NetperfResults.
126
127        @return a single IperfResult or NetperfResult which represents the
128        distribution of results.
129        """
130        # All the results will be of the same type, so we can safely check the
131        # first result only.
132        if isinstance(results[0], iperf_runner.IperfResult):
133            return iperf_runner.IperfResult.from_samples(results)
134        if isinstance(results[0], netperf_runner.NetperfResult):
135            return netperf_runner.NetperfResult.from_samples(results)
136        raise error.TestFail('Invalid test result type: %s' % type(results))
137
138    def _netperf_type_from_perf_type(self, test_type):
139        """Convert a performance test type to a netperf test type.
140
141        @param test_type string, test type from PerfTestTypes.
142
143        @return string netperf test type that corresponds to the generic test type.
144        """
145        if test_type == PerfTestTypes.TEST_TYPE_TCP_TX:
146            return netperf_runner.NetperfConfig.TEST_TYPE_TCP_STREAM
147        elif test_type == PerfTestTypes.TEST_TYPE_TCP_RX:
148            return netperf_runner.NetperfConfig.TEST_TYPE_TCP_MAERTS
149        elif test_type == PerfTestTypes.TEST_TYPE_TCP_BIDIRECTIONAL:
150            return netperf_runner.NetperfConfig.TEST_TYPE_TCP_BIDIRECTIONAL
151        elif test_type == PerfTestTypes.TEST_TYPE_UDP_TX:
152            return netperf_runner.NetperfConfig.TEST_TYPE_UDP_STREAM
153        elif test_type == PerfTestTypes.TEST_TYPE_UDP_RX:
154            return netperf_runner.NetperfConfig.TEST_TYPE_UDP_MAERTS
155        elif test_type == PerfTestTypes.TEST_TYPE_UDP_BIDIRECTIONAL:
156            return netperf_runner.NetperfConfig.TEST_TYPE_UDP_BIDIRECTIONAL
157        raise error.TestFail(
158                'Test type %s is not supported by netperf_runner.' % test_type)
159
160    def _iperf_type_from_perf_type(self, test_type):
161        """Convert a performance test type to an iperf test type
162
163        @param test_type string, test type from PerfTestTypes.
164
165        @return string iperf test type that corresponds to the generic test type.
166        """
167        if test_type == PerfTestTypes.TEST_TYPE_TCP_TX:
168            return iperf_runner.IperfConfig.IPERF_TEST_TYPE_TCP_TX
169        elif test_type == PerfTestTypes.TEST_TYPE_TCP_RX:
170            return iperf_runner.IperfConfig.IPERF_TEST_TYPE_TCP_RX
171        elif test_type == PerfTestTypes.TEST_TYPE_TCP_BIDIRECTIONAL:
172            return iperf_runner.IperfConfig.IPERF_TEST_TYPE_TCP_BIDIRECTIONAL
173        elif test_type == PerfTestTypes.TEST_TYPE_UDP_TX:
174            return iperf_runner.IperfConfig.IPERF_TEST_TYPE_UDP_TX
175        elif test_type == PerfTestTypes.TEST_TYPE_UDP_RX:
176            return iperf_runner.IperfConfig.IPERF_TEST_TYPE_UDP_RX
177        elif test_type == PerfTestTypes.TEST_TYPE_UDP_BIDIRECTIONAL:
178            return iperf_runner.IperfConfig.IPERF_TEST_TYPE_UDP_BIDIRECTIONAL
179        raise error.TestFail(
180                'Test type %s is not supported by netperf_runner.' % test_type)
181