A comprehensive network performance testing toolkit designed for measuring bandwidth, latency, jitter, and packet loss across wireless and ethernet networks. Ideal for autonomous vessel diagnostics, satellite communications testing, and network infrastructure validation.
- Features
- Installation
- Quick Start
- Usage
- Results and Analysis
- Advanced Features
- Public iperf3 Servers
- Troubleshooting
- β TCP Bandwidth Testing: Upload and download throughput measurements
- β UDP Bandwidth Testing: Controlled-rate UDP testing with jitter and packet loss metrics
- β Latency Testing: ICMP ping tests to gateway and WAN targets
- β Traceroute Analysis: Network path discovery and hop-by-hop latency
- β Network Interface Detection: Automatic WiFi/Ethernet interface identification
- β WiFi Statistics: RSSI, BSSID, channel, and link speed capture (macOS)
- π Automated HTML Reports: Summary statistics with comparison plots
- π Time-Series Visualization: Bandwidth, latency, jitter, and packet loss trends
- πΊοΈ Network Topology Graphs: Visual representation of network paths
- π CSV Export: Summary data for external analysis
- π Continuous Testing: Loop mode for long-duration monitoring
- π macOS: Full support with native WiFi tools (wdutil)
- πͺ Windows: PowerShell scripts (see
wifi_tests/) - π§ Linux: Compatible with standard network tools
- iperf3: Network bandwidth testing tool
- Python 3.8+: For analysis and plotting
- Bash/Zsh: For test execution scripts (macOS/Linux)
brew install iperf3Verify installation:
iperf3 --version# Navigate to project directory
cd network_perf_tests
# Install required packages
pip3 install --break-system-packages pandas matplotlib seaborn networkx
# Or using a virtual environment (recommended)
python3 -m venv .venv
source .venv/bin/activate
pip3 install pandas matplotlib seaborn networkxchmod +x scripts/wifi_run_macos.shSee wifi_tests/wifi_test_suite.ps1 for PowerShell-based testing on Windows.
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id My_Network_Test \
--run-name testA \
--duration 30 \
--udp-target-mbps 50 \
--verbose \
--auto-plotThis will:
- Run traceroute to server and WAN
- Execute TCP download/upload tests
- Execute UDP download/upload tests at 50 Mbps
- Ping gateway and 8.8.8.8
- Capture WiFi/network interface stats
- Generate HTML report with plots
- Automatically open report in browser
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id Boston_Monitor \
--duration 30 \
--udp-target-mbps 50 \
--loop-minutes 120 \
--loop-interval 60 \
--verbose \
--auto-plotThis runs 30-second tests every 60 seconds for 2 hours, automatically naming iterations (test1, test2, test3...).
./scripts/wifi_run_macos.sh --server SERVER --test-id TEST_ID [OPTIONS]--server SERVER: iperf3 server IP or hostname--test-id TEST_ID: Identifier for this test series (e.g., "macbook_wifi", "vessel_network")
--run-name NAME: Custom name for this test run (e.g., "testA", "baseline")--duration N: Duration of each iperf test in seconds (default: 30)--udp-target-mbps M: Target UDP bandwidth in Mbps (default: 100)--verbose: Enable detailed logging--auto-plot: Automatically generate and open HTML report after test
Quick test with default settings:
./scripts/wifi_run_macos.sh --server 100.101.52.16 --test-id vessel_testHigh-bandwidth test with verbose logging:
./scripts/wifi_run_macos.sh \
--server 185.93.1.65 \
--test-id high_bandwidth \
--run-name test1 \
--duration 60 \
--udp-target-mbps 1000 \
--verbose \
--auto-plotLow-bandwidth test for satellite connections:
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id viasat_test \
--duration 30 \
--udp-target-mbps 50 \
--verbose \
--auto-plotLoop testing runs multiple test iterations over a specified time period, ideal for monitoring network stability and performance trends.
--loop-minutes N: Run tests continuously for N minutes--loop-interval N: Wait N seconds between iterations (default: 60)
2-hour monitoring with 2-minute intervals:
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id daily_monitor \
--duration 30 \
--udp-target-mbps 50 \
--loop-minutes 120 \
--loop-interval 120 \
--verbose \
--auto-plotAll-day monitoring (8 hours) with 5-minute intervals:
./scripts/wifi_run_macos.sh \
--server 100.101.52.16 \
--test-id vessel_ops \
--duration 30 \
--udp-target-mbps 50 \
--loop-minutes 480 \
--loop-interval 300 \
--verbose \
--auto-plotIntensive testing with 30-second intervals for 1 hour:
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id stress_test \
--duration 10 \
--udp-target-mbps 100 \
--loop-minutes 60 \
--loop-interval 30 \
--verbose \
--auto-plotCustom run names with loop mode:
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id experiment \
--run-name trial \
--loop-minutes 30 \
--loop-interval 60 \
--verbose \
--auto-plotThis creates: trial1, trial2, trial3, etc.
- 10 seconds: Quick connectivity checks
- 30 seconds: Standard testing (recommended)
- 60 seconds: Detailed analysis, better statistics
- 10 Mbps: Minimal telemetry and low-quality video
- 25-50 Mbps: Single HD video stream + telemetry (recommended for vessel ops)
- 100 Mbps: Multiple HD streams with headroom
- 500-1000 Mbps: High-bandwidth infrastructure testing
Note: For satellite and Silvus radio links, use 50 Mbps or less to avoid overwhelming the connection.
Test results are stored in the results/ directory with the following structure:
results/
βββ artifacts_<test_id>_<run_name>_<timestamp>/
β βββ iperf_<test_id>_<timestamp>_tcp_dl.json # TCP download results
β βββ iperf_<test_id>_<timestamp>_tcp_ul.json # TCP upload results
β βββ iperf_<test_id>_<timestamp>_udp_dl.json # UDP download results
β βββ iperf_<test_id>_<timestamp>_udp_ul.json # UDP upload results
β βββ ping_<test_id>_<timestamp>_gw.txt # Gateway ping results
β βββ ping_<test_id>_<timestamp>_wan.txt # WAN ping results (8.8.8.8)
β βββ traceroute_<test_id>_<timestamp>_server.txt # Traceroute to iperf server
β βββ traceroute_<test_id>_<timestamp>_wan.txt # Traceroute to 8.8.8.8
β βββ wlan_<test_id>_<timestamp>.txt # Raw WiFi/interface info
β βββ wlan_<test_id>_<timestamp>_summary.json # Parsed network interface data
βββ analysis_output/
βββ summary.csv # Combined results from all tests
βββ comparison_report.html # Interactive HTML report
βββ plot_tcp_bandwidth.png # TCP throughput comparison
βββ plot_udp_bandwidth.png # UDP throughput comparison
βββ plot_latency.png # Latency comparison
βββ plot_udp_jitter.png # UDP jitter comparison
βββ plot_udp_packet_loss.png # UDP packet loss comparison
When using --auto-plot, reports are generated automatically after each test (or after each loop iteration).
Regenerate reports anytime from existing test data:
python3 scripts/plot_results.py \
--artifacts-root results \
--outdir results/analysis_output \
--open-reportThe HTML report includes:
- Summary Statistics Table: All tests with key metrics
- TCP Bandwidth Plots: Upload and download throughput over time
- UDP Bandwidth Plots: Upload and download throughput over time
- Latency Plots: Gateway and WAN ping latency with mean/median/P95
- UDP Jitter Plots: Jitter measurements (UDP only)
- UDP Packet Loss Plots: Packet loss percentage (UDP only)
Access raw data in results/analysis_output/summary.csv for:
- Custom analysis
- Importing into Excel/Google Sheets
- Integration with other tools
Generate network topology visualizations from traceroute data:
python3 scripts/analyze_traceroute.py \
--artifacts-root results \
--outdir results/traceroute_analysis \
--open-reportAnalyze only tests matching a pattern:
python3 scripts/analyze_traceroute.py \
--artifacts-root results \
--outdir results/traceroute_analysis_paolo \
--filter paolo \
--open-report- Network Graph Visualization: Color-coded nodes by type (client, LAN, gateway, radio, satellite, ISP, WAN)
- Hop-by-Hop Analysis: Detailed latency at each hop
- Path Summary: Number of hops, total nodes, unique paths
- Node Classification: Automatic identification of network segments
- π΅ Client: Your local machine
- π’ LAN: Local network devices
- π‘ Gateway: Router/gateway devices
- π Radio: Silvus or other radio equipment
- π΄ Satellite: Viasat or other satellite terminals
- π£ ISP: Internet service provider infrastructure
- β« WAN: Internet backbone and destination servers
The script automatically detects and logs:
- WiFi: SSID, BSSID, RSSI, channel, link speed (via
wdutilon macOS) - Ethernet: Interface name, device, MAC address, link speed
- Thunderbolt/USB: Network adapters
Automatically discovers and pings your default gateway using:
route -n get default | awk '/gateway/ {print $2}'iperf tests use exponential backoff with jitter:
- Up to 8 retry attempts
- Base delay: 1 second
- Maximum backoff: 16 seconds
- Handles temporary network interruptions gracefully
Uses Perl-based timeout for macOS compatibility:
perl -e 'alarm shift; exec @ARGV' 60 traceroute -m 20 -q 2 -w 2 <target>- 60-second total timeout
- Maximum 20 hops
- 2 queries per hop
- 2-second wait per query
--server 109.61.86.65- Location: Boston, US
- Bandwidth: 2x10 Gbps
- Supports: TCP, UDP (-R, -u flags)
- Port: 5201 (default)
--server iperf.he.net- Provider: Hurricane Electric
- Supports: TCP, UDP
- Port: 5201
--server 185.93.1.65- Supports: TCP, UDP
- Port: 5201
If testing against your own iperf3 server:
Server side:
iperf3 -s -p 5201Client side (this script):
./scripts/wifi_run_macos.sh --server <your-server-ip> --test-id my_test# Install via Homebrew (macOS)
brew install iperf3
# Verify installation
iperf3 --versionpip3 install --break-system-packages pandas matplotlib seaborn networkxOr use a virtual environment:
python3 -m venv .venv
source .venv/bin/activate
pip3 install pandas matplotlib seaborn networkxThe script attempts sudo -n wdutil (no password prompt) first, then falls back to regular wdutil. If you see permission errors:
# Allow sudo without password for wdutil (optional)
sudo visudo
# Add: your_username ALL=(ALL) NOPASSWD: /usr/sbin/wdutil- Verify iperf3 server is running:
iperf3 -c <server> -t 5 - Check firewall settings on server
- Ensure network connectivity:
ping <server>
If traceroute files show timeout errors, the script now uses Perl-based timeout (fixed in latest version). Re-run tests to capture proper traceroute data.
Manually open the report:
open results/analysis_output/comparison_report.htmlOr specify the full path:
python3 scripts/plot_results.py \
--artifacts-root results \
--outdir results/analysis_output \
--open-report# Test 1: High bandwidth baseline
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id baseline \
--run-name high_bw \
--duration 30 \
--udp-target-mbps 100 \
--verbose --auto-plot
# Test 2: Low bandwidth (realistic vessel ops)
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id baseline \
--run-name low_bw \
--duration 30 \
--udp-target-mbps 50 \
--verbose --auto-plot# Monitor network for 4 hours with 5-minute intervals
./scripts/wifi_run_macos.sh \
--server 100.101.52.16 \
--test-id vessel_monitor \
--duration 30 \
--udp-target-mbps 50 \
--loop-minutes 240 \
--loop-interval 300 \
--verbose --auto-plot# Before configuration change
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id config_test \
--run-name before \
--duration 30 \
--udp-target-mbps 50 \
--verbose --auto-plot
# (Make configuration changes)
# After configuration change
./scripts/wifi_run_macos.sh \
--server 109.61.86.65 \
--test-id config_test \
--run-name after \
--duration 30 \
--udp-target-mbps 50 \
--verbose --auto-plot
# Compare results in the HTML reportContributions welcome! Areas for improvement:
- Linux-specific WiFi statistics collection
- Windows Bash/WSL support
- Additional network metrics (DNS resolution time, HTTP latency)
- Real-time plotting during long test runs
- Database storage for historical analysis
This project is licensed under the MIT License. See the LICENSE file for details.
For issues, questions, or feature requests, please open an issue on GitHub.
Note: This toolkit is designed for network diagnostics and performance validation. Always ensure you have permission to run bandwidth tests against any iperf3 server you use.