def create_runner(self, logger=None): self.settings_manager = Mock() self.clients_manager = ClientsManager({}) self.notifier_manager = NotifierManager(self.settings_manager, {}) # noinspection PyTypeChecker self.engine_runner = DBEngineRunner( Logger() if logger is None else logger, self.settings_manager, self.trackers_manager, self.clients_manager, self.notifier_manager)
def main(): def try_int(s, base=10, val=None): if s is None: return None try: return int(s, base) except ValueError: return val class Config(object): debug = False ip = '0.0.0.0' port = 6687 db_path = 'monitorrent.db' config = 'config.py' def __init__(self, parsed_args): if parsed_args.config is not None and not os.path.isfile(parsed_args.config): warnings.warn('File not found: {}'.format(parsed_args.config)) config_path = parsed_args.config or self.config if os.path.isfile(config_path): # noinspection PyBroadException try: parsed_config = {} with open(config_path) as config_file: six.exec_(compile(config_file.read(), config_path, 'exec'), {}, parsed_config) self.debug = parsed_config.get('debug', self.debug) self.ip = parsed_config.get('ip', self.ip) self.port = parsed_config.get('port', self.port) self.db_path = parsed_config.get('db_path', self.db_path) except: ex, val, tb = sys.exc_info() warnings.warn('Error reading: {0}: {1} ({2}'.format(parsed_args.config, ex, val)) env_debug = (os.environ.get('MONITORRENT_DEBUG', None) in ['true', 'True', '1']) self.debug = parsed_args.debug or env_debug or self.debug self.ip = parsed_args.ip or os.environ.get('MONITORRENT_IP', None) or self.ip self.port = parsed_args.port or try_int(os.environ.get('MONITORRENT_PORT', None)) or self.port self.db_path = parsed_args.db_path or os.environ.get('MONITORRENT_DB_PATH', None) or self.db_path parser = argparse.ArgumentParser(description='Monitorrent server') parser.add_argument('--debug', action='store_true', help='Run in debug mode. Secret key is always the same.') parser.add_argument('--ip', type=str, dest='ip', help='Bind interface. Default is {0}'.format(Config.ip)) parser.add_argument('--port', type=int, dest='port', help='Port for server. Default is {0}'.format(Config.port)) parser.add_argument('--db-path', type=str, dest='db_path', help='Path to SQL lite database. Default is to {0}'.format(Config.db_path)) parser.add_argument('--config', type=str, dest='config', default=os.environ.get('MONITORRENT_CONFIG', None), help='Path to config file (default {0})'.format(Config.config)) parsed_args = parser.parse_args() config = Config(parsed_args) db_connection_string = "sqlite:///" + config.db_path init_db_engine(db_connection_string, False) load_plugins() upgrade() create_db() settings_manager = SettingsManager() tracker_manager = TrackersManager(settings_manager, get_plugins('tracker')) clients_manager = DbClientsManager(settings_manager, get_plugins('client')) notifier_manager = NotifierManager(settings_manager, get_plugins('notifier')) log_manager = ExecuteLogManager() engine_runner_logger = DbLoggerWrapper(log_manager, settings_manager) engine_runner = DBEngineRunner(engine_runner_logger, settings_manager, tracker_manager, clients_manager, notifier_manager) include_prerelease = settings_manager.get_new_version_check_include_prerelease() new_version_checker = NewVersionChecker(notifier_manager, include_prerelease) if settings_manager.get_is_new_version_checker_enabled(): # noinspection PyBroadException try: new_version_checker.execute() except: pass new_version_checker.start(settings_manager.new_version_check_interval) debug = config.debug if debug: secret_key = 'Secret!' token = 'monitorrent' else: secret_key = os.urandom(24) token = ''.join(random.choice(string.ascii_letters) for _ in range(8)) app = create_app(secret_key, token, tracker_manager, clients_manager, notifier_manager, settings_manager, engine_runner, log_manager, new_version_checker) server_start_params = (config.ip, config.port) server = wsgi.Server(server_start_params, app) print('Server started on {0}:{1}'.format(*server_start_params)) try: server.start() except KeyboardInterrupt: engine_runner.stop() server.stop()
def create_runner(self, logger=None): self.clients_manager = ClientsManager({}) self.engine_runner = DBEngineRunner(Logger() if logger is None else logger, self.trackers_manager, self.clients_manager)
class DBEngineRunnerTest(DbTestCase, WithEngineRunnerTest): def setUp(self): super(DBEngineRunnerTest, self).setUp() self.create_trackers_manager() def create_runner(self, logger=None): self.clients_manager = ClientsManager({}) self.engine_runner = DBEngineRunner(Logger() if logger is None else logger, self.trackers_manager, self.clients_manager) @data(10, 200, 3600, 7200) def test_set_interval(self, value): self.create_runner() self.assertEqual(7200, self.engine_runner.interval) self.engine_runner.interval = value self.stop_runner() self.create_runner() self.assertEqual(value, self.engine_runner.interval) self.stop_runner() class TestDatetime(datetime): mock_now = None @classmethod def now(cls, tz=None): return cls.mock_now def test_get_last_execute(self): self.TestDatetime.mock_now = datetime.now(pytz.utc) with patch('monitorrent.engine.datetime', self.TestDatetime(2015, 8, 28)): self.create_runner() self.assertIsNone(self.engine_runner.last_execute) self.engine_runner.execute(None) sleep(0.1) self.stop_runner() self.create_runner() self.assertEqual(self.TestDatetime.mock_now, self.engine_runner.last_execute) self.stop_runner() @data(10, 200, 3600, 7200) @patch('monitorrent.engine.timer') def test_interval_set_should_update_timer_and_persisted_value(self, expected_value, create_timer_mock): # arrange cancel_mock = Mock() create_timer_mock.return_value = cancel_mock self.create_runner() # act self.engine_runner.interval = expected_value self.stop_runner() # assert self.assertEqual(2, create_timer_mock.call_count) self.assertEqual(2, cancel_mock.call_count) with DBSession() as db: settings = db.query(ExecuteSettings).first() self.assertEqual(settings.interval, expected_value) def test_last_execute_set_should_update_persisted_value(self): # arrange last_execute_expected = datetime.now(pytz.utc) self.create_runner() self.assertIsNone(self.engine_runner.last_execute) # act self.engine_runner.last_execute = last_execute_expected self.stop_runner() # assert with DBSession() as db: settings = db.query(ExecuteSettings).first() self.assertEqual(settings.last_execute, last_execute_expected) def test_manual_execute_shouldnt_reset_timeout_for_whole_execute(self): executed = Event() # noinspection PyUnusedLocal def execute(*args, **kwargs): executed.set() execute_mock = Mock(side_effect=execute) self.trackers_manager.execute = execute_mock with DBSession() as db: db.add(ExecuteSettings(interval=1, last_execute=None)) self.create_runner() sleep(0.5) # start manual self.engine_runner.execute([1, 2, 3]) executed.wait(0.3) executed.clear() sleep(0.5) executed.wait(0.3) self.assertTrue(executed.is_set) self.stop_runner() self.assertEqual(2, execute_mock.call_count)
class DBEngineRunnerTest(DbTestCase, WithEngineRunnerTest): def setUp(self): super(DBEngineRunnerTest, self).setUp() self.create_trackers_manager() def create_runner(self, logger=None): self.settings_manager = Mock() self.clients_manager = ClientsManager({}) self.notifier_manager = NotifierManager(self.settings_manager, {}) # noinspection PyTypeChecker self.engine_runner = DBEngineRunner( Logger() if logger is None else logger, self.settings_manager, self.trackers_manager, self.clients_manager, self.notifier_manager) @data(10, 200, 3600, 7200) def test_set_interval(self, value): self.create_runner() self.assertEqual(7200, self.engine_runner.interval) self.engine_runner.interval = value self.stop_runner() self.create_runner() self.assertEqual(value, self.engine_runner.interval) self.stop_runner() class TestDatetime(datetime): mock_now = None @classmethod def now(cls, tz=None): return cls.mock_now def test_get_last_execute(self): self.TestDatetime.mock_now = datetime.now(pytz.utc) with patch('monitorrent.engine.datetime', self.TestDatetime(2015, 8, 28)): self.create_runner() self.assertIsNone(self.engine_runner.last_execute) self.engine_runner.execute(None) sleep(0.1) self.stop_runner() self.create_runner() self.assertEqual(self.TestDatetime.mock_now, self.engine_runner.last_execute) self.stop_runner() @data(10, 200, 3600, 7200) @patch('monitorrent.engine.timer') def test_interval_set_should_update_timer_and_persisted_value( self, expected_value, create_timer_mock): # arrange cancel_mock = Mock() create_timer_mock.return_value = cancel_mock self.create_runner() # act self.engine_runner.interval = expected_value self.stop_runner() # assert self.assertEqual(2, create_timer_mock.call_count) self.assertEqual(2, cancel_mock.call_count) with DBSession() as db: settings = db.query(ExecuteSettings).first() self.assertEqual(settings.interval, expected_value) def test_last_execute_set_should_update_persisted_value(self): # arrange last_execute_expected = datetime.now(pytz.utc) self.create_runner() self.assertIsNone(self.engine_runner.last_execute) # act self.engine_runner.last_execute = last_execute_expected self.stop_runner() # assert with DBSession() as db: settings = db.query(ExecuteSettings).first() self.assertEqual(settings.last_execute, last_execute_expected) def test_manual_execute_shouldnt_reset_timeout_for_whole_execute(self): executed = Event() # noinspection PyUnusedLocal def execute(*args, **kwargs): executed.set() execute_mock = Mock(side_effect=execute) mock_tracker = Mock() mock_tracker.get_topics = Mock(return_value=[Topic()]) mock_tracker.execute = execute_mock self.trackers_manager.trackers = {'mock.tracker': mock_tracker} with DBSession() as db: db.add(ExecuteSettings(interval=1, last_execute=None)) self.create_runner() sleep(0.5) # start manual self.engine_runner.execute([1, 2, 3]) executed.wait(0.3) executed.clear() sleep(0.5) executed.wait(0.3) self.assertTrue(executed.is_set) self.stop_runner() self.assertEqual(2, execute_mock.call_count)
def test_get_last_execute(self): execute_mock = Mock() self.trackers_manager.execute = execute_mock clients_manager = ClientsManager({}) self.TestDatetime.mock_now = datetime.now(pytz.utc) with patch('monitorrent.engine.datetime', self.TestDatetime(2015, 8, 28)): engine_runner = DBEngineRunner(Logger(), self.trackers_manager, clients_manager) self.assertIsNone(engine_runner.last_execute) engine_runner.execute(None) sleep(0.1) engine_runner.stop() engine_runner.join(1) self.assertFalse(engine_runner.is_alive()) engine_runner = DBEngineRunner(Logger(), self.trackers_manager, clients_manager) self.assertEqual(self.TestDatetime.mock_now, engine_runner.last_execute) engine_runner.stop() engine_runner.join(1) self.assertFalse(engine_runner.is_alive())
def test_set_interval(self, value): execute_mock = Mock() self.trackers_manager.execute = execute_mock clients_manager = ClientsManager({}) engine_runner = DBEngineRunner(Logger(), self.trackers_manager, clients_manager) self.assertEqual(7200, engine_runner.interval) engine_runner.interval = value engine_runner.stop() engine_runner.join(1) self.assertFalse(engine_runner.is_alive()) engine_runner = DBEngineRunner(Logger(), self.trackers_manager, clients_manager) self.assertEqual(value, engine_runner.interval) engine_runner.stop() engine_runner.join(1) self.assertFalse(engine_runner.is_alive())
def main(): def try_int(s, base=10, val=None): if s is None: return None try: return int(s, base) except ValueError: return val class Config(object): debug = False ip = '0.0.0.0' port = 6687 db_path = 'monitorrent.db' config = 'config.py' def __init__(self, parsed_args): if parsed_args.config is not None and not os.path.isfile(parsed_args.config): warnings.warn('File not found: {}'.format(parsed_args.config)) config_path = parsed_args.config or self.config if os.path.isfile(config_path): # noinspection PyBroadException try: parsed_config = {} with open(config_path) as config_file: six.exec_(compile(config_file.read(), config_path, 'exec'), {}, parsed_config) self.debug = parsed_config.get('debug', self.debug) self.ip = parsed_config.get('ip', self.ip) self.port = parsed_config.get('port', self.port) self.db_path = parsed_config.get('db_path', self.db_path) except: ex, val, tb = sys.exc_info() warnings.warn('Error reading: {0}: {1} ({2}'.format(parsed_args.config, ex, val)) env_debug = (os.environ.get('MONITORRENT_DEBUG', None) in ['true', 'True', '1']) self.debug = parsed_args.debug or env_debug or self.debug self.ip = parsed_args.ip or os.environ.get('MONITORRENT_IP', None) or self.ip self.port = parsed_args.port or try_int(os.environ.get('MONITORRENT_PORT', None)) or self.port self.db_path = parsed_args.db_path or os.environ.get('MONITORRENT_DB_PATH', None) or self.db_path parser = argparse.ArgumentParser(description='Monitorrent server') parser.add_argument('--debug', action='store_true', help='Run in debug mode. Secret key is always the same.') parser.add_argument('--ip', type=str, dest='ip', help='Bind interface. Default is {0}'.format(Config.ip)) parser.add_argument('--port', type=int, dest='port', help='Port for server. Default is {0}'.format(Config.port)) parser.add_argument('--db-path', type=str, dest='db_path', help='Path to SQL lite database. Default is to {0}'.format(Config.db_path)) parser.add_argument('--config', type=str, dest='config', default=os.environ.get('MONITORRENT_CONFIG', None), help='Path to config file (default {0})'.format(Config.config)) parsed_args = parser.parse_args() config = Config(parsed_args) db_connection_string = "sqlite:///" + config.db_path init_db_engine(db_connection_string, False) load_plugins() upgrade() create_db() settings_manager = SettingsManager() tracker_manager = TrackersManager(settings_manager.tracker_settings, get_plugins('tracker')) clients_manager = DbClientsManager(get_plugins('client'), settings_manager) notifier_manager = NotifierManager(get_plugins('notifier')) log_manager = ExecuteLogManager() engine_runner_logger = DbLoggerWrapper(None, log_manager, settings_manager) engine_runner = DBEngineRunner(engine_runner_logger, tracker_manager, clients_manager) debug = config.debug if debug: secret_key = 'Secret!' token = 'monitorrent' else: secret_key = os.urandom(24) token = ''.join(random.choice(string.ascii_letters) for _ in range(8)) app = create_app(secret_key, token, tracker_manager, clients_manager, notifier_manager, settings_manager, engine_runner, log_manager) d = wsgiserver.WSGIPathInfoDispatcher({'/': app}) server_start_params = (config.ip, config.port) server = wsgiserver.CherryPyWSGIServer(server_start_params, d) print('Server started on {0}:{1}'.format(*server_start_params)) try: server.start() except KeyboardInterrupt: engine_runner.stop() server.stop()