Skip to content

Commit 6259c04

Browse files
Read env vars in main() instead of the beginning to avoid KeyError
1 parent 427c677 commit 6259c04

File tree

1 file changed

+56
-54
lines changed

1 file changed

+56
-54
lines changed

speedtest.py

Lines changed: 56 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,40 @@
11
#!/usr/bin/env python3
2-
# Make sure you have iperf3 executable downloaded and make sure it's running before you run this code
3-
# Below is the command to run this code
4-
# TCP: python iperf_automation.py <ip address> -p <port> -t <test length> -i <test interval> -o <saved folder>
5-
# Example: python iperf_automation.py 127.0.0.1 -p 5201 -t 8 -i 20 -o highway_test_Linux
6-
# UDP: python iperf_automation.py <ip address> -p <port> -t <test length> -i <test interval> -o <saved folder> -u -b <bandwidth>
7-
# Example: python iperf_automation.py 127.0.0.1 -p 5201 -t 8 -i 20 -o highway_test_Linux_udp -u -b 100M
8-
# -b 100M = 100 Mbps
9-
# -b 1G = 1 Gbps
10-
# -b 500M = 500 Mbps
11-
# -b 10M = 10 Mbps
2+
"""
3+
Iperf3 automation for network performance testing.
4+
Configured via environment variables for containerized deployment.
5+
6+
Required environment variables:
7+
SERVER_IP - iperf3 server IP address
8+
9+
Optional environment variables (with defaults):
10+
PORT - Server port (default: 5201)
11+
DURATION - Test duration in seconds (default: 5)
12+
INTERVAL - Interval between tests in seconds (default: 10)
13+
OUTPUT_DIR - Output directory (default: /data)
14+
PROTOCOL - 'tcp' or 'udp' (default: tcp)
15+
BANDWIDTH - UDP bandwidth limit (default: 100M)
16+
17+
Usage:
18+
podman run --env-file options.env -v ./results:/data:z image_name
19+
"""
1220
import json
1321
import csv
1422
import time
1523
import datetime
1624
import subprocess
17-
import argparse
1825
import os
1926
from pathlib import Path
2027

2128

22-
server_ip = os.environ["SERVER_IP"]
23-
port = os.environ["PORT"]
24-
duration = os.environ["DURATION"]
25-
output_dir = os.environ["OUTPUT_DIR"]
26-
test_count = os.environ["TEST_COUNT"]
27-
protocol = os.environ["PROTOCOL"]
28-
bandwidth = os.environ["BANDWIDTH"]
29-
30-
## Runs both Download and Upload tests
31-
def run_tests(server_ip, port, duration, iperf3_path, output_dir, test_count, protocol, bandwidth):
29+
def run_tests(server_ip, port, duration, output_dir, test_count, protocol, bandwidth):
30+
"""Run download and upload iperf3 tests."""
3231
results = {}
3332

3433
# Download test
3534
print("Running download test...")
36-
cmd = [iperf3_path, '-c', server_ip, '-p', str(port), '-t', str(duration), '-R', '-J']
35+
cmd = ['iperf3', '-c', server_ip, '-p', str(port), '-t', str(duration), '-R', '-J']
3736
if protocol == 'udp':
38-
cmd.insert(-2, '-u')
39-
cmd.insert(-2, '-b')
40-
cmd.insert(-2, bandwidth)
37+
cmd.extend(['-u', '-b', bandwidth])
4138

4239
result = subprocess.run(cmd, capture_output=True, text=True)
4340
data = json.loads(result.stdout)
@@ -56,13 +53,11 @@ def run_tests(server_ip, port, duration, iperf3_path, output_dir, test_count, pr
5653

5754
time.sleep(1)
5855

59-
# Upload test
56+
# Upload test
6057
print("Running upload test...")
61-
cmd = [iperf3_path, '-c', server_ip, '-p', str(port), '-t', str(duration), '-J']
58+
cmd = ['iperf3', '-c', server_ip, '-p', str(port), '-t', str(duration), '-J']
6259
if protocol == 'udp':
63-
cmd.insert(-1, '-u')
64-
cmd.insert(-1, '-b')
65-
cmd.insert(-1, bandwidth)
60+
cmd.extend(['-u', '-b', bandwidth])
6661

6762
result = subprocess.run(cmd, capture_output=True, text=True)
6863
data = json.loads(result.stdout)
@@ -81,10 +76,12 @@ def run_tests(server_ip, port, duration, iperf3_path, output_dir, test_count, pr
8176

8277
return results
8378

79+
8480
def save_to_csv(results, csv_file, test_number, protocol):
81+
"""Save test results to CSV file."""
8582
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
8683

87-
# If file csv file does not exist, create a new one
84+
# Create CSV with headers if it doesn't exist
8885
if not csv_file.exists():
8986
with open(csv_file, 'w', newline='') as f:
9087
if protocol == 'tcp':
@@ -108,47 +105,52 @@ def save_to_csv(results, csv_file, test_number, protocol):
108105
results['upload_lost_packets'], results['upload_lost_percent']
109106
]
110107

111-
# New Row
108+
# Append row to CSV
112109
with open(csv_file, 'a', newline='') as f:
113110
csv.writer(f).writerow(row)
114111

112+
# Print summary
115113
if protocol == 'tcp':
116114
print(f"Test #{test_number}: Down={results['download_mbps']:.2f} Mbps, Up={results['upload_mbps']:.2f} Mbps")
117115
else:
118116
print(f"Test #{test_number}: Down={results['download_mbps']:.2f} Mbps, Up={results['upload_mbps']:.2f} Mbps | DL Loss: {results['download_lost_percent']:.2f}%, UL Loss: {results['upload_lost_percent']:.2f}%")
119117

118+
120119
def main():
121-
parser = argparse.ArgumentParser()
122-
parser.add_argument('server_ip')
123-
parser.add_argument('-p', '--port', type=int, default=5201)
124-
parser.add_argument('-t', '--duration', type=int, default=5)
125-
parser.add_argument('-i', '--interval', type=int, default=10)
126-
parser.add_argument('-o', '--output-dir', default='test_results')
127-
parser.add_argument('-u', '--udp', action='store_true', help='Use UDP instead of TCP')
128-
parser.add_argument('-b', '--bandwidth', default='100M')
129-
130-
args = parser.parse_args()
131-
132-
protocol = 'udp' if args.udp else 'tcp'
133-
134-
iperf3_path = 'iperf3'
135-
136-
output_dir = Path(args.output_dir)
137-
output_dir.mkdir(exist_ok=True)
120+
# Read configuration from environment variables
121+
server_ip = os.environ.get('SERVER_IP')
122+
port = int(os.environ.get('PORT', 5201))
123+
duration = int(os.environ.get('DURATION', 5))
124+
interval = int(os.environ.get('INTERVAL', 10))
125+
output_dir = Path(os.environ.get('OUTPUT_DIR', '/data'))
126+
protocol = os.environ.get('PROTOCOL', 'tcp').lower()
127+
bandwidth = os.environ.get('BANDWIDTH', '100M')
128+
129+
# Validate required parameters
130+
if not server_ip:
131+
raise ValueError("SERVER_IP environment variable is required")
132+
133+
if protocol not in ['tcp', 'udp']:
134+
raise ValueError(f"PROTOCOL must be 'tcp' or 'udp', got: {protocol}")
135+
136+
# Setup output
137+
output_dir.mkdir(parents=True, exist_ok=True)
138138
timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
139139
csv_file = output_dir / f"results_{protocol}_{timestamp}.csv"
140140

141-
print(f"Testing {args.server_ip}:{args.port} using {protocol.upper()}")
141+
print(f"Testing {server_ip}:{port} using {protocol.upper()}")
142142
if protocol == 'udp':
143-
print(f"UDP bandwidth: {args.bandwidth}")
144-
print(f"Results: {csv_file}")
143+
print(f"UDP bandwidth: {bandwidth}")
144+
print(f"Results: {csv_file}\n")
145145

146+
# Run continuous tests
146147
test_count = 0
147148
while True:
148149
test_count += 1
149-
results = run_tests(args.server_ip, args.port, args.duration, iperf3_path, output_dir, test_count, protocol, args.bandwidth)
150+
results = run_tests(server_ip, port, duration, output_dir, test_count, protocol, bandwidth)
150151
save_to_csv(results, csv_file, test_count, protocol)
151-
time.sleep(args.interval)
152+
time.sleep(interval)
153+
152154

153155
if __name__ == "__main__":
154156
main()

0 commit comments

Comments
 (0)