2 # SPDX-License-Identifier: GPL-2.0
5 #This file has basic performance test for generic NIC drivers.
6 #The test comprises of throughput check for TCP and UDP streams.
9 #Connect the DUT PC with NIC card to partner pc back via ethernet medium of your choice(RJ45, T1)
12 #┌───────────────────────┐ ┌──────────────────────────┐
17 #│ │Interface ─┼─────────────────────────┼─ any eth Interface │
21 #└───────────────────────┘ └──────────────────────────┘
24 #To prevent interruptions, Add ethtool, ip to the sudoers list in remote PC and get the ssh key from remote.
25 #Required minimum ethtool version is 6.10
26 #Change the below configuration based on your hw needs.
27 # """Default values"""
28 #time_delay = 8 #time taken to wait for transitions to happen, in seconds.
29 #test_duration = 10 #performance test duration for the throughput check, in seconds.
30 #send_throughput_threshold = 80 #percentage of send throughput required to pass the check
31 #receive_throughput_threshold = 50 #percentage of receive throughput required to pass the check
36 from lib
.py
import ksft_run
, ksft_exit
, ksft_pr
, ksft_true
37 from lib
.py
import KsftFailEx
, KsftSkipEx
, GenerateTraffic
38 from lib
.py
import NetDrvEpEnv
, bkg
, wait_port_listen
39 from lib
.py
import cmd
40 from lib
.py
import LinkConfig
43 def __init__(self
, time_delay
: int, test_duration
: int, send_throughput_threshold
: int, receive_throughput_threshold
: int) -> None:
44 self
.time_delay
= time_delay
45 self
.test_duration
= test_duration
46 self
.send_throughput_threshold
= send_throughput_threshold
47 self
.receive_throughput_threshold
= receive_throughput_threshold
49 def _pre_test_checks(cfg
: object, link_config
: LinkConfig
) -> None:
50 if not link_config
.verify_link_up():
51 KsftSkipEx(f
"Link state of interface {cfg.ifname} is DOWN")
52 common_link_modes
= link_config
.common_link_modes
53 if common_link_modes
is None:
54 KsftSkipEx("No common link modes found")
55 if link_config
.partner_netif
== None:
56 KsftSkipEx("Partner interface is not available")
57 if link_config
.check_autoneg_supported():
58 KsftSkipEx("Auto-negotiation not supported by local")
59 if link_config
.check_autoneg_supported(remote
=True):
60 KsftSkipEx("Auto-negotiation not supported by remote")
61 cfg
.require_cmd("iperf3", remote
=True)
63 def check_throughput(cfg
: object, link_config
: LinkConfig
, test_config
: TestConfig
, protocol
: str, traffic
: GenerateTraffic
) -> None:
64 common_link_modes
= link_config
.common_link_modes
65 speeds
, duplex_modes
= link_config
.get_speed_duplex_values(common_link_modes
)
66 """Test duration in seconds"""
67 duration
= test_config
.test_duration
69 ksft_pr(f
"{protocol} test")
70 test_type
= "-u" if protocol
== "UDP" else ""
73 receive_throughput
= []
74 for idx
in range(0, len(speeds
)):
75 if link_config
.set_speed_and_duplex(speeds
[idx
], duplex_modes
[idx
]) == False:
76 raise KsftFailEx(f
"Not able to set speed and duplex parameters for {cfg.ifname}")
77 time
.sleep(test_config
.time_delay
)
78 if not link_config
.verify_link_up():
79 raise KsftSkipEx(f
"Link state of interface {cfg.ifname} is DOWN")
81 send_command
=f
"{test_type} -b 0 -t {duration} --json"
82 receive_command
=f
"{test_type} -b 0 -t {duration} --reverse --json"
84 send_result
= traffic
.run_remote_test(cfg
, command
=send_command
)
85 if send_result
.ret
!= 0:
86 raise KsftSkipEx("Error occurred during data transmit: {send_result.stdout}")
88 send_output
= send_result
.stdout
89 send_data
= json
.loads(send_output
)
91 """Convert throughput to Mbps"""
92 send_throughput
.append(round(send_data
['end']['sum_sent']['bits_per_second'] / 1e6
, 2))
93 ksft_pr(f
"{protocol}: Send throughput: {send_throughput[idx]} Mbps")
95 receive_result
= traffic
.run_remote_test(cfg
, command
=receive_command
)
96 if receive_result
.ret
!= 0:
97 raise KsftSkipEx("Error occurred during data receive: {receive_result.stdout}")
99 receive_output
= receive_result
.stdout
100 receive_data
= json
.loads(receive_output
)
102 """Convert throughput to Mbps"""
103 receive_throughput
.append(round(receive_data
['end']['sum_received']['bits_per_second'] / 1e6
, 2))
104 ksft_pr(f
"{protocol}: Receive throughput: {receive_throughput[idx]} Mbps")
106 """Check whether throughput is not below the threshold (default values set at start)"""
107 for idx
in range(0, len(speeds
)):
108 send_threshold
= float(speeds
[idx
]) * float(test_config
.send_throughput_threshold
/ 100)
109 receive_threshold
= float(speeds
[idx
]) * float(test_config
.receive_throughput_threshold
/ 100)
110 ksft_true(send_throughput
[idx
] >= send_threshold
, f
"{protocol}: Send throughput is below threshold for {speeds[idx]} Mbps in {duplex_modes[idx]} duplex")
111 ksft_true(receive_throughput
[idx
] >= receive_threshold
, f
"{protocol}: Receive throughput is below threshold for {speeds[idx]} Mbps in {duplex_modes[idx]} duplex")
113 def test_tcp_throughput(cfg
: object, link_config
: LinkConfig
, test_config
: TestConfig
, traffic
: GenerateTraffic
) -> None:
114 _pre_test_checks(cfg
, link_config
)
115 check_throughput(cfg
, link_config
, test_config
, 'TCP', traffic
)
117 def test_udp_throughput(cfg
: object, link_config
: LinkConfig
, test_config
: TestConfig
, traffic
: GenerateTraffic
) -> None:
118 _pre_test_checks(cfg
, link_config
)
119 check_throughput(cfg
, link_config
, test_config
, 'UDP', traffic
)
122 parser
= argparse
.ArgumentParser(description
="Run basic performance test for NIC driver")
123 parser
.add_argument('--time-delay', type=int, default
=8, help='Time taken to wait for transitions to happen(in seconds). Default is 8 seconds.')
124 parser
.add_argument('--test-duration', type=int, default
=10, help='Performance test duration for the throughput check, in seconds. Default is 10 seconds.')
125 parser
.add_argument('--stt', type=int, default
=80, help='Send throughput Threshold: Percentage of send throughput upon actual throughput required to pass the throughput check (in percentage). Default is 80.')
126 parser
.add_argument('--rtt', type=int, default
=50, help='Receive throughput Threshold: Percentage of receive throughput upon actual throughput required to pass the throughput check (in percentage). Default is 50.')
127 args
=parser
.parse_args()
128 test_config
= TestConfig(args
.time_delay
, args
.test_duration
, args
.stt
, args
.rtt
)
129 with
NetDrvEpEnv(__file__
, nsim_test
=False) as cfg
:
130 traffic
= GenerateTraffic(cfg
)
131 link_config
= LinkConfig(cfg
)
132 ksft_run(globs
=globals(), case_pfx
={"test_"}, args
=(cfg
, link_config
, test_config
, traffic
, ))
133 link_config
.reset_interface()
136 if __name__
== "__main__":