def test_task_failed(self): """Execution is stopped when a task failed. The next task is not executed""" class FailedTask(tasks.WorkflowTask): name = 'failtask' def apply_async(self): self.set_state(tasks.TASK_FAILED) task1 = FailedTask(mock.Mock()) task2 = mock.Mock() g = TaskDependencyGraph(MockWorkflowContext()) seq = g.sequence() seq.add(task1, task2) with limited_sleep_mock(): try: g.execute() except RuntimeError as e: self.assertIn('Workflow failed', e.message) else: self.fail('Expected task to fail') self.assertTrue(task1.is_terminated) self.assertFalse(task2.apply_async.called)
def test_task_sequence(self): """Tasks in a sequence are called in order""" class Task(tasks.WorkflowTask): name = 'task' def apply_async(self): record.append(self.i) self.set_state(tasks.TASK_SUCCEEDED) task_count = 10 # prepare the task seuqence seq_tasks = [] for i in range(task_count): t = Task(None) seq_tasks.append(t) t.i = i g = TaskDependencyGraph(MockWorkflowContext()) seq = g.sequence() seq.add(*seq_tasks) record = [] with limited_sleep_mock(): g.execute() expected = list(range(task_count)) self.assertEqual(expected, record)
def test_wait_after_fail(self): """When a task fails, the already-running tasks are waited for""" class FailedTask(tasks.WorkflowTask): """Task that fails 1 second after starting""" name = 'failtask' def get_state(self): if time.time() > start_time + 1: return tasks.TASK_FAILED else: return tasks.TASK_SENT class DelayedTask(tasks.WorkflowTask): """Task that succeeds 3 seconds after starting""" name = 'delayedtask' def get_state(self): if time.time() > start_time + 3: return tasks.TASK_SUCCEEDED else: return tasks.TASK_SENT handle_task_terminated = mock.Mock() task1 = FailedTask(mock.Mock()) task2 = DelayedTask(mock.Mock()) g = TaskDependencyGraph(MockWorkflowContext()) seq = g.sequence() seq.add(task1, task2) with limited_sleep_mock(): start_time = time.time() try: g.execute() except RuntimeError as e: self.assertIn('Workflow failed', e.message) else: self.fail('Expected task to fail') # even though the workflow failed 1 second in, the other task was # still waited for and completed task2.handle_task_terminated.assert_called()
def test_task_failed(self): """Execution is stopped when a task failed. The next task is not executed""" class FailedTask(tasks.WorkflowTask): name = 'failtask' def apply_async(self): self.set_state(tasks.TASK_FAILED) task1 = FailedTask(mock.Mock()) task2 = mock.Mock(execute_after=0) g = TaskDependencyGraph(MockWorkflowContext()) seq = g.sequence() seq.add(task1, task2) with limited_sleep_mock(): self.assertRaisesRegex(RuntimeError, 'Workflow failed', g.execute) self.assertTrue(task1.is_terminated) self.assertFalse(task2.apply_async.called)