[AETHER-1472]: Add iperf downlink+uplink test to monitoring agent
Change-Id: I9d37ddfa0d8e2f8c773f54a751a751c8b6a42c12
diff --git a/edge-monitoring/agent_modem/config.json b/edge-monitoring/agent_modem/config.json
index c8717b0..3a33d1d 100644
--- a/edge-monitoring/agent_modem/config.json
+++ b/edge-monitoring/agent_modem/config.json
@@ -7,12 +7,14 @@
},
"ips": {
"user_plane_ping_test": "8.8.8.8",
- "speedtest_ping_dns": "8.8.8.8"
+ "speedtest_ping_dns": "8.8.8.8",
+ "speedtest_iperf": ""
},
"attach_timeout": 30,
"detach_timeout": 10,
"report_url": "https://monitoring.aetherproject.org/edges",
"report_interval": 180,
"log_level": "WARN",
- "log_file": "/var/log/edge_monitoring_agent.log"
+ "log_file": "/var/log/edge_monitoring_agent.log",
+ "iperf_port": 0
}
diff --git a/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py b/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
index cdfab63..180ea76 100755
--- a/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
+++ b/edge-monitoring/agent_modem/edge_monitoring_agent_modem.py
@@ -185,6 +185,7 @@
def get_ping_test(modem):
'''
+ Prepares the ping test.
Each ping test result saves the min/avg/max/stddev to dict.
1) Performs ping test to Google Public DNS for 10 iterations.
2) # TODO: Performs ping to device on network.
@@ -193,6 +194,41 @@
speedtest_ping['dns'] = run_ping_test(CONF.ips.speedtest_ping_dns, 10)
return speedtest_ping
+def run_iperf_test(ip, port, time_duration, is_downlink):
+ '''
+ Runs iperf test to specified IP in the config file.
+ - Runs for 10 seconds (10 iterations)
+ - Retrieves downlink and uplink test results from json output
+ '''
+ result = 0.0
+ if not ip:
+ return result
+ try:
+ iperfResult = json.loads(subprocess.check_output(
+ "iperf3 -c " + ip +
+ " -p " + str(port) +
+ " -t " + str(time_duration) +
+ (" -R " if is_downlink else "") +
+ " --json", shell=True).decode("UTF-8"))
+ received_mbps = iperfResult['end']['sum_received']['bits_per_second'] / 1000000
+ sent_mbps = iperfResult['end']['sum_sent']['bits_per_second'] / 1000000.0
+ result = received_mbps if is_downlink else sent_mbps
+ except Exception as e:
+ logging.error("iperf test failed for " + ip + ": %s", e)
+ return result
+
+
+def get_iperf_test(modem):
+ '''
+ Prepares the iperf test.
+ '''
+ speedtest_iperf = {}
+ speedtest_iperf['cluster'] = {}
+ speedtest_iperf['cluster']['downlink'] = run_iperf_test(CONF.ips.speedtest_iperf, CONF.iperf_port, 10, True)
+ speedtest_iperf['cluster']['uplink'] = run_iperf_test(CONF.ips.speedtest_iperf, CONF.iperf_port, 10, False)
+
+ return speedtest_iperf
+
def get_signal_quality(modem):
success, result = modem.write('AT+CESQ')
@@ -214,7 +250,7 @@
return result
-def report_status(signal_quality, cp_state=None, up_state=None, speedtest_ping=None):
+def report_status(signal_quality, cp_state=None, up_state=None, speedtest_ping=None, speedtest_iperf=None):
report = {
'name': CONF.edge_name,
'status': {
@@ -229,6 +265,12 @@
'max': 0.0,
'stddev': 0.0
}
+ },
+ 'iperf': {
+ 'cluster': {
+ 'downlink': 0.0,
+ 'uplink': 0.0
+ }
}
},
'signal_quality': {
@@ -243,6 +285,8 @@
report['status']['user_plane'] = up_state.name
if speedtest_ping is not None:
report['speedtest']['ping'] = speedtest_ping
+ if speedtest_iperf is not None:
+ report['speedtest']['iperf'] = speedtest_iperf
report['signal_quality'] = signal_quality
logging.info("Sending report %s", report)
@@ -261,6 +305,8 @@
def main():
for ip in CONF.ips:
+ if not ip:
+ continue
try:
subprocess.check_output("sudo ip route replace {}/32 via {}".format(
ip, CONF.modem.ip_addr), shell=True)
@@ -289,12 +335,14 @@
up_state = get_user_plane_state(modem)
if up_state is State.disconnected:
- # Basic user plan test failed, don't need to run the rest of tests
+ # Basic user plane test failed, don't need to run the rest of tests
report_status(signal_quality, cp_state)
continue
speedtest_ping = get_ping_test(modem)
- report_status(signal_quality, cp_state, up_state, speedtest_ping)
+ speedtest_iperf = get_iperf_test(modem)
+
+ report_status(signal_quality, cp_state, up_state, speedtest_ping, speedtest_iperf)
modem.close()