def test_create_flow_with_name_as_none(self): with pytest.raises(ValueError): f1 = Flow(name=None)
def test_add_task_to_flow(): f = Flow(name="test") t = Task() f.add_task(t) assert t in f.tasks
def test_get_tasks_defaults_to_name(self): t1, t2 = Task(name="t1"), Task(name="t2") f = Flow(name="test", tasks=[t1, t2]) assert f.get_tasks("t1") == [t1]
def test_cache_terminal_tasks(self): f = Flow(name="test") t1 = Task() t2 = Task() t3 = Task() f.add_edge(t1, t2) f.terminal_tasks() # check that cache holds result key = ("terminal_tasks", ()) assert f._cache[key] == set([t2]) # check that cache is read f._cache[key] = 1 assert f.terminal_tasks() == 1 f.add_edge(t2, t3) assert f.terminal_tasks() == set([t3])
def test_adding_edge_clears_cache(self): f = Flow(name="test") f._cache[1] = 2 f.add_edge(Task(), Task()) assert 1 not in f._cache
def test_cache_created(self): f = Flow(name="test") assert isinstance(f._cache, dict) assert len(f._cache) == 0
def test_flow_has_logger(self): f = Flow(name="test") assert isinstance(f.logger, logging.Logger)
def test_create_flow_with_name(self): f2 = Flow(name="test") assert f2.name == "test"
def test_flow_raises_for_missing_required_parameters(): with Flow(name="test") as f: f.add_task(Parameter("x")) with pytest.raises(ValueError): f.run()
def test_equality_based_on_name(self): f1 = Flow("hi") f2 = Flow("bye") assert f1 != f2
def test_create_flow_with_name_as_false(self): with pytest.raises(ValueError): f1 = Flow(name=False)
def test_create_flow_with_name_as_empty_string(self): with pytest.raises(ValueError): f1 = Flow(name="")
def test_key_states_raises_error_if_not_iterable(): with Flow(name="test") as f: t1 = Task() f.add_task(t1) with pytest.raises(TypeError): f.set_reference_tasks(t1)
def test_key_states_raises_error_if_not_part_of_flow(): f = Flow(name="test") t1 = Task() with pytest.raises(ValueError): f.set_reference_tasks([t1])
def test_call_accepts_flow(): f = Flow("test") Parameter("x")(flow=f) assert len(f.tasks) == 1
def test_validate_edges_kwarg(): f = Flow(name="test") t1, t2 = Task(), Task() # these tasks don't support keyed edges with pytest.raises(TypeError): f.add_edge(t1, t2, key="x", validate=True)
def test_create_flow_illegal_handler(self): with pytest.raises(TypeError): Flow(name="test", state_handlers=lambda *a: 1)
def test_validate_edges(): with set_temporary_config({"flows.eager_edge_validation": True}): f = Flow(name="test") t1, t2 = Task(), Task() # these tasks don't support keyed edges with pytest.raises(TypeError): f.add_edge(t1, t2, key="x")
def test_cache_sorted_tasks_with_args(self): f = Flow(name="test") t1 = Task() t2 = Task() t3 = Task() f.add_edge(t1, t2) f.sorted_tasks([t2]) # check that cache holds result key = ("_sorted_tasks", (("root_tasks", (t2,)),)) assert f._cache[key] == (t2,) # check that cache is read f._cache[key] = 1 assert f.sorted_tasks([t2]) == 1 assert f.sorted_tasks() == (t1, t2) f.add_edge(t2, t3) assert f.sorted_tasks([t2]) == (t2, t3)
def test_skip_validate_edges(): f = Flow(name="test") t1, t2 = Task(), Task() # these tasks don't support keyed edges f.add_edge(t1, t2, key="x", validate=False) f.add_edge(t2, t1, validate=False) # this introduces a cycle
def test_create_flow_with_result_handler(self): f = Flow(name="test", result_handler=LocalResultHandler()) assert isinstance(f.result_handler, ResultHandler) assert isinstance(f.result_handler, LocalResultHandler)
def test_create_flow_without_state_handler(self): assert Flow(name="test").state_handlers == []
def test_cache_all_downstream_edges(self): f = Flow(name="test") t1 = Task() t2 = Task() t3 = Task() f.add_edge(t1, t2) f.all_downstream_edges() key = ("all_downstream_edges", ()) f._cache[key] = 1 assert f.all_downstream_edges() == 1 f.add_edge(t2, t3) assert f.all_downstream_edges() != 1
def test_create_flow_with_on_failure(self): f = Flow(name="test", on_failure=lambda *args: None) assert len(f.state_handlers) == 1
def test_replace_complains_about_tasks_not_in_flow(self): with Flow(name="test") as f: t1 = Task(name="t1")() t3 = Task(name="t3") with pytest.raises(ValueError): f.replace(t3, t1)
def test_raise_error_if_two_parameters_have_same_name(): f = Flow(name="test") f.add_task(Parameter("x")) assert "x" in {p.name for p in f.parameters()} with pytest.raises(ValueError): f.add_task(Parameter("x"))
def test_get_tasks_defaults_to_return_everything(self): t1, t2 = Task(name="t1"), Task(name="t2") f = Flow(name="test", tasks=[t1, t2]) assert f.get_tasks() == [t1, t2]
def test_calling_parameter_is_ok(): with Flow("test") as f: Parameter("x")() assert len(f.tasks) == 1
def test_get_tasks_takes_intersection(self): t1, t2 = Task(name="t1", slug="11"), Task(name="t1", slug="22") f = Flow(name="test", tasks=[t1, t2]) assert f.get_tasks(name="t1") == [t1, t2] assert f.get_tasks(name="t1", slug="11") == [t1] assert f.get_tasks(name="t1", slug="11", tags=["atag"]) == []
def test_set_reference_tasks_at_init_with_empty_flow_raises_error(): with pytest.raises(ValueError) as exc: Flow(name="test", reference_tasks=[Task()]) assert "must be part of the flow" in str(exc.value)