def test_run_count_tracked_via_retry_states(self): flow = Flow(name="test") t1 = ErrorTask(max_retries=1, retry_delay=datetime.timedelta(0)) t2 = ErrorTask(max_retries=2, retry_delay=datetime.timedelta(0)) flow.add_task(t1) flow.add_task(t2) # first run state1 = FlowRunner(flow=flow).run(return_tasks=[t1, t2]) assert state1.is_running() assert state1.result[t1].is_retrying() assert state1.result[t1].run_count == 1 assert state1.result[t2].is_retrying() assert state1.result[t2].run_count == 1 # second run state2 = FlowRunner(flow=flow).run(task_states=state1.result, return_tasks=[t1, t2]) assert state2.is_running() assert isinstance(state2.result[t1], Failed) assert state2.result[t2].is_retrying() assert state2.result[t2].run_count == 2 # third run state3 = FlowRunner(flow=flow).run(task_states=state2.result, return_tasks=[t1, t2]) assert state3.is_failed() assert isinstance(state3.result[t1], Failed) assert isinstance(state3.result[t2], Failed)
def test_task_handler_that_raises_signal_is_trapped(self): def handler(flow, old, new): raise signals.FAIL() flow = Flow(name="test", state_handlers=[handler]) state = FlowRunner(flow=flow).run() assert state.is_failed()
def test_task_handler_that_has_error_is_trapped(self): def handler(flow, old, new): 1 / 0 flow = Flow(name="test", state_handlers=[handler]) state = FlowRunner(flow=flow).run() assert state.is_failed()
def test_terminal_mapped_states_are_used_for_flow_state(self, executor): with Flow(name="test") as flow: res = ReturnTask().map([0, 1]) state = FlowRunner(flow=flow).run(return_tasks=[res], executor=executor) assert state.is_failed() assert state.result[res].map_states[0].is_successful() assert state.result[res].map_states[1].is_failed()
def test_flow_runner_handles_timeout_error_with_mproc(mproc): sleeper = SlowTask(timeout=1) with Flow(name="test") as flow: res = sleeper(2) state = FlowRunner(flow=flow).run(return_tasks=[res], executor=mproc) assert state.is_failed() assert isinstance(state.result[res], TimedOut) assert isinstance(state.result[res].result, TimeoutError)
def test_flow_runner_handles_timeout_error_with_mproc(mproc): "daemonic processes are not allowed to have children" sleeper = SlowTask(timeout=1) with Flow(name="test") as flow: res = sleeper(3) state = FlowRunner(flow=flow).run(return_tasks=[res], executor=mproc) assert state.is_failed() assert isinstance(state.result[res].result, AssertionError)
def test_flow_runner_handles_timeouts(executor): sleeper = SlowTask(timeout=1) with Flow(name="test") as flow: res = sleeper(3) state = FlowRunner(flow=flow).run(return_tasks=[res], executor=executor) assert state.is_failed() assert isinstance(state.result[res], TimedOut) assert "timed out" in state.result[res].message assert isinstance(state.result[res].result, TimeoutError)
def test_mapped_will_use_partial_existing_map_states_if_available(self, executor): with Flow(name="test") as flow: res = ReturnTask().map([1, 1]) state = FlowRunner(flow=flow).run( return_tasks=[res], executor=executor, task_states={res: Mapped(map_states=[None, Success(result=100)])}, ) assert state.is_failed() assert state.result[res].map_states[0].is_failed() assert state.result[res].map_states[1].is_successful() assert state.result[res].map_states[1].result == 100
def test_flow_runner_handles_mapped_timeouts(executor): sleeper = SlowTask(timeout=1) with Flow(name="test") as flow: res = sleeper.map([0, 2, 3]) state = FlowRunner(flow=flow).run(return_tasks=[res], executor=executor) assert state.is_failed() mapped_states = state.result[res] assert mapped_states.map_states[0].is_successful() for fstate in mapped_states.map_states[1:]: assert fstate.is_failed() assert isinstance(fstate.result, TimeoutError)
def test_improper_use_of_unmapped_fails_gracefully(): add = AddTask() x = Parameter("x", default=[1, 2, 3]) with Flow(name="test") as f: res = add.map(x, y=8) # incorrect, should use `unmapped` state = FlowRunner(flow=f).run(return_tasks=f.tasks) assert state.is_failed() # make sure tasks were still returned with the correct states x_state = state.result.pop(x) res_state = state.result.pop(res) y_state = state.result.popitem()[1] assert x_state.is_successful() assert x_state.result == [1, 2, 3] assert y_state.is_successful() assert y_state.result == 8 assert res_state.is_failed()