def test_is_new_version_checker_enabled(self, include_prerelease, enabled, interval): with patch('monitorrent.settings_manager.SettingsManager.new_version_check_interval', new_callable=PropertyMock) as new_version_check_interval_mock: new_version_check_interval_mock.return_value = interval settings_manager = SettingsManager() get_is_new_version_checker_enabled_mock = Mock(return_value=enabled) get_new_version_check_include_prerelease_mock = Mock(return_value=include_prerelease) settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled_mock settings_manager.get_new_version_check_include_prerelease = get_new_version_check_include_prerelease_mock new_version_checker = NewVersionChecker(False) new_version_checker.execute = Mock() settings_new_version_checker = SettingsNewVersionChecker(settings_manager, new_version_checker) self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker) body = self.simulate_request("/api/settings/new_version_checker", decode='utf-8') self.assertEqual(self.srmock.status, falcon.HTTP_OK) self.assertTrue('application/json' in self.srmock.headers_dict['Content-Type']) result = json.loads(body) expected = {'include_prerelease': include_prerelease, 'enabled': enabled, 'interval': interval} self.assertEqual(result, expected) get_is_new_version_checker_enabled_mock.assert_called_once_with() get_new_version_check_include_prerelease_mock.assert_called_once_with() new_version_check_interval_mock.assert_called_once_with()
def test_patch_test(self, patch_include_prerelease, patch_enabled, patch_interval, update_include_prerelease, update_enabled, update_interval): with patch('monitorrent.settings_manager.SettingsManager.new_version_check_interval', new_callable=PropertyMock) as new_version_check_interval_mock: new_version_check_interval_mock.return_value = 4000 settings_manager = SettingsManager() settings_manager.get_new_version_check_include_prerelease = Mock(return_value=False) settings_manager.set_new_version_check_include_prerelease = Mock() settings_manager.get_is_new_version_checker_enabled = Mock(return_value=True) settings_manager.set_is_new_version_checker_enabled = Mock() settings_manager.new_version_check_interval = PropertyMock(return_value=3600) new_version_checker = NewVersionChecker(False) update_mock = Mock() new_version_checker.update = update_mock settings_new_version_checker = SettingsNewVersionChecker(settings_manager, new_version_checker) self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker) request = dict() if patch_include_prerelease is not None: request['include_prerelease'] = patch_include_prerelease if patch_enabled is not None: request['enabled'] = patch_enabled if patch_interval is not None: request['interval'] = patch_interval self.simulate_request('/api/settings/new_version_checker', method="PATCH", body=json.dumps(request)) self.assertEqual(self.srmock.status, falcon.HTTP_NO_CONTENT) update_mock.assert_called_once_with(update_include_prerelease, update_enabled, update_interval)
def test_new_public_version_url(self, version): checker = NewVersionChecker(False) with patch('monitorrent.new_version_checker.monitorrent', create=True) as version_mock: version_mock.__version__ = version checker.execute() self.assertEqual('https://github.com/werwolfby/monitorrent/releases/tag/1.0.2', checker.new_version_url)
def test_get_latest_release_with_error_tag_success(self, mocker): """ :type mocker: Mocker """ checker = NewVersionChecker(Mock(), True) mocker.get( 'https://api.github.com/repos/werwolfby/monitorrent/releases', text=self.read_httpretty_content('github.com_releases.json', encoding='utf-8')) self.assertEqual('1.1.0-rc.4', checker.get_latest_release())
def test_update(self, include_prerelease, is_started, start_interval, enabled, interval, start_called, stop_called): checker = NewVersionChecker(Mock(), False) def start_side_effect(i): checker.interval = i start_mock = Mock(side_effect=start_side_effect) stop_mock = Mock() is_started_mock = Mock(return_value=is_started) checker.interval = start_interval checker.start = start_mock checker.stop = stop_mock checker.is_started = is_started_mock checker.update(include_prerelease, enabled, interval) self.assertEqual(checker.interval, interval) self.assertEqual(checker.include_prereleases, include_prerelease) if start_called: start_mock.assert_called_once_with(interval) else: start_mock.assert_not_called() if stop_called: stop_mock.assert_called_once() else: stop_mock.assert_not_called()
def test_get_url(self, url): new_version_checker = NewVersionChecker(False) new_version_resource = NewVersion(new_version_checker) new_version_checker.new_version_url = url self.api.add_route('/api/new_version', new_version_resource) body = self.simulate_request("/api/new_version", decode='utf-8') self.assertEqual(self.srmock.status, falcon.HTTP_OK) self.assertTrue('application/json' in self.srmock.headers_dict['Content-Type']) result = json.loads(body) self.assertEqual(result, {'url': url})
def test_get_url(self, url): new_version_checker = NewVersionChecker(Mock(), False) new_version_resource = NewVersion(new_version_checker) new_version_checker.new_version_url = url self.api.add_route('/api/new_version', new_version_resource) body = self.simulate_request("/api/new_version", decode='utf-8') self.assertEqual(self.srmock.status, falcon.HTTP_OK) self.assertTrue('application/json' in self.srmock.headers_dict['Content-Type']) result = json.loads(body) self.assertEqual(result, {'url': url})
def test_start_twice_should_raise(self): checker = NewVersionChecker(Mock(), False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(10) with self.assertRaises(Exception): checker.start(10) checker.stop() execute_mock.assert_not_called()
def test_is_started(self): checker = NewVersionChecker(Mock(), False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(10) self.assertTrue(checker.is_started()) checker.stop() self.assertFalse(checker.is_started()) execute_mock.assert_not_called()
def test_update(self, include_prerelease, is_started, start_interval, enabled, interval, start_called, stop_called): checker = NewVersionChecker(False) def start_side_effect(i): checker.interval = i start_mock = Mock(side_effect=start_side_effect) stop_mock = Mock() is_started_mock = Mock(return_value=is_started) checker.interval = start_interval checker.start = start_mock checker.stop = stop_mock checker.is_started = is_started_mock checker.update(include_prerelease, enabled, interval) self.assertEqual(checker.interval, interval) self.assertEqual(checker.include_prereleases, include_prerelease) if start_called: start_mock.assert_called_once_with(interval) else: start_mock.assert_not_called() if stop_called: stop_mock.assert_called_once() else: stop_mock.assert_not_called()
def test_bad_request(self, body): with patch('monitorrent.settings_manager.SettingsManager.new_version_check_interval', new_callable=PropertyMock) as new_version_check_interval_mock: new_version_check_interval_mock.return_value = 4000 settings_manager = SettingsManager() get_is_new_version_checker_enabled = Mock() settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled new_version_checker = NewVersionChecker(False) new_version_checker.execute = Mock() settings_new_version_checker = SettingsNewVersionChecker(settings_manager, new_version_checker) self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker) self.simulate_request("/api/settings/new_version_checker", method="PATCH", body=json.dumps(body) if body else None) self.assertEqual(self.srmock.status, falcon.HTTP_BAD_REQUEST)
def test_patch_test(self, patch_include_prerelease, patch_enabled, patch_interval, update_include_prerelease, update_enabled, update_interval): with patch( 'monitorrent.settings_manager.SettingsManager.new_version_check_interval', new_callable=PropertyMock) as new_version_check_interval_mock: new_version_check_interval_mock.return_value = 4000 settings_manager = SettingsManager() settings_manager.get_new_version_check_include_prerelease = Mock( return_value=False) settings_manager.set_new_version_check_include_prerelease = Mock() settings_manager.get_is_new_version_checker_enabled = Mock( return_value=True) settings_manager.set_is_new_version_checker_enabled = Mock() settings_manager.new_version_check_interval = PropertyMock( return_value=3600) new_version_checker = NewVersionChecker(Mock(), False) update_mock = Mock() new_version_checker.update = update_mock settings_new_version_checker = SettingsNewVersionChecker( settings_manager, new_version_checker) self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker) request = dict() if patch_include_prerelease is not None: request['include_prerelease'] = patch_include_prerelease if patch_enabled is not None: request['enabled'] = patch_enabled if patch_interval is not None: request['interval'] = patch_interval self.simulate_request('/api/settings/new_version_checker', method="PATCH", body=json.dumps(request)) self.assertEqual(self.srmock.status, falcon.HTTP_NO_CONTENT) update_mock.assert_called_once_with(update_include_prerelease, update_enabled, update_interval)
def test_is_started(self): checker = NewVersionChecker(False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(10) self.assertTrue(checker.is_started()) checker.stop() self.assertFalse(checker.is_started()) execute_mock.assert_not_called()
def test_is_new_version_checker_enabled(self, include_prerelease, enabled, interval): with patch( 'monitorrent.settings_manager.SettingsManager.new_version_check_interval', new_callable=PropertyMock) as new_version_check_interval_mock: new_version_check_interval_mock.return_value = interval settings_manager = SettingsManager() get_is_new_version_checker_enabled_mock = Mock( return_value=enabled) get_new_version_check_include_prerelease_mock = Mock( return_value=include_prerelease) settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled_mock settings_manager.get_new_version_check_include_prerelease = get_new_version_check_include_prerelease_mock new_version_checker = NewVersionChecker(Mock(), False) new_version_checker.execute = Mock() settings_new_version_checker = SettingsNewVersionChecker( settings_manager, new_version_checker) self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker) body = self.simulate_request("/api/settings/new_version_checker", decode='utf-8') self.assertEqual(self.srmock.status, falcon.HTTP_OK) self.assertTrue( 'application/json' in self.srmock.headers_dict['Content-Type']) result = json.loads(body) expected = { 'include_prerelease': include_prerelease, 'enabled': enabled, 'interval': interval } self.assertEqual(result, expected) get_is_new_version_checker_enabled_mock.assert_called_once_with() get_new_version_check_include_prerelease_mock.assert_called_once_with( ) new_version_check_interval_mock.assert_called_once_with()
def test_start_twice_should_raise(self): checker = NewVersionChecker(False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(10) with self.assertRaises(Exception): checker.start(10) checker.stop() execute_mock.assert_not_called()
def test_new_public_version_url(self, version): notifier_manager_execute = MagicMock() notifier_manager_execute.notify = Mock() notifier_manager_execute.__enter__ = Mock( return_value=notifier_manager_execute) notifier_manager = Mock() notifier_manager.execute = Mock(name="notifier_manager.execute123", return_value=notifier_manager_execute) checker = NewVersionChecker(notifier_manager, False) with patch('monitorrent.new_version_checker.monitorrent', create=True) as version_mock: version_mock.__version__ = version checker.execute() self.assertEqual( 'https://github.com/werwolfby/monitorrent/releases/tag/1.0.2', checker.new_version_url) notifier_manager_execute.notify.assert_called_once()
def test_new_public_version_notify_second_time_after_version_change( self, mocker): notifier_manager_execute = MagicMock() notifier_manager_execute.notify = Mock() notifier_manager_execute.__enter__ = Mock( return_value=notifier_manager_execute) notifier_manager = Mock() notifier_manager.execute = Mock(name="notifier_manager.execute123", return_value=notifier_manager_execute) # noinspection PyTypeChecker checker = NewVersionChecker(notifier_manager, False) with patch('monitorrent.new_version_checker.monitorrent', create=True) as version_mock: version_mock.__version__ = "1.0.0" mocker.get( 'https://api.github.com/repos/werwolfby/monitorrent/releases', text=self.read_httpretty_content('github.com_releases.json', encoding='utf-8')) checker.execute() assert 'https://github.com/werwolfby/monitorrent/releases/tag/1.0.2' == checker.new_version_url notifier_manager_execute.notify.assert_called_once() notify_message = notifier_manager_execute.notify.mock_calls[0][1][ 0] assert "1.0.2" in notify_message assert 'https://github.com/werwolfby/monitorrent/releases/tag/1.0.2' in notify_message checker.execute() notifier_manager_execute.notify.assert_called_once() notifier_manager_execute.notify.reset_mock() mocker.get( 'https://api.github.com/repos/werwolfby/monitorrent/releases', text=self.read_httpretty_content('github.com_releases_2.json', encoding='utf-8')) checker.execute() self.assertEqual( 'https://github.com/werwolfby/monitorrent/releases/tag/1.1.1', checker.new_version_url) notifier_manager_execute.notify.assert_called_once() notify_message = notifier_manager_execute.notify.mock_calls[0][1][ 0] assert "1.1.1" in notify_message assert 'https://github.com/werwolfby/monitorrent/releases/tag/1.1.1' in notify_message
def test_timer_stop_dont_call_execute(self): checker = NewVersionChecker(Mock(), False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(1) checker.stop() execute_mock.assert_not_called() self.assertLess(execute_mock.call_count, 4)
def test_bad_request(self, body): with patch( 'monitorrent.settings_manager.SettingsManager.new_version_check_interval', new_callable=PropertyMock) as new_version_check_interval_mock: new_version_check_interval_mock.return_value = 4000 settings_manager = SettingsManager() get_is_new_version_checker_enabled = Mock() settings_manager.get_is_new_version_checker_enabled = get_is_new_version_checker_enabled new_version_checker = NewVersionChecker(Mock(), False) new_version_checker.execute = Mock() settings_new_version_checker = SettingsNewVersionChecker( settings_manager, new_version_checker) self.api.add_route('/api/settings/new_version_checker', settings_new_version_checker) self.simulate_request("/api/settings/new_version_checker", method="PATCH", body=json.dumps(body) if body else None) self.assertEqual(self.srmock.status, falcon.HTTP_BAD_REQUEST)
def test_timer_stop_dont_call_execute(self): checker = NewVersionChecker(False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(1) checker.stop() execute_mock.assert_not_called() self.assertLess(execute_mock.call_count, 4)
def test_timer_calls(self): checker = NewVersionChecker(Mock(), False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(0.1) sleep(0.3) checker.stop() self.assertGreaterEqual(execute_mock.call_count, 2) self.assertLess(execute_mock.call_count, 4) sleep(0.3) self.assertLess(execute_mock.call_count, 4)
def test_timer_calls(self): checker = NewVersionChecker(False) execute_mock = Mock(return_value=True) checker.execute = execute_mock checker.start(0.1) sleep(0.3) checker.stop() self.assertGreaterEqual(execute_mock.call_count, 2) self.assertLess(execute_mock.call_count, 4) sleep(0.3) self.assertLess(execute_mock.call_count, 4)
def test_get_latest_public_release(self): checker = NewVersionChecker(Mock(), False) self.assertEqual('1.0.2', checker.get_latest_release())
def test_get_latest_prerelease_release(self): checker = NewVersionChecker(Mock(), True) self.assertEqual('1.1.0-rc.1.1', checker.get_latest_release())
def test_get_latest_prerelease_release(self): checker = NewVersionChecker(True) self.assertEqual('1.1.0-rc.1.1', checker.get_latest_release())
def test_get_latest_public_release(self): checker = NewVersionChecker(False) self.assertEqual('1.0.2', checker.get_latest_release())
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 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(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) new_version_checker = NewVersionChecker(settings_manager.get_new_version_check_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) 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()