blob: 8fe0d749a4b8418b043a3cd1c9d52390396dc041 [file] [log] [blame]
Naveen Joy7ea7ab52021-05-11 10:31:18 -07001#!/usr/bin/env python
2
3# Start an iPerf connection stream between two Linux namespaces ##
4
5import subprocess
6import os
Naveen Joye4168932022-10-04 14:22:05 -07007import sys
Naveen Joy7ea7ab52021-05-11 10:31:18 -07008
9
10class VppIperf:
11 """ "Create an iPerf connection stream between two namespaces.
12
13 Usage:
14 iperf = VppIperf() # Create the iPerf Object
15 iperf.client_ns = 'ns1' # Client Namespace
16 iperf.server_ns = 'ns2' # Server Namespace
17 iperf.server_ip = '10.0.0.102' # Server IP Address
18 iperf.start() # Start the connection stream
19
20 Optional:
21 iperf.duration = 15 # Time to transmit for in seconds (Default=10)
22
23 ## Optionally set any iperf client & server args
24 Example:
25 # Run 4 parallel streams, write to logfile & bind to port 5202
26 iperf.client_args='-P 4 --logfile /tmp/vpp-vm-tests/vpp_iperf.log -p 5202'
27 iperf.server_args='-p 5202'
28 """
29
Naveen Joye4168932022-10-04 14:22:05 -070030 def __init__(self, server_ns=None, client_ns=None, server_ip=None, logger=None):
Naveen Joy7ea7ab52021-05-11 10:31:18 -070031 self.server_ns = server_ns
32 self.client_ns = client_ns
33 self.server_ip = server_ip
34 self.duration = 10
35 self.client_args = ""
36 self.server_args = ""
Naveen Joye4168932022-10-04 14:22:05 -070037 self.logger = logger
Naveen Joy7ea7ab52021-05-11 10:31:18 -070038 # Set the iperf executable
Naveen Joy25b6e442023-02-02 13:56:59 -080039 self.iperf = self.get_iperf()
Naveen Joy7ea7ab52021-05-11 10:31:18 -070040
41 def ensure_init(self):
42 if self.server_ns and self.client_ns and self.server_ip:
43 return True
44 else:
45 raise Exception(
46 "Error: Cannot Start." "iPerf object has not been initialized"
47 )
48
Naveen Joy25b6e442023-02-02 13:56:59 -080049 def get_iperf(self):
50 """Return the iperf executable for running tests.
51
52 Look for the iperf executable in the following order
53 1. ${TEST_DATA_DIR}/usr/bin/iperf # running tests inside the VM
54 2. /usr/bin/iperf3 # running tests on the host
55 """
56 vm_test_dir = os.getenv("TEST_DATA_DIR", "/tmp/vpp-vm-tests")
57 if os.path.isdir(vm_test_dir):
58 iperf = os.path.join(vm_test_dir, "/usr/bin/iperf")
59 else:
60 iperf = "/usr/bin/iperf3"
61 if os.path.exists(iperf):
62 return iperf
63 else:
64 self.logger.error(f"Could not find an iperf executable for running tests")
65 sys.exit(1)
66
Naveen Joy7ea7ab52021-05-11 10:31:18 -070067 def start_iperf_server(self):
Naveen Joy7ea7ab52021-05-11 10:31:18 -070068 args = [
69 "ip",
70 "netns",
71 "exec",
72 self.server_ns,
73 self.iperf,
74 "-s",
75 "-D",
Naveen Joy7ea7ab52021-05-11 10:31:18 -070076 ]
77 args.extend(self.server_args.split())
Naveen Joye4168932022-10-04 14:22:05 -070078 args = " ".join(args)
Naveen Joy25b6e442023-02-02 13:56:59 -080079 self.logger.debug(f"Starting iperf server: {args}")
Naveen Joy7ea7ab52021-05-11 10:31:18 -070080 try:
Naveen Joye4168932022-10-04 14:22:05 -070081 return subprocess.run(
Naveen Joy7ea7ab52021-05-11 10:31:18 -070082 args,
Naveen Joy7ea7ab52021-05-11 10:31:18 -070083 timeout=self.duration + 5,
84 encoding="utf-8",
Naveen Joye4168932022-10-04 14:22:05 -070085 shell=True,
86 stdout=subprocess.PIPE,
87 stderr=subprocess.STDOUT,
Naveen Joy7ea7ab52021-05-11 10:31:18 -070088 )
89 except subprocess.TimeoutExpired as e:
90 raise Exception("Error: Timeout expired for iPerf", e.output)
91
92 def start_iperf_client(self):
Naveen Joy7ea7ab52021-05-11 10:31:18 -070093 args = [
94 "ip",
95 "netns",
96 "exec",
97 self.client_ns,
98 self.iperf,
99 "-c",
100 self.server_ip,
101 "-t",
102 str(self.duration),
103 ]
104 args.extend(self.client_args.split())
Naveen Joye4168932022-10-04 14:22:05 -0700105 args = " ".join(args)
Naveen Joy7ea7ab52021-05-11 10:31:18 -0700106 try:
Naveen Joye4168932022-10-04 14:22:05 -0700107 return subprocess.run(
Naveen Joy7ea7ab52021-05-11 10:31:18 -0700108 args,
Naveen Joy7ea7ab52021-05-11 10:31:18 -0700109 timeout=self.duration + 5,
110 encoding="utf-8",
Naveen Joye4168932022-10-04 14:22:05 -0700111 capture_output=True,
112 shell=True,
Naveen Joy7ea7ab52021-05-11 10:31:18 -0700113 )
114 except subprocess.TimeoutExpired as e:
115 raise Exception("Error: Timeout expired for iPerf", e.output)
116
Naveen Joye4168932022-10-04 14:22:05 -0700117 def start(self, server_only=False, client_only=False):
118 """Runs iPerf.
Naveen Joy7ea7ab52021-05-11 10:31:18 -0700119
Naveen Joye4168932022-10-04 14:22:05 -0700120 Starts the iperf server daemon & runs the iperf client.
121 arguments:-
122 server_only -- start the iperf server daemon only
123 client_only -- run the iperf client only
124 Return True if we have no errors in iPerf client, else False.
125 """
126 self.ensure_init()
127 if not client_only:
128 self.start_iperf_server()
129 if not server_only:
130 result = self.start_iperf_client()
131 self.logger.debug(f"Iperf client args: {result.args}")
132 self.logger.debug(result.stdout)
133 if result.stderr:
134 self.logger.error(
135 f"Error starting Iperf Client in Namespace: {self.client_ns}"
136 )
137 self.logger.error(f"Iperf client args: {result.args}")
138 self.logger.error(f"Iperf client has errors: {result.stderr}")
139 return False
140 else:
141 return True
142
143
144## Functions to start and stop iPerf using the iPerf object
145def start_iperf(
146 ip_version,
147 client_ns="iprf_client_ns",
148 server_ns="iprf_server_ns",
149 server_ipv4_address="10.0.0.102",
150 server_ipv6_address="2001:1::2",
151 client_args="",
152 server_args="",
153 duration=10,
154 server_only=False,
155 client_only=False,
156 logger=None,
157):
158 """Start an iperf connection stream using the iPerf object.
159
160 Starts iPerf an connection stream between an iPerf client in the
161 client namespace (client_ns) and a server in another
162 namespace (server_ns).
163 Parameters:
164 ip_version - 4 or 6
165 client_ns - iPerf client namespace
166 server_ns - iPerf server namespace
167 server_ipv4_address - ipv4 address of the server, if ip_version=4
168 server_ipv6_address - ipv6 address of the server, if ip_version=6
169 client_args - Additonal iperf control arguments to be passed
170 to the iperf client from the test (str)
171 server_args - Additonal iperf control arguments to be passed
172 to the iperf server from the test (str)
173 duration - Iperf duration in seconds
174 server_only - start iperf server only
175 client_only - start the iperf client only
176 logger - test logger
177 """
178 if ip_version == 4:
179 iperf_server_ip = server_ipv4_address
180 elif ip_version == 6:
181 iperf_server_ip = server_ipv6_address
182 client_args = "-V" + " " + client_args
183 server_args = "-V" + " " + server_args
184 iperf = VppIperf()
185 iperf.client_ns = client_ns
186 iperf.server_ns = server_ns
187 iperf.server_ip = iperf_server_ip
188 iperf.client_args = client_args
189 iperf.server_args = server_args
190 iperf.duration = duration
191 iperf.logger = logger
192 return iperf.start(server_only=server_only, client_only=client_only)
193
194
195def stop_iperf():
196 args = ["pkill", "iperf"]
197 args = " ".join(args)
198 try:
199 return subprocess.run(
200 args,
201 encoding="utf-8",
202 shell=True,
203 )
204 except Exception:
205 pass
Naveen Joy7ea7ab52021-05-11 10:31:18 -0700206
207
208if __name__ == "__main__":
209 # Run iPerf using default settings
210 iperf = VppIperf()
211 iperf.client_ns = "ns1"
212 iperf.server_ns = "ns2"
213 iperf.server_ip = "10.0.0.102"
214 iperf.duration = 20
215 iperf.start()