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+ """
1220import json
1321import csv
1422import time
1523import datetime
1624import subprocess
17- import argparse
1825import os
1926from 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+
8480def 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+
120119def 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
153155if __name__ == "__main__" :
154156 main ()
0 commit comments