From a138b92f3a2bab16de376c4b577b7d0527086346 Mon Sep 17 00:00:00 2001 From: notplants Date: Mon, 1 May 2023 21:56:45 +0530 Subject: [PATCH] tests --- cowmesh_constants.py | 22 +++ cowmesh_pi_iperf_test.py | 37 ++-- cowmesh_router_iperf_test.py | 90 ++++----- cowmesh_scp_test.py | 125 +++++++----- get_device_info.y.py | 0 moonlight_analytics.py | 364 ++++++++++++++++++++++------------- nightly_test.py | 9 +- 7 files changed, 398 insertions(+), 249 deletions(-) create mode 100644 cowmesh_constants.py create mode 100644 get_device_info.y.py diff --git a/cowmesh_constants.py b/cowmesh_constants.py new file mode 100644 index 0000000..cce90fe --- /dev/null +++ b/cowmesh_constants.py @@ -0,0 +1,22 @@ +NODES = [ + "jaaga", + "redcottage", + "new-gazebo2", + "kotemanetp", + "guard", + "ddhills", + "bambino", + "thimmanayaka" +] + +HOST_TO_IP = { + "jaaga": "10.56.121.19", + "redcottage": "10.56.58.194", + "redcottage2": "10.56.114.42", + "new-gazebo2": "10.56.114.42", + "new-gazebo": "10.56.113.2", + "guard": "10.56.121.73", + "kotemanetp": "10.56.40.113", + "thimmanayaka": "10.56.39.34", + "bambino": "10.56.0.102" +} \ No newline at end of file diff --git a/cowmesh_pi_iperf_test.py b/cowmesh_pi_iperf_test.py index 94298cc..bdf9c46 100644 --- a/cowmesh_pi_iperf_test.py +++ b/cowmesh_pi_iperf_test.py @@ -73,21 +73,27 @@ class CowmeshPiIperfTester: async def start_iperf_servers(self): for node in nodes: - print("++ starting iperf server on {}".format(node)) - user = SECRETS["HOST_INFO"][node]["user"] - password = SECRETS["HOST_INFO"][node]["password"] + try: + print("++ starting iperf server on {}".format(node)) + user = SECRETS["HOST_INFO"][node]["user"] + password = SECRETS["HOST_INFO"][node]["password"] - myconn = paramiko.SSHClient() - myconn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + myconn = paramiko.SSHClient() + myconn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - myconn.connect(node, username=user, password=password) + myconn.connect(node, username=user, password=password) - remote_cmd = 'iperf -s &' - (stdin, stdout, stderr) = myconn.exec_command(remote_cmd) - await self.debug_log("{}".format(stdout.read())) - await self.debug_log("{}".format(type(myconn))) - await self.debug_log("Options available to deal with the connections are many like\n{}".format(dir(myconn))) - myconn.close() + remote_cmd = 'iperf -s &' + (stdin, stdout, stderr) = myconn.exec_command(remote_cmd) + await self.debug_log("{}".format(stdout.read())) + await self.debug_log("{}".format(type(myconn))) + await self.debug_log("Options available to deal with the connections are many like\n{}".format(dir(myconn))) + myconn.close() + except: + try: + self.log("++ error starting iperf server on {}".format(node)) + except: + continue async def cleanup_iperf_servers(self): await self.log("++ shutting down iperf servers") @@ -107,9 +113,12 @@ class CowmeshPiIperfTester: await self.debug_log("skip self") continue - r = await self.test_between_two_nodes(node_a, node_b) result_key = "{} -> {}".format(node_a, node_b) - self.results[result_key] = r + try: + r = await self.test_between_two_nodes(node_a, node_b) + self.results[result_key] = r + except Exception as e: + self.results[result_key] = "error: {}".format(e) # try: # await self.cleanup_iperf_servers() diff --git a/cowmesh_router_iperf_test.py b/cowmesh_router_iperf_test.py index 0fa7344..ff1c2e7 100644 --- a/cowmesh_router_iperf_test.py +++ b/cowmesh_router_iperf_test.py @@ -11,6 +11,7 @@ import asyncio, asyncssh, sys import paramiko import subprocess import json +from cowmesh_constants import NODES, HOST_TO_IP from cowmesh_helpers import cleanup_iperf_server @@ -19,32 +20,14 @@ SECRETS_PATH = os.path.join(PROJECT_PATH, "secrets.json") with open(SECRETS_PATH, 'r') as f: SECRETS = json.loads(f.read()) -nodes = [ - "jaaga", - "redcottage", - "new-gazebo2", - "kotemanetp", - "guard" -] - -host_to_ip = { - "jaaga": "10.56.121.19", - "redcottage": "10.56.58.194", - "redcottage2": "10.56.114.42", - "new-gazebo2": "10.56.114.42", - "new-gazebo": "10.56.113.2", - "guard": "10.56.121.73", - "kotemanetp": "10.56.40.113" -} - class CowmeshRouterIperfTester: - def __init__(self, log=None, debug=False, seconds=10): + def __init__(self, log=None, debug=False, time=10): if log: self.log = log self.debug = debug - self.time = seconds + self.time = time self.results = {} async def log(self, msg): @@ -64,7 +47,7 @@ class CowmeshRouterIperfTester: myconn.connect(node_a, username =u_name, password=pswd) - ip = host_to_ip[node_b] + ip = HOST_TO_IP[node_b] remote_cmd = 'iperf -c {ip} -p 5001 -t {seconds}'.format(ip=ip, seconds=self.time) (stdin, stdout, stderr) = myconn.exec_command(remote_cmd) @@ -77,50 +60,69 @@ class CowmeshRouterIperfTester: if match: to_return = match.group(1) else: - to_return = None + match = re.search("(\S+) Kbits", output) + if match: + to_return = match.group(1) + to_return = float(to_return) / 1000.0 + else: + to_return = None return to_return async def start_iperf_servers(self): - for node in nodes: - print("++ starting iperf server on {}".format(node)) - u_name = 'root' - pswd = SECRETS["ROUTER_PASSWORD"] + for node in NODES: + try: + print("++ starting iperf server on {}".format(node)) + u_name = 'root' + pswd = SECRETS["ROUTER_PASSWORD"] - myconn = paramiko.SSHClient() - myconn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + myconn = paramiko.SSHClient() + myconn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - myconn.connect(node, username=u_name, password=pswd) + myconn.connect(node, username=u_name, password=pswd) - remote_cmd = 'iperf -s &' - (stdin, stdout, stderr) = myconn.exec_command(remote_cmd) - await self.debug_log("{}".format(stdout.read())) - await self.debug_log("{}".format(type(myconn))) - await self.debug_log("Options available to deal with the connections are many like\n{}".format(dir(myconn))) - myconn.close() + remote_cmd = 'iperf -s &' + (stdin, stdout, stderr) = myconn.exec_command(remote_cmd) + await self.debug_log("{}".format(stdout.read())) + await self.debug_log("{}".format(type(myconn))) + await self.debug_log("Options available to deal with the connections are many like\n{}".format(dir(myconn))) + myconn.close() + except: + try: + await self.log("++ error starting iperf server on {}".format(node)) + except: + continue async def cleanup_iperf_servers(self): await self.log("shutting down iperf servers") - for node in nodes: + for node in NODES: user = "root" password = SECRETS["ROUTER_PASSWORD"] - ip = host_to_ip[node] + ip = HOST_TO_IP[node] await cleanup_iperf_server(node=node, ip=ip, username=user, password=password, log=self.log) async def run_test(self): - await self.start_iperf_servers() + try: + await self.start_iperf_servers() + except: + pass - for node_a in nodes: - for node_b in nodes: + for node_a in NODES: + for node_b in NODES: if node_a == node_b: await self.debug_log("skip self") continue - r = await self.test_between_two_nodes(node_a, node_b) - result_key = "{} -> {}".format(node_a, node_b) - self.results[result_key] = r - + try: + r = await self.test_between_two_nodes(node_a, node_b) + result_key = "{} -> {}".format(node_a, node_b) + self.results[result_key] = r + except Exception as e: + try: + await self.log("++ error running test between {} and {}: {}".format(node_a, node_b, e)) + except: + continue # try: # await self.cleanup_iperf_servers() # except: diff --git a/cowmesh_scp_test.py b/cowmesh_scp_test.py index ec5ef2c..8ef897c 100644 --- a/cowmesh_scp_test.py +++ b/cowmesh_scp_test.py @@ -7,29 +7,24 @@ import os import time import asyncio, asyncssh, sys import subprocess - +import json +import paramiko PROJECT_PATH = os.path.abspath(os.path.dirname(__file__)) test_img_path = os.path.join(PROJECT_PATH, "test.png") +SECRETS_PATH = os.path.join(PROJECT_PATH, "secrets.json") +with open(SECRETS_PATH, 'r') as f: + SECRETS = json.loads(f.read()) + +base_node = "janastunuc" # nuc in jaaga + +nodes = [ + "janastunuc", # nuc in jaaga + "solipi", # pi in guard + "writer", # pi in new-gazebo +] -node_dict = { - "jagga-nuc": { - "ip": "10.56.10.247", - "user": "cow", - "node_path": "/datadrive/data/cowmesh-network-test" - }, - "redcottage-pi": { - "ip": "10.56.148.122", - "user": "admin", - "node_path": "/home/admin/cowmesh-network-test" - }, - "newgazebo-pi": { - "ip": "10.56.11.111", - "user": "pi", - "node_path": "/home/pi/cowmesh-network-test" - }, -} # url for downloading test.png from the internet internet_url = "https://canalswans.commoninternet.net/test.png" @@ -44,12 +39,13 @@ if PREPARE_TEST: os.system(internet_scp_cmd) # first put the image on every node without testing the time (so that the test is prepared to run) - for name, from_node_vals in node_dict.items(): + for name, from_node_vals in SECRETS["HOST_INFO"].items(): print("PREPARING NODE {}".format(name)) ip = from_node_vals["ip"] dir_path = from_node_vals["node_path"] file_path = os.path.join(dir_path, "test.png") user = from_node_vals["user"] + password = from_node_vals["password"] mkdir_cmd = "ssh {user}@{ip} 'mkdir -p {dir_path}'".format(user=user, ip=ip, dir_path=dir_path) os.system(mkdir_cmd) scp_cmd = "scp {test_img_path} {user}@{ip}:{file_path}".format( @@ -60,16 +56,43 @@ if PREPARE_TEST: ) os.system(scp_cmd) + myconn = paramiko.SSHClient() + myconn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + myconn.connect(ip, username=user, password=password) + remote_cmd = 'mkdir -p {dir_path}'.format(dir_path=dir_path) + (stdin, stdout, stderr) = myconn.exec_command(remote_cmd) + output = str(stdout.read()) + print("output: {}".format(output)) + print(("errors: {}".format(stderr.read()))) + + scp_cmd = "scp {test_img_path} {user}@{ip}:{file_path}".format( + test_img_path=test_img_path, + ip=ip, + user=user, + file_path=file_path + ) + (stdin, stdout, stderr) = myconn.exec_command(scp_cmd) + output = str(stdout.read()) + print("output: {}".format(output)) + print(("errors: {}".format(stderr.read()))) + + myconn.close() + results = {} async def run_test(): # run the test on each node - for from_name, from_node_vals in node_dict.items(): + node_dict = SECRETS["HOST_INFO"] + for node in nodes: + from_name = node + from_node_vals = node_dict[node] from_ip = from_node_vals["ip"] from_dir_path = from_node_vals["node_path"] from_file_path = os.path.join(from_dir_path, "test.png") from_user = from_node_vals["user"] - for to_name, to_node_vals in node_dict.items(): + from_password = from_node_vals["password"] + for to_name in nodes: + to_node_vals = node_dict[to_name] if from_name == to_name: print("skip self") continue @@ -80,35 +103,40 @@ async def run_test(): to_ip = to_node_vals["ip"] to_dir_path = to_node_vals["node_path"] to_file_path = os.path.join(to_dir_path, "download.png") + to_password = to_node_vals["password"] - async with asyncssh.connect(from_ip, username=from_user) as conn: + scp_cmd = "scp -i {key_path} {from_file_path} {to_user}@{to_ip}:{to_file_path}".format( + key_path="$HOME/.ssh/janastu", + to_user=to_user, + to_ip=to_ip, + to_file_path=to_file_path, + from_file_path=from_file_path + ) - scp_cmd = "scp -i {key_path} {from_file_path} {to_user}@{to_ip}:{to_file_path}".format( - key_path="$HOME/.ssh/janastu", - to_user=to_user, - to_ip=to_ip, - to_file_path=to_file_path, - from_file_path=from_file_path - ) + start = time.time() - print(scp_cmd) + myconn = paramiko.SSHClient() + myconn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + myconn.connect(from_ip, username=from_user, password=from_password) + print(scp_cmd) + (stdin, stdout, stderr) = myconn.exec_command(scp_cmd) + exit_status = stdout.channel.recv_exit_status() + output = str(stdout.read()) + error = str(stderr.read()) + print("output: {}".format(output)) + print(("errors: {}".format(stderr.read()))) - start = time.time() - result = await conn.run(scp_cmd) - - if result.exit_status == 0: - print(result.stdout, end='') - end = time.time() - elapsed = (end - start) - result_key = "{}->{}".format(from_name, to_name) - print("{}: {} seconds".format(result_key, elapsed)) - results[result_key] = elapsed - else: - print(result.stderr, end='', file=sys.stderr) - print('Program exited with status %d' % result.exit_status, - file=sys.stderr) - results[result_key] = "error: {}".format(result.stderr) - return + result_key = "{} -> {}".format(from_name, to_name) + if exit_status == 0: + print("success: {}".format(output)) + end = time.time() + elapsed = (end - start) + print("{}: {} seconds".format(result_key, elapsed)) + results[result_key] = elapsed + else: + print("error: {}".format(error)) + results[result_key] = "error: {}".format(error) + return # scp_with_time_cmd = "set -e; /usr/bin/time -f '%e' {}".format(scp_cmd) # print("running: {}".format(scp_with_time_cmd)) @@ -117,6 +145,7 @@ async def run_test(): def run_laptop_test(): from_name = "laptop" # also measure transfers from laptop + node_dict = SECRETS["HOST_INFO"] for to_name, to_node_vals in node_dict.items(): print("** running test.png transfer test from laptop to {}".format(to_name)) @@ -154,8 +183,8 @@ def run_laptop_test(): try: - asyncio.get_event_loop().run_until_complete(run_test()) - # run_laptop_test() + # asyncio.get_event_loop().run_until_complete(run_test()) + run_laptop_test() print("** final results **") file_size = 13476 diff --git a/get_device_info.y.py b/get_device_info.y.py new file mode 100644 index 0000000..e69de29 diff --git a/moonlight_analytics.py b/moonlight_analytics.py index 61c7c9e..0351179 100644 --- a/moonlight_analytics.py +++ b/moonlight_analytics.py @@ -1,5 +1,6 @@ import asyncio import logging +from datetime import date, datetime from telegram import Update from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters @@ -12,6 +13,7 @@ from cowmesh_pi_iperf_test import CowmeshPiIperfTester PROJECT_PATH = os.path.abspath(os.path.dirname(__file__)) SECRETS_PATH = os.path.join(PROJECT_PATH, "secrets.json") +LOG_DIR_PATH = "/datadrive/apps/moonlight_analytics/results" with open(SECRETS_PATH, 'r') as f: SECRETS = json.loads(f.read()) @@ -20,186 +22,270 @@ logging.basicConfig( level=logging.INFO ) +class MoonlightTester: -async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): - await context.bot.send_message(chat_id=update.effective_chat.id, text="This is the moonlight analytics bot for mesh network diagnostics.\n\nType /help to see available commands.", message_thread_id=update.message.message_thread_id) + async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE): + await context.bot.send_message(chat_id=update.effective_chat.id, text="This is the moonlight analytics bot for mesh network diagnostics.\n\nType /help to see available commands.", message_thread_id=update.message.message_thread_id) -async def caps(update: Update, context: ContextTypes.DEFAULT_TYPE): - """ - this is just a function to test that the bot is working as expected - """ - text_caps = ' '.join(context.args).upper() - print("chat_id: {}".format(update.effective_chat.id)) - print("message_thread_id: {}".format(update.message.message_thread_id)) - await context.bot.send_message(chat_id=update.effective_chat.id, text=text_caps, message_thread_id=update.message.message_thread_id) + async def caps(self, update: Update, context: ContextTypes.DEFAULT_TYPE): + """ + this is just a function to test that the bot is working as expected + """ + text_caps = ' '.join(context.args).upper() + print("chat_id: {}".format(update.effective_chat.id)) + print("message_thread_id: {}".format(update.message.message_thread_id)) + await context.bot.send_message(chat_id=update.effective_chat.id, text=text_caps, message_thread_id=update.message.message_thread_id) -async def router_iperf(update: Update, context: ContextTypes.DEFAULT_TYPE): + async def router_iperf(self, update: Update, context: ContextTypes.DEFAULT_TYPE): - time = context.args[0] if context.args else None - if not time: - time = 10 - async def log(msg): - await context.bot.send_message(chat_id=update.effective_chat.id, text=msg, message_thread_id=update.message.message_thread_id) + time = context.args[0] if context.args else None + if not time: + time = 10 - if update.effective_chat.id != int(SECRETS["TELEGRAM_LOG_CHAT_ID"]): - await log("++ can only start iperf test from Moonlight Bot group") - return + log_name = "moonlight-{:%m-%d-%Y}-{:%H-%M}-router-iperf.txt".format(date.today(), datetime.now()) + log_location = os.path.join(LOG_DIR_PATH, log_name) - await log("++ starting router iperf test with {} seconds per test".format(time)) - tester = CowmeshRouterIperfTester(log=log, seconds=time) - await tester.run_test() - await tester.output_results() + async def offline_log(msg): + with open(log_location, 'a') as log_file: + log_file.write(msg + "\n") + + async def log(msg): + await offline_log(msg) + await context.bot.send_message(chat_id=update.effective_chat.id, text=msg, + message_thread_id=update.message.message_thread_id) + + if update.effective_chat.id != int(SECRETS["TELEGRAM_LOG_CHAT_ID"]): + await log("++ can only start iperf test from Moonlight Bot group") + return + + await log("++ starting router iperf test with {} seconds per test".format(time)) + tester = CowmeshRouterIperfTester(log=log, time=time) + await tester.run_test() + await tester.output_results() + + # send log file + document = open(log_location, 'rb') + await context.bot.send_document(update.effective_chat.id, document, + message_thread_id=update.message.message_thread_id) + + async def pi_iperf(self, update: Update, context: ContextTypes.DEFAULT_TYPE): + + time = context.args[0] if context.args else None + if not time: + time = 10 + + log_name = "moonlight-{:%m-%d-%Y}-{:%H-%M}-pi-iperf.txt".format(date.today(), datetime.now()) + log_location = os.path.join(LOG_DIR_PATH, log_name) + + async def offline_log(msg): + with open(log_location, 'a') as log_file: + log_file.write(msg + "\n") + async def log(msg): + await offline_log(msg) + await context.bot.send_message(chat_id=update.effective_chat.id, text=msg, message_thread_id=update.message.message_thread_id) + + if update.effective_chat.id != int(SECRETS["TELEGRAM_LOG_CHAT_ID"]): + await log("++ can only start iperf test from Moonlight Bot group") + return + + await log("++ starting pi iperf test with {} seconds per test".format(time)) + tester = CowmeshPiIperfTester(log=log, time=time) + await tester.run_test() + await tester.output_results() + + # send log file + document = open(log_location, 'rb') + await context.bot.send_document(update.effective_chat.id, document, message_thread_id=update.message.message_thread_id) -async def pi_iperf(update: Update, context: ContextTypes.DEFAULT_TYPE): + async def speedtest(self, update: Update, context: ContextTypes.DEFAULT_TYPE): - time = context.args[0] if context.args else None - if not time: - time = 10 - async def log(msg): - await context.bot.send_message(chat_id=update.effective_chat.id, text=msg, message_thread_id=update.message.message_thread_id) + log_name = "moonlight-{:%m-%d-%Y}-{:%H-%M}-pi-speedtest.txt".format(date.today(), datetime.now()) + log_location = os.path.join(LOG_DIR_PATH, log_name) - if update.effective_chat.id != int(SECRETS["TELEGRAM_LOG_CHAT_ID"]): - await log("++ can only start iperf test from Moonlight Bot group") - return + async def offline_log(msg): + with open(log_location, 'a') as log_file: + log_file.write(msg + "\n") - await log("++ starting pi iperf test with {} seconds per test".format(time)) - tester = CowmeshPiIperfTester(log=log, time=time) - await tester.run_test() - await tester.output_results() + async def log(msg): + await offline_log(msg) + await context.bot.send_message(chat_id=update.effective_chat.id, text=msg, + message_thread_id=update.message.message_thread_id) + + if update.effective_chat.id != int(SECRETS["TELEGRAM_LOG_CHAT_ID"]): + await log("++ can only start test from Moonlight Bot group") + return + + await log("++ starting pi speedtest-cli speedtest") + tester = CowmeshPiSpeedtestTester(log=log) + await tester.run_test() + await tester.output_results() + + # send log file + document = open(log_location, 'rb') + await context.bot.send_document(update.effective_chat.id, document, + message_thread_id=update.message.message_thread_id) + + async def unknown(self, update: Update, context: ContextTypes.DEFAULT_TYPE): + await context.bot.send_message(chat_id=update.effective_chat.id, text="Sorry, I didn't understand that, please run /help for a list of available commands.", message_thread_id=update.message.message_thread_id) -async def speedtest(update: Update, context: ContextTypes.DEFAULT_TYPE): - - async def log(msg): - await context.bot.send_message(chat_id=update.effective_chat.id, text=msg, message_thread_id=update.message.message_thread_id) - - if update.effective_chat.id != int(SECRETS["TELEGRAM_LOG_CHAT_ID"]): - await log("++ can only start test from Moonlight Bot group") - return - - await log("++ starting pi speedtest-cli speedtest") - tester = CowmeshPiSpeedtestTester(log=log) - await tester.run_test() - await tester.output_results() + def about_message(self): + msg = "This is a bot designed to help measure the performance of a mesh network through active testing. " \ + "Every night the bot runs a network test using iperf to measure the connectivity between all the nodes in the mesh, " \ + "and logs the result to this channel. " \ + "Members of this channel can also initiate a new network iperf test at any time by sending a message to this channel, " \ + "with the command /iperf . " \ + "Telegram users outside of this channel cannot initiate a test, to help keep the network secure from being " \ + "overrun by malicious users. " \ + "The network test runs at night because that is when the fewest people are using the network, and so is more likely to " \ + "give consistent results with less random variability. " \ + "Please be mindful of initiating too many iperf tests during the day, as it uses a lot of network resources " \ + "to run the test and could interfere with the internet connections of people using the network. " + return msg -async def unknown(update: Update, context: ContextTypes.DEFAULT_TYPE): - await context.bot.send_message(chat_id=update.effective_chat.id, text="Sorry, I didn't understand that, please run /help for a list of available commands.", message_thread_id=update.message.message_thread_id) + def help_message(self): + msg = "This bot runs an iperf test every night and logs the results here. You can also initiate a new test using the command /iperf " \ + "or read a longer message explaining how this bot works by typing the command /readme." + return msg -def about_message(): - msg = "This is a bot designed to help measure the performance of a mesh network through active testing. " \ - "Every night the bot runs a network test using iperf to measure the connectivity between all the nodes in the mesh, " \ - "and logs the result to this channel. " \ - "Members of this channel can also initiate a new network iperf test at any time by sending a message to this channel, " \ - "with the command /iperf . " \ - "Telegram users outside of this channel cannot initiate a test, to help keep the network secure from being " \ - "overrun by malicious users. " \ - "The network test runs at night because that is when the fewest people are using the network, and so is more likely to " \ - "give consistent results with less random variability. " \ - "Please be mindful of initiating too many iperf tests during the day, as it uses a lot of network resources " \ - "to run the test and could interfere with the internet connections of people using the network. " - return msg + async def about(self, update: Update, context: ContextTypes.DEFAULT_TYPE): + text = self.about_message() + await context.bot.send_message(chat_id=update.effective_chat.id, text=text, message_thread_id=update.message.message_thread_id) -def help_message(): - msg = "This bot runs an iperf test every night and logs the results here. You can also initiate a new test using the command /iperf " \ - "or read a longer message explaining how this bot works by typing the command /readme." - return msg + async def help_fun(self, update: Update, context: ContextTypes.DEFAULT_TYPE): + text = self.help_message() + await context.bot.send_message(chat_id=update.effective_chat.id, text=text, message_thread_id=update.message.message_thread_id) + + async def send_log(self, bot, chat_id, message_thread_id, log_location): + # send log file + document = open(log_location, 'rb') + bot.send_document(chat_id, document, message_thread_id=message_thread_id) + + async def nightly_router_iperf(self, time=10): + token = SECRETS["TELEGRAM_TOKEN"] + application = ApplicationBuilder().token(token).build() + chat_id = SECRETS["TELEGRAM_LOG_CHAT_ID"] + message_thread_id = SECRETS.get("TELEGRAM_LOG_MESSAGE_THREAD_ID") + bot = application.bot + + log_name = "moonlight-{:%M-%d-%Y}-{:%H:%m}-router-iperf.txt".format(datetime.today(), datetime.now()) + log_location = os.path.join(LOG_DIR_PATH, log_name) + + async def offline_log(msg): + with open(log_location, 'a') as log_file: + log_file.write(msg) + + async def log(msg): + await offline_log(msg) + try: + await bot.send_message(chat_id=chat_id, text=msg, message_thread_id=message_thread_id) + except: + pass + + await log("☾☾ starting nightly router-to-router iperf test with {time} seconds per test".format(time=time)) + tester = CowmeshRouterIperfTester(log=log, time=time) + await tester.run_test() + await tester.output_results() + await self.send_log(bot=bot, log_location=log_location, chat_id=chat_id, message_thread_id=message_thread_id) -async def about(update: Update, context: ContextTypes.DEFAULT_TYPE): - text = about_message() - await context.bot.send_message(chat_id=update.effective_chat.id, text=text, message_thread_id=update.message.message_thread_id) + + async def nightly_pi_iperf(self, time=10): + token = SECRETS["TELEGRAM_TOKEN"] + application = ApplicationBuilder().token(token).build() + chat_id = SECRETS["TELEGRAM_LOG_CHAT_ID"] + message_thread_id = SECRETS.get("TELEGRAM_LOG_MESSAGE_THREAD_ID") + bot = application.bot -async def help_fun(update: Update, context: ContextTypes.DEFAULT_TYPE): - text = help_message() - await context.bot.send_message(chat_id=update.effective_chat.id, text=text, message_thread_id=update.message.message_thread_id) + log_name = "moonlight-{:%M-%d-%Y}-{:%H:%m}-pi-iperf.txt".format(datetime.today(), datetime.now()) + log_location = os.path.join(LOG_DIR_PATH, log_name) + + async def offline_log(msg): + with open(log_location, 'a') as log_file: + log_file.write(msg) + + async def log(msg): + await offline_log(msg) + try: + await bot.send_message(chat_id=chat_id, text=msg, message_thread_id=message_thread_id) + except: + pass + + await log("☾☾ starting nightly computer-to-computer iperf test with {} seconds per test".format(time)) + tester = CowmeshPiIperfTester(log=log, time=time) + await tester.run_test() + await tester.output_results() + await self.send_log(bot=bot, log_location=log_location, chat_id=chat_id, message_thread_id=message_thread_id) -async def nightly_router_iperf(time=10): - token = SECRETS["TELEGRAM_TOKEN"] - application = ApplicationBuilder().token(token).build() - chat_id = SECRETS["TELEGRAM_LOG_CHAT_ID"] - message_thread_id = SECRETS.get("TELEGRAM_LOG_MESSAGE_THREAD_ID") - bot = application.bot - async def log(msg): - await bot.send_message(chat_id=chat_id, text=msg, message_thread_id=message_thread_id) + async def nightly_pi_speedtest(self): + token = SECRETS["TELEGRAM_TOKEN"] + application = ApplicationBuilder().token(token).build() + chat_id = SECRETS["TELEGRAM_LOG_CHAT_ID"] + message_thread_id = SECRETS.get("TELEGRAM_LOG_MESSAGE_THREAD_ID") + bot = application.bot - await log("☾☾ starting nightly router-to-router iperf test with {} seconds per test") - tester = CowmeshRouterIperfTester(log=log, time=time) - await tester.run_test() - await tester.output_results() + log_name = "moonlight-{:%M-%d-%Y}-{:%H:%m}-pi-iperf.txt".format(datetime.today(), datetime.now()) + log_location = os.path.join(LOG_DIR_PATH, log_name) + + async def offline_log(msg): + with open(log_location, 'a') as log_file: + log_file.write(msg) + + async def log(msg): + await offline_log(msg) + try: + await bot.send_message(chat_id=chat_id, text=msg, message_thread_id=message_thread_id) + except: + pass + + await log("☾☾ starting nightly speedtest-cli speedtest") + tester = CowmeshPiSpeedtestTester(log=log) + await tester.run_test() + await tester.output_results() + await self.send_log(bot=bot, log_location=log_location, chat_id=chat_id, message_thread_id=message_thread_id) -async def nightly_pi_iperf(time=10): - token = SECRETS["TELEGRAM_TOKEN"] - application = ApplicationBuilder().token(token).build() - chat_id = SECRETS["TELEGRAM_LOG_CHAT_ID"] - message_thread_id = SECRETS.get("TELEGRAM_LOG_MESSAGE_THREAD_ID") - bot = application.bot - async def log(msg): - await bot.send_message(chat_id=chat_id, text=msg, message_thread_id=message_thread_id) + def init_bot_listener(self): + token = SECRETS["TELEGRAM_TOKEN"] + application = ApplicationBuilder().token(token).build() - await log("☾☾ starting nightly computer-to-computer iperf test with {} seconds per test".format(time)) - tester = CowmeshPiIperfTester(log=log, time=time) - await tester.run_test() - await tester.output_results() + start_handler = CommandHandler('start', self.start) + application.add_handler(start_handler) + caps_handler = CommandHandler('caps', self.caps) + application.add_handler(caps_handler) -async def nightly_pi_speedtest(): - token = SECRETS["TELEGRAM_TOKEN"] - application = ApplicationBuilder().token(token).build() - chat_id = SECRETS["TELEGRAM_LOG_CHAT_ID"] - message_thread_id = SECRETS.get("TELEGRAM_LOG_MESSAGE_THREAD_ID") - bot = application.bot + about_handler = CommandHandler('readme', self.about) + application.add_handler(about_handler) - async def log(msg): - await bot.send_message(chat_id=chat_id, text=msg, message_thread_id=message_thread_id) + help_handler = CommandHandler('help', self.help_fun) + application.add_handler(help_handler) - await log("☾☾ starting nightly speedtest-cli speedtest") - tester = CowmeshPiSpeedtestTester(log=log) - await tester.run_test() - await tester.output_results() + iperf_handler = CommandHandler('iperf', self.router_iperf) + application.add_handler(iperf_handler) + pi_iperf_handler = CommandHandler('pi_iperf', self.pi_iperf) + application.add_handler(pi_iperf_handler) -def init_bot_listener(): - token = SECRETS["TELEGRAM_TOKEN"] - application = ApplicationBuilder().token(token).build() + speedtest_handler = CommandHandler('speedtest', self.speedtest) + application.add_handler(speedtest_handler) - start_handler = CommandHandler('start', start) - application.add_handler(start_handler) + unknown_handler = MessageHandler(filters.COMMAND, self.unknown) + application.add_handler(unknown_handler) - caps_handler = CommandHandler('caps', caps) - application.add_handler(caps_handler) - - about_handler = CommandHandler('readme', about) - application.add_handler(about_handler) - - help_handler = CommandHandler('help', help_fun) - application.add_handler(help_handler) - - iperf_handler = CommandHandler('iperf', router_iperf) - application.add_handler(iperf_handler) - - pi_iperf_handler = CommandHandler('pi_iperf', pi_iperf) - application.add_handler(pi_iperf_handler) - - speedtest_handler = CommandHandler('speedtest', speedtest) - application.add_handler(speedtest_handler) - - - unknown_handler = MessageHandler(filters.COMMAND, unknown) - application.add_handler(unknown_handler) - - application.run_polling() + application.run_polling() if __name__ == '__main__': - init_bot_listener() \ No newline at end of file + tester = MoonlightTester() + tester.init_bot_listener() \ No newline at end of file diff --git a/nightly_test.py b/nightly_test.py index 72f0b15..66356f8 100644 --- a/nightly_test.py +++ b/nightly_test.py @@ -1,14 +1,15 @@ import argparse -from moonlight_analytics import nightly_router_iperf, nightly_pi_iperf, nightly_pi_speedtest +from moonlight_analytics import MoonlightTester import asyncio import sys if __name__ == '__main__': + tester = MoonlightTester() time = sys.argv[2] if len(sys.argv) > 2 else 10 if sys.argv[1] == "router": - asyncio.get_event_loop().run_until_complete(nightly_router_iperf(time=time)) + asyncio.get_event_loop().run_until_complete(tester.nightly_router_iperf(time=time)) elif sys.argv[1] == "pi": - asyncio.get_event_loop().run_until_complete(nightly_pi_iperf(time=time)) + asyncio.get_event_loop().run_until_complete(tester.nightly_pi_iperf(time=time)) elif sys.argv[1] == "speedtest": - asyncio.get_event_loop().run_until_complete(nightly_pi_speedtest()) \ No newline at end of file + asyncio.get_event_loop().run_until_complete(tester.nightly_pi_speedtest()) \ No newline at end of file