def test_no_config_folder(self): test_utils.cleanup() schedule_service = ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) self.assertEqual(schedule_service._scheduled_executions, {}) self.assertEqual('1', schedule_service._id_generator.next_id())
def test_restore_configs_when_one_corrupted(self): job1 = create_job(id='11', repeatable=None) job2 = create_job(id=3) self.save_job(job1) self.save_job(job2) schedule_service = ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) self.assertSetEqual({'3'}, set(schedule_service._scheduled_executions.keys())) self.assertEqual('12', schedule_service._id_generator.next_id())
def test_schedule_on_restore_when_repeatable_in_past(self): job = create_job(id=3, repeatable=True, start_datetime=mocked_now + timedelta(days=2)) self.save_job(job) ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) self.assert_schedule_calls([(job, mocked_now_epoch + 1468800)])
def test_schedule_on_restore_when_one_time_in_past(self): job = create_job(id=3, repeatable=False, start_datetime=mocked_now - timedelta(seconds=1)) self.save_job(job) ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) self.assert_schedule_calls([])
def test_schedule_on_restore_when_one_time(self): job = create_job(id=3, repeatable=False, start_datetime=mocked_now + timedelta(minutes=3)) self.save_job(job) ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) self.assert_schedule_calls([(job, mocked_now_epoch + 180)])
def test_restore_multiple_configs(self): job1 = create_job(id='11') job2 = create_job(id=9) job3 = create_job(id=3) self.save_job(job1) self.save_job(job2) self.save_job(job3) schedule_service = ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) self.assertSetEqual({'3', '9', '11'}, set(schedule_service._scheduled_executions.keys())) self.assertEqual('12', schedule_service._id_generator.next_id())
def setUp(self) -> None: super().setUp() self.patcher = patch('sched.scheduler') self.scheduler_mock = MagicMock() self.patcher.start().return_value = self.scheduler_mock schedule_service._sleep = MagicMock() schedule_service._sleep.side_effect = lambda x: time.sleep(0.001) self.unschedulable_scripts = set() self.config_service = MagicMock() self.config_service.load_config_model.side_effect = lambda name, b, c: test_utils.create_config_model( name, schedulable=name not in self.unschedulable_scripts) self.execution_service = MagicMock() self.schedule_service = ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) date_utils._mocked_now = mocked_now test_utils.setup()
def setUp(self) -> None: super().setUp() test_utils.setup() self.patcher = patch('sched.scheduler') self.scheduler_mock = MagicMock() self.patcher.start().return_value = self.scheduler_mock schedule_service._sleep = MagicMock() schedule_service._sleep.side_effect = lambda x: time.sleep(0.001) self.config_service = ConfigService(AnyUserAuthorizer(), test_utils.temp_folder) self.create_config('my_script_A') self.create_config('unschedulable-script', scheduling_enabled=False) self.execution_service = MagicMock() self.schedule_service = ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) date_utils._mocked_now = mocked_now
class ScheduleServiceTestCase(TestCase): def assert_schedule_calls(self, expected_job_time_pairs): self.assertEqual(len(expected_job_time_pairs), len(self.scheduler_mock.enterabs.call_args_list)) for i, pair in enumerate(expected_job_time_pairs): expected_time = date_utils.sec_to_datetime(pair[1]) expected_job = pair[0] # the first item of call_args is actual arguments, passed to the method args = self.scheduler_mock.enterabs.call_args_list[i][0] # we schedule job as enterabs(expected_time, priority, self._execute_job, (job,)) # to get the job, we need to get the last arg, and extract the first parameter from it schedule_method_args_tuple = args[3] schedule_method_job_arg = schedule_method_args_tuple[0] actual_time = date_utils.sec_to_datetime(args[0]) self.assertEqual(expected_time, actual_time) self.assertDictEqual(expected_job.as_serializable_dict(), schedule_method_job_arg.as_serializable_dict()) def mock_schedule_model_with_secure_param(self): model = test_utils.create_config_model('some-name', parameters=[{'name': 'p1', 'secure': True}]) model.schedulable = True self.config_service.load_config_model.side_effect = lambda a, b, c: model def setUp(self) -> None: super().setUp() self.patcher = patch('sched.scheduler') self.scheduler_mock = MagicMock() self.patcher.start().return_value = self.scheduler_mock schedule_service._sleep = MagicMock() schedule_service._sleep.side_effect = lambda x: time.sleep(0.001) self.unschedulable_scripts = set() self.config_service = MagicMock() self.config_service.load_config_model.side_effect = lambda name, b, c: test_utils.create_config_model( name, schedulable=name not in self.unschedulable_scripts) self.execution_service = MagicMock() self.schedule_service = ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) date_utils._mocked_now = mocked_now test_utils.setup() def tearDown(self) -> None: super().tearDown() test_utils.cleanup() date_utils._mocked_now = None self.schedule_service._stop() self.schedule_service.scheduling_thread.join() schedule_service._sleep = time.sleep self.patcher.stop()
def main(): project_path = os.getcwd() try: tool_utils.validate_web_build_exists(project_path) except InvalidWebBuildException as e: print(str(e)) sys.exit(-1) logging_conf_file = os.path.join(CONFIG_FOLDER, 'logging.json') with open(logging_conf_file, 'rt') as f: log_config = json.load(f) file_utils.prepare_folder(LOG_FOLDER) logging.config.dictConfig(log_config) server_version = tool_utils.get_server_version(project_path) logging.info('Starting Script Server' + (', v' + server_version if server_version else ' (custom version)')) file_utils.prepare_folder(CONFIG_FOLDER) file_utils.prepare_folder(TEMP_FOLDER) migrations.migrate.migrate(TEMP_FOLDER, CONFIG_FOLDER, SERVER_CONF_PATH, LOG_FOLDER) server_config = server_conf.from_json(SERVER_CONF_PATH, TEMP_FOLDER) secret = get_secret(server_config.secret_storage_file) tornado_client_config.initialize() group_provider = create_group_provider(server_config.user_groups, server_config.authenticator, server_config.admin_users) authorizer = Authorizer(server_config.allowed_users, server_config.admin_users, server_config.full_history_users, server_config.code_editor_users, group_provider) config_service = ConfigService(authorizer, CONFIG_FOLDER) alerts_service = AlertsService(server_config.alerts_config) alerts_service = alerts_service execution_logs_path = os.path.join(LOG_FOLDER, 'processes') log_name_creator = LogNameCreator( server_config.logging_config.filename_pattern, server_config.logging_config.date_format) execution_logging_service = ExecutionLoggingService( execution_logs_path, log_name_creator, authorizer) existing_ids = [ entry.id for entry in execution_logging_service.get_history_entries( None, system_call=True) ] id_generator = IdGenerator(existing_ids) execution_service = ExecutionService(authorizer, id_generator) execution_logging_controller = ExecutionLoggingController( execution_service, execution_logging_service) execution_logging_controller.start() user_file_storage = UserFileStorage(secret) file_download_feature = FileDownloadFeature(user_file_storage, TEMP_FOLDER) file_download_feature.subscribe(execution_service) file_upload_feature = FileUploadFeature(user_file_storage, TEMP_FOLDER) alerter_feature = FailAlerterFeature(execution_service, alerts_service) alerter_feature.start() executions_callback_feature = ExecutionsCallbackFeature( execution_service, server_config.callbacks_config) executions_callback_feature.start() schedule_service = ScheduleService(config_service, execution_service, CONFIG_FOLDER) server.init(server_config, server_config.authenticator, authorizer, execution_service, schedule_service, execution_logging_service, config_service, alerts_service, file_upload_feature, file_download_feature, secret, server_version, CONFIG_FOLDER)
class ScheduleServiceTestCase(TestCase): def assert_schedule_calls(self, expected_job_time_pairs): self.assertEqual(len(expected_job_time_pairs), len(self.scheduler_mock.enterabs.call_args_list)) for i, pair in enumerate(expected_job_time_pairs): expected_time = date_utils.sec_to_datetime(pair[1]) expected_job = pair[0] # the first item of call_args is actual arguments, passed to the method args = self.scheduler_mock.enterabs.call_args_list[i][0] # we schedule job as enterabs(expected_time, priority, self._execute_job, (job,)) # to get the job, we need to get the last arg, and extract the first parameter from it schedule_method_args_tuple = args[3] schedule_method_job_arg = schedule_method_args_tuple[0] actual_time = date_utils.sec_to_datetime(args[0]) self.assertEqual(expected_time, actual_time) self.assertDictEqual( expected_job.as_serializable_dict(), schedule_method_job_arg.as_serializable_dict()) def mock_schedule_model_with_secure_param(self): self.create_config('secure-config', parameters=[ { 'name': 'p1', 'secure': True }, { 'name': 'param_2', 'type': 'multiselect', 'values': ['hello', 'world', '1', '2', '3'] }, ]) def setUp(self) -> None: super().setUp() test_utils.setup() self.patcher = patch('sched.scheduler') self.scheduler_mock = MagicMock() self.patcher.start().return_value = self.scheduler_mock schedule_service._sleep = MagicMock() schedule_service._sleep.side_effect = lambda x: time.sleep(0.001) self.config_service = ConfigService(AnyUserAuthorizer(), test_utils.temp_folder) self.create_config('my_script_A') self.create_config('unschedulable-script', scheduling_enabled=False) self.execution_service = MagicMock() self.schedule_service = ScheduleService(self.config_service, self.execution_service, test_utils.temp_folder) date_utils._mocked_now = mocked_now def create_config(self, name, scheduling_enabled=True, parameters=None): if parameters is None: parameters = [ { 'name': 'p1' }, { 'name': 'param_2', 'type': 'multiselect', 'values': ['hello', 'world', '1', '2', '3'] }, ] test_utils.write_script_config( { 'name': name, 'script_path': 'echo 1', 'parameters': parameters, 'scheduling': { 'enabled': scheduling_enabled } }, name) def tearDown(self) -> None: super().tearDown() test_utils.cleanup() date_utils._mocked_now = None self.schedule_service._stop() self.schedule_service.scheduling_thread.join() schedule_service._sleep = time.sleep self.patcher.stop()