def test_flow_doesnt_raises_for_missing_nonrequired_parameters(): with Flow(name="test") as f: p = Parameter("x", default=1) f.add_task(p) flow_state = f.run() assert flow_state.is_successful() assert flow_state.result[p].result == 1
def test_flow_accepts_unserializeable_parameters(): with Flow(name="test") as f: p = Parameter("x")() value = lambda a: a + 1 state = f.run(parameters={"x": value}) assert state.result[p].result is value
def test_add_edge_raise_error_for_downstream_parameter(): f = Flow(name="test") t = Task() p = Parameter("p") with pytest.raises(ValueError) as exc: f.add_edge(upstream_task=t, downstream_task=p) assert "can not have upstream dependencies" in str(exc.value)
def test_serialization(self): p1, t2, t3, = Parameter("1"), Task("2"), Task("3") f = Flow(name="test", tasks=[p1, t2, t3]) f.add_edge(p1, t2) f.add_edge(p1, t3) serialized = f.serialize() assert isinstance(serialized, dict) assert len(serialized["tasks"]) == len(f.tasks)
def test_replace_runs_smoothly(self): add = AddTask() class SubTask(Task): def run(self, x, y): return x - y sub = SubTask() with Flow(name="test") as f: x, y = Parameter("x"), Parameter("y") res = add(x, y) state = f.run(x=10, y=11) assert state.result[res].result == 21 f.replace(res, sub) state = f.run(x=10, y=11) assert state.result[sub].result == -1
def test_flow_raises_for_irrelevant_user_provided_parameters(): class ParameterTask(Task): def run(self): return prefect.context.get("parameters") with Flow(name="test") as f: x = Parameter("x") t = ParameterTask() f.add_task(x) f.add_task(t) # errors because of the invalid parameter with pytest.raises(ValueError): state = f.run(parameters=dict(x=10, y=3, z=9)) # errors because the parameter is passed to FlowRunner.run() as an invalid kwarg with pytest.raises(TypeError): state = f.run(x=10, y=3, z=9)
def test_deserialization(self): p1, t2, t3, = Parameter("1"), Task("2"), Task("3") f = Flow( name="hi", tasks=[p1, t2, t3], schedule=prefect.schedules.CronSchedule("0 0 * * *"), ) f.add_edge(p1, t2) f.add_edge(p1, t3) serialized = f.serialize() f2 = prefect.serialization.flow.FlowSchema().load(serialized) assert len(f2.tasks) == 3 assert len(f2.edges) == 2 assert len(f2.reference_tasks()) == 2 assert {t.name for t in f2.reference_tasks()} == {"2", "3"} assert f2.name == f.name assert isinstance(f2.schedule, prefect.schedules.CronSchedule)
def test_call_must_have_a_flow_out_of_context(): with pytest.raises(ValueError) as exc: Parameter("x")() assert "infer an active Flow" in str(exc.value)
def test_create_parameter_with_default_is_not_required(): x = Parameter("x", default=2) assert not x.required
def test_parameters_can_not_be_downstream_dependencies(): with Flow(name="test") as f: p = Parameter("x") t = Task() with pytest.raises(ValueError): t.set_downstream(p)
def test_call_does_not_accept_most_args(attr): x = Parameter("x") with pytest.raises(TypeError) as exc: x(**{attr: None}) assert "unexpected keyword argument" in str(exc.value)
def test_create_parameter(): x = Parameter("x") assert isinstance(x, Task) assert x.default is None assert x.required
def test_copy_with_new_name(): x = Parameter("x") y = x.copy("y") assert x.name == x.slug == "x" assert y.name == y.slug == "y"
def test_call_accepts_flow(): f = Flow("test") Parameter("x")(flow=f) assert len(f.tasks) == 1
def test_copy_requires_name(): x = Parameter("x") with pytest.raises(TypeError) as exc: x.copy() assert "required positional argument" in str(exc.value)
def test_create_parameter_with_default(): x = Parameter("x", default=2) assert x.default == 2 assert x.run() == 2
def test_parameter_slug_cant_be_changed(): x = Parameter("x") assert x.slug == "x" with pytest.raises(AttributeError): x.slug = "hi"
def test_parameter_slug_is_its_name(): x = Parameter("x") assert x.name == x.slug == "x"
def test_create_required_parameter(): x = Parameter("x", required=True) assert x.required
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_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_calling_parameter_is_ok(): with Flow("test") as f: Parameter("x")() assert len(f.tasks) == 1