def test_task_server(self): # Create some stats t_now = datetime.utcnow() dm.save_object(SystemStats( 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, t_now - timedelta(minutes=5), t_now )) # We should now have stats sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertGreater(len(sys_stats), 0) # Check current task list entries tasks = dm.list_objects(Task, order_field=Task.id) task_list_len = len(tasks) # Post a background task to purge the stats KEEP_SECS = 10 task_obj = tm.add_task( None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS ) self.assertIsNotNone(task_obj) # Check it really got added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len + 1) task_list_len = len(tasks) # Post it again, make sure there is no dupe added dupe_task_obj = tm.add_task( None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS ) self.assertIsNone(dupe_task_obj) # Check it really didn't get re-added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len) task = tasks[-1] self.assertEqual(task.id, task_obj.id) # Wait for task completion tm.wait_for_task(task_obj.id, 20) # We should now have no stats t_now = datetime.utcnow() sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertEqual(len(sys_stats), 0) # The completed task should only be removed after the delay we specified task = dm.get_object(Task, task_obj.id) self.assertIsNotNone(task) self.assertEqual(task.status, Task.STATUS_COMPLETE) # Wait for keep time + task server's poll time time.sleep(KEEP_SECS + 10) # Should now be gone task = dm.get_object(Task, task_obj.id) self.assertIsNone(task)
def test_task_result_none(self): # Test no return value task_obj = tm.add_task(None, 'Test return values', 'test_result_task', { 'raise_exception': False, 'return_value': None }, Task.PRIORITY_NORMAL, 'info', 'error', 5) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 10) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertIsNone(task_obj.result) dm.delete_object(task_obj)
def test_task_result_object(self): # Test normal return value task_obj = tm.add_task( None, 'Test return values', 'test_result_task', {'raise_exception': False, 'return_value': {'my_bool': True}}, Task.PRIORITY_NORMAL, 'info', 'error', 5 ) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 20) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertEqual(task_obj.result, {'my_bool': True}) dm.delete_object(task_obj)
def test_task_server(self): # Create some stats t_now = datetime.utcnow() dm.save_object( SystemStats(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, t_now - timedelta(minutes=5), t_now)) # We should now have stats sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertGreater(len(sys_stats), 0) # Check current task list entries tasks = dm.list_objects(Task, order_field=Task.id) task_list_len = len(tasks) # Post a background task to purge the stats KEEP_SECS = 10 task_obj = tm.add_task(None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS) self.assertIsNotNone(task_obj) # Check it really got added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len + 1) task_list_len = len(tasks) # Post it again, make sure there is no dupe added dupe_task_obj = tm.add_task(None, 'Purge system statistics', 'purge_system_stats', {'before_time': t_now}, Task.PRIORITY_NORMAL, 'info', 'error', KEEP_SECS) self.assertIsNone(dupe_task_obj) # Check it really didn't get re-added tasks = dm.list_objects(Task, order_field=Task.id) self.assertEqual(len(tasks), task_list_len) task = tasks[-1] self.assertEqual(task.id, task_obj.id) # Wait for task completion tm.wait_for_task(task_obj.id, 10) # We should now have no stats t_now = datetime.utcnow() sys_stats = dm.search_system_stats(t_now - timedelta(minutes=60), t_now) self.assertEqual(len(sys_stats), 0) # The completed task should only be removed after the delay we specified task = dm.get_object(Task, task_obj.id) self.assertIsNotNone(task) self.assertEqual(task.status, Task.STATUS_COMPLETE) # Wait for keep time + task server's poll time time.sleep(KEEP_SECS + 10) # Should now be gone task = dm.get_object(Task, task_obj.id) self.assertIsNone(task)
def test_task_result_exception(self): # Test exception raised task_obj = tm.add_task( None, 'Test return values', 'test_result_task', {'raise_exception': True, 'return_value': None}, Task.PRIORITY_NORMAL, 'info', 'error', 5 ) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 20) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertIsInstance(task_obj.result, ValueError) self.assertEqual(repr(task_obj.result), repr(ValueError('An error happened'))) dm.delete_object(task_obj)
def test_task_result_exception(self): # Test exception raised task_obj = tm.add_task(None, 'Test return values', 'test_result_task', { 'raise_exception': True, 'return_value': None }, Task.PRIORITY_NORMAL, 'info', 'error', 5) self.assertIsNotNone(task_obj) tm.wait_for_task(task_obj.id, 10) task_obj = tm.get_task(task_obj.id, decode_attrs=True) self.assertIsInstance(task_obj.result, ValueError) self.assertEqual(repr(task_obj.result), repr(ValueError('An error happened'))) dm.delete_object(task_obj)
def _task_response(self, task, timeout_secs): task_completed = False try: # Wait for task to complete task = task_engine.wait_for_task(task.id, timeout_secs) if task is None: # Someone else deleted it? Shouldn't normally get here. raise TimeoutError() task_completed = True # Return the updated folder (or raise the exception) if isinstance(task.result, Exception): raise task.result return make_api_success_response(object_to_dict(task.result)) except TimeoutError: # Return a 202 "task ongoing" response task_dict = object_to_dict(task) if task is not None else None # Decode the params before returning if task_dict and task_dict.get('params'): task_dict['params'] = pickle.loads(task_dict['params']) return make_api_success_response(task_dict, task_accepted=True) finally: if task and task_completed: try: # Delete the task so another API call can be made immediately data_engine.delete_object(task) except Exception: pass