forked from p15670423/monkey
Fixed bugs regarding waiting for monkeys to die, readability improvements
This commit is contained in:
parent
91fe7c22a8
commit
018d3ddc08
|
@ -0,0 +1,17 @@
|
|||
LOG_INIT_MESSAGE = "Analysis didn't run."
|
||||
|
||||
|
||||
class AnalyzerLog(object):
|
||||
|
||||
def __init__(self, analyzer_name):
|
||||
self.contents = LOG_INIT_MESSAGE
|
||||
self.name = analyzer_name
|
||||
|
||||
def clear(self):
|
||||
self.contents = ""
|
||||
|
||||
def add_entry(self, message):
|
||||
self.contents = "{}\n{}".format(self.contents, message)
|
||||
|
||||
def get_contents(self):
|
||||
return "{}: {}\n".format(self.name, self.contents)
|
|
@ -1,4 +1,4 @@
|
|||
LOG_INIT_MESSAGE = "Analysis didn't run."
|
||||
from envs.monkey_zoo.blackbox.analyzers.analyzer_log import AnalyzerLog
|
||||
|
||||
|
||||
class CommunicationAnalyzer(object):
|
||||
|
@ -10,29 +10,15 @@ class CommunicationAnalyzer(object):
|
|||
|
||||
def analyze_test_results(self):
|
||||
self.log.clear()
|
||||
all_monkeys_communicated = True
|
||||
for machine_ip in self.machine_ips:
|
||||
if not self.did_monkey_communicate_back(machine_ip):
|
||||
self.log.add_entry("Monkey from {} didn't communicate back".format(machine_ip))
|
||||
return False
|
||||
self.log.add_entry("Monkey from {} communicated back".format(machine_ip))
|
||||
return True
|
||||
all_monkeys_communicated = False
|
||||
else:
|
||||
self.log.add_entry("Monkey from {} communicated back".format(machine_ip))
|
||||
return all_monkeys_communicated
|
||||
|
||||
def did_monkey_communicate_back(self, machine_ip):
|
||||
query = {'ip_addresses': {'$elemMatch': {'$eq': machine_ip}}}
|
||||
return len(self.island_client.find_monkeys_in_db(query)) > 0
|
||||
|
||||
|
||||
class AnalyzerLog(object):
|
||||
|
||||
def __init__(self, analyzer_name):
|
||||
self.contents = LOG_INIT_MESSAGE
|
||||
self.name = analyzer_name
|
||||
|
||||
def clear(self):
|
||||
self.contents = ""
|
||||
|
||||
def add_entry(self, message):
|
||||
self.contents = "{}\n{}".format(self.contents, message)
|
||||
|
||||
def get_contents(self):
|
||||
return "{}: {}\n".format(self.name, self.contents)
|
||||
|
|
|
@ -82,5 +82,5 @@ class MonkeyIslandClient(object):
|
|||
return json.loads(response.content)['results']
|
||||
|
||||
def is_all_monkeys_dead(self):
|
||||
query = {'dead': 'false'}
|
||||
query = {'dead': False}
|
||||
return len(self.find_monkeys_in_db(query)) == 0
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import re
|
||||
|
||||
|
||||
class LogParser(object):
|
||||
|
||||
def __init__(self, log_path):
|
||||
self.log_path = log_path
|
||||
self.log_contents = self.read_log()
|
||||
|
||||
def read_log(self):
|
||||
with open(self.log_path, 'r') as log:
|
||||
return log.read()
|
||||
|
||||
def print_errors(self):
|
||||
print("Errors:")
|
||||
for error_line in LogParser.get_errors(self.log_contents):
|
||||
print(error_line)
|
||||
|
||||
@staticmethod
|
||||
def get_errors(log_contents):
|
||||
searcher = re.compile(r"^.*:ERROR].*$", re.MULTILINE)
|
||||
return searcher.findall(log_contents)
|
||||
|
||||
def print_warnings(self):
|
||||
print("Warnings:")
|
||||
for warning_line in LogParser.get_warnings(self.log_contents):
|
||||
print(warning_line)
|
||||
|
||||
@staticmethod
|
||||
def get_warnings(log_contents):
|
||||
searcher = re.compile(r"^.*:WARNING].*$", re.MULTILINE)
|
||||
return searcher.findall(log_contents)
|
|
@ -0,0 +1,22 @@
|
|||
from envs.monkey_zoo.blackbox.log_handlers.monkey_log import MonkeyLog
|
||||
|
||||
|
||||
class LogsDownloader(object):
|
||||
|
||||
def __init__(self, island_client, log_dir_path):
|
||||
self.island_client = island_client
|
||||
self.log_dir_path = log_dir_path
|
||||
self.monkey_log_paths = []
|
||||
|
||||
def download_monkey_logs(self):
|
||||
print("Downloading each monkey log.")
|
||||
all_monkeys = self.island_client.find_monkeys_in_db(None)
|
||||
for monkey in all_monkeys:
|
||||
downloaded_log_path = self._download_monkey_log(monkey)
|
||||
if downloaded_log_path:
|
||||
self.monkey_log_paths.append(downloaded_log_path)
|
||||
|
||||
def _download_monkey_log(self, monkey):
|
||||
log_handler = MonkeyLog(monkey, self.log_dir_path)
|
||||
download_successful = log_handler.download_log(self.island_client)
|
||||
return log_handler.get_log_path_for_monkey(monkey) if download_successful else None
|
|
@ -12,8 +12,10 @@ class MonkeyLog(object):
|
|||
log = island_client.find_log_in_db({'monkey_id': ObjectId(self.monkey['id'])})
|
||||
if not log:
|
||||
print("Log for monkey {} not found".format(self.monkey['ip_addresses'][0]))
|
||||
return False
|
||||
else:
|
||||
self.write_log_to_file(log)
|
||||
return True
|
||||
|
||||
def write_log_to_file(self, log):
|
||||
with open(self.get_log_path_for_monkey(self.monkey), 'w') as log_file:
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import os
|
||||
import shutil
|
||||
|
||||
from envs.monkey_zoo.blackbox.log_handlers.monkey_log import MonkeyLog
|
||||
from envs.monkey_zoo.blackbox.log_handlers.log_parser import LogParser
|
||||
from envs.monkey_zoo.blackbox.log_handlers.logs_downloader import LogsDownloader
|
||||
|
||||
LOG_DIR_NAME = 'logs'
|
||||
|
||||
|
@ -12,12 +13,18 @@ class TestLogsHandler(object):
|
|||
self.island_client = island_client
|
||||
self.log_dir_path = os.path.join(TestLogsHandler.get_log_dir_path(), self.test_name)
|
||||
|
||||
def parse_test_logs(self):
|
||||
log_paths = self.download_logs()
|
||||
if not log_paths:
|
||||
print("No logs were downloaded, maybe no monkeys were ran?")
|
||||
return
|
||||
TestLogsHandler.parse_logs(log_paths)
|
||||
|
||||
def download_logs(self):
|
||||
self.try_create_log_dir_for_test()
|
||||
print("Downloading logs")
|
||||
all_monkeys = self.island_client.find_monkeys_in_db(None)
|
||||
for monkey in all_monkeys:
|
||||
MonkeyLog(monkey, self.log_dir_path).download_log(self.island_client)
|
||||
downloader = LogsDownloader(self.island_client, self.log_dir_path)
|
||||
downloader.download_monkey_logs()
|
||||
return downloader.monkey_log_paths
|
||||
|
||||
def try_create_log_dir_for_test(self):
|
||||
try:
|
||||
|
@ -33,3 +40,11 @@ class TestLogsHandler(object):
|
|||
def delete_log_folder_contents():
|
||||
shutil.rmtree(TestLogsHandler.get_log_dir_path(), ignore_errors=True)
|
||||
os.mkdir(TestLogsHandler.get_log_dir_path())
|
||||
|
||||
@staticmethod
|
||||
def parse_logs(log_paths):
|
||||
for log_path in log_paths:
|
||||
print("Info from log at {}".format(log_path))
|
||||
log_parser = LogParser(log_path)
|
||||
log_parser.print_errors()
|
||||
log_parser.print_warnings()
|
|
@ -6,7 +6,7 @@ from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import Communicat
|
|||
from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser
|
||||
from envs.monkey_zoo.blackbox.utils import gcp_machine_handlers
|
||||
from envs.monkey_zoo.blackbox.tests.basic_test import BasicTest
|
||||
from envs.monkey_zoo.blackbox.log_handlers.test_logs import TestLogsHandler
|
||||
from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import TestLogsHandler
|
||||
|
||||
DEFAULT_TIMEOUT_SECONDS = 4*60
|
||||
MACHINE_BOOTUP_WAIT_SECONDS = 30
|
||||
|
@ -53,7 +53,7 @@ class TestMonkeyBlackbox(object):
|
|||
analyzer = CommunicationAnalyzer(island_client, config_parser.get_ips_of_targets())
|
||||
BasicTest(test_name,
|
||||
island_client,
|
||||
config_parser.config_raw,
|
||||
config_parser,
|
||||
[analyzer],
|
||||
timeout_in_seconds).run()
|
||||
|
||||
|
|
|
@ -1,35 +1,42 @@
|
|||
from time import sleep
|
||||
|
||||
from envs.monkey_zoo.blackbox.utils.test_timer import TestTimer
|
||||
from envs.monkey_zoo.blackbox.log_handlers.test_logs import TestLogsHandler
|
||||
from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import TestLogsHandler
|
||||
|
||||
MAX_TIME_FOR_MONKEYS_TO_DIE = 5*60
|
||||
WAIT_TIME_BETWEEN_REQUESTS = 10
|
||||
TIME_FOR_MONKEY_PROCESS_TO_FINISH = 20
|
||||
|
||||
|
||||
class BasicTest(object):
|
||||
|
||||
def __init__(self, name, island_client, island_config, analyzers, timeout):
|
||||
def __init__(self, name, island_client, config_parser, analyzers, timeout):
|
||||
self.name = name
|
||||
self.island_client = island_client
|
||||
self.island_config = island_config
|
||||
self.config_parser = config_parser
|
||||
self.analyzers = analyzers
|
||||
self.timeout = timeout
|
||||
|
||||
def run(self):
|
||||
self.island_client.import_config(self.island_config)
|
||||
self.island_client.import_config(self.config_parser.config_raw)
|
||||
self.print_test_starting_info()
|
||||
try:
|
||||
self.island_client.run_monkey_local()
|
||||
self.test_until_timeout()
|
||||
except AssertionError:
|
||||
print("Test {} failed. Downloading logs of all monkeys.".format(self.name))
|
||||
TestLogsHandler(self.name, self.island_client).download_logs()
|
||||
raise
|
||||
finally:
|
||||
self.island_client.kill_all_monkeys()
|
||||
self.wait_until_monkeys_die()
|
||||
self.wait_for_monkey_process_to_finish()
|
||||
self.parse_logs()
|
||||
self.island_client.reset_env()
|
||||
|
||||
def print_test_starting_info(self):
|
||||
print("Started {} test".format(self.name))
|
||||
print("Machines participating in test:")
|
||||
for target_ip in self.config_parser.get_ips_of_targets():
|
||||
print(" "+target_ip)
|
||||
print("")
|
||||
|
||||
def test_until_timeout(self):
|
||||
timer = TestTimer(self.timeout)
|
||||
while not timer.timed_out():
|
||||
|
@ -68,3 +75,11 @@ class BasicTest(object):
|
|||
if time_passed > MAX_TIME_FOR_MONKEYS_TO_DIE:
|
||||
print("Some monkeys didn't die after the test, passing")
|
||||
assert False
|
||||
|
||||
def parse_logs(self):
|
||||
print("\nParsing test logs:")
|
||||
TestLogsHandler(self.name, self.island_client).parse_test_logs()
|
||||
|
||||
@staticmethod
|
||||
def wait_for_monkey_process_to_finish():
|
||||
sleep(TIME_FOR_MONKEY_PROCESS_TO_FINISH)
|
||||
|
|
Loading…
Reference in New Issue