def test_consumer_logs_cleaned_backtrace(self): """Consumer will log catched exceptions with internal frames removed from the backtrace.""" create_task(function_name='tests.fixtures.failing_alphabet', max_retries=0) consumer = Consumer() with self.assertLogs('taskq', level='ERROR') as context_manager: consumer.execute_tasks() output = ''.join(context_manager.output) lines = output.splitlines() # First line is our custom message self.assertIn('ValueError', lines[0]) self.assertIn('I don\'t know what comes after "d"', lines[0]) # Skip the first line (our message) and the second one ("Traceback # (most recent call last)") lines = lines[2:] # Only check the even lines (containing the filename, line and function name) relevant_lines = [l for i, l in enumerate(lines) if i % 2 == 0] # Check that we are getting the expected function names in the traceback expected_functions = [ '_protected_call', 'failing_alphabet', 'a', 'b', 'c', 'd' ] for i, expected_function in enumerate(expected_functions): self.assertIn(expected_function, relevant_lines[i])
def test_consumer_will_catch_task_exceptions(self): """Consumer will catch and log exceptions raised by the tasks.""" task = create_task(function_name='tests.fixtures.failing', max_retries=0) consumer = Consumer() consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_FAILED)
def test_consumer_run_due_task(self): """Consumer will run task at or after their due date.""" due_at = now() - timedelta(milliseconds=100) task = create_task(due_at=due_at) consumer = Consumer() consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_SUCCESS)
def test_consumer_task_timeout(self): """Consumer will abort a task if it exceeds the timeout.""" task = create_task(function_name='tests.fixtures.never_return', timeout=timedelta(seconds=2)) consumer = Consumer() consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_FAILED)
def test_consumer_wont_load_not_taskified_function(self): """Consumer will refuse to load a regular function not decorated with @taskify. """ task = create_task(function_name='tests.fixtures.naked_function', ) consumer = Consumer() consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_FAILED)
def test_consumer_run_self_cancelling_task(self): """Consumer will run a self-cancelling task only once.""" due_at = now() - timedelta(milliseconds=100) task = create_task(function_name='tests.fixtures.self_cancelling', due_at=due_at) consumer = Consumer() consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_CANCELED)
def test_consumer_logs_task_started(self): """Consumer will log that a task has started.""" due_at = now() - timedelta(milliseconds=100) task = create_task(due_at=due_at) consumer = Consumer() with self.assertLogs('taskq', level='INFO') as context_manager: consumer.execute_tasks() output = ''.join(context_manager.output) self.assertIn(task.uuid, output) self.assertIn('Started', output)
def test_consumer_will_retry_after_task_error(self): """Consumer will catch the tasks error and retry to run the task later. """ task = create_task(function_name='tests.fixtures.failing', max_retries=3) consumer = Consumer() consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_QUEUED) self.assertEqual(task.retries, 1)
def test_consumer_logs_task_started_nth_rety(self): """Consumer will log that a task has started and is executing its nth rety.""" due_at = now() - timedelta(milliseconds=100) task = create_task(function_name='tests.fixtures.failing', due_at=due_at) consumer = Consumer() consumer.execute_tasks() with self.assertLogs('taskq', level='INFO') as context_manager: consumer.execute_tasks() output = ''.join(context_manager.output) self.assertIn(task.uuid, output) self.assertIn('Started (1st retry)', output)
def test_consumer_will_retry_at_most_max_retries_times(self): """Consumer will not retry the task more than task.max_retries times.""" task = create_task(function_name='tests.fixtures.failing', max_retries=2) consumer = Consumer() consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_QUEUED) self.assertEqual(task.retries, 1) consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_QUEUED) self.assertEqual(task.retries, 2) consumer.execute_tasks() task.refresh_from_db() self.assertEqual(task.status, Task.STATUS_FAILED) self.assertEqual(task.retries, 2)