Esempio n. 1
0
def test_task_runner_validates_cached_state_inputs_if_task_has_caching_and_uses_task_handler(
    client, ):
    class Handler(ResultHandler):
        def read(self, val):
            return 1337

    @prefect.task(
        cache_for=datetime.timedelta(minutes=1),
        cache_validator=all_inputs,
        result_handler=Handler(),
    )
    def cached_task(x):
        return 42

    dull_state = Cached(
        cached_result_expiration=datetime.datetime.utcnow() +
        datetime.timedelta(minutes=2),
        result=SafeResult("-1", JSONResultHandler()),
    )
    state = Cached(
        cached_result_expiration=datetime.datetime.utcnow() +
        datetime.timedelta(minutes=2),
        result=SafeResult("99", JSONResultHandler()),
        cached_inputs={
            "x": SafeResult("2", result_handler=JSONResultHandler())
        },
    )
    client.get_latest_cached_states = MagicMock(
        return_value=[dull_state, state])

    res = CloudTaskRunner(task=cached_task).check_task_is_cached(
        Pending(), inputs={"x": Result(2, result_handler=JSONResultHandler())})
    assert client.get_latest_cached_states.called
    assert res.is_successful()
    assert res.is_cached()
    assert res.result == 1337
    async def test_set_task_run_state_with_safe_result(self, run_query,
                                                       task_run_id):
        result = SafeResult("10", result_handler=JSONResultHandler())
        state = Success(result=result)

        result = await run_query(
            query=self.mutation,
            variables=dict(input=dict(states=[
                dict(task_run_id=task_run_id, state=state.serialize())
            ])),
        )
        tr = await models.TaskRun.where(
            id=result.data.set_task_run_states.states[0].id
        ).first({"state", "version"})
        assert tr.version == 2
        assert tr.state == "Success"
Esempio n. 3
0
def test_serialize_and_deserialize_on_mixed_cached_state():
    safe_dct = SafeResult(dict(hi=5, bye=6),
                          result_handler=JSONResultHandler())
    now = pendulum.now("utc")
    state = Cached(
        cached_inputs=dict(x=Result(2), p=Result("p")),
        result=safe_dct,
        cached_result_expiration=now,
    )
    serialized = state.serialize()
    new_state = State.deserialize(serialized)
    assert isinstance(new_state, Cached)
    assert new_state.color == state.color
    assert new_state.result == dict(hi=5, bye=6)
    assert new_state.cached_result_expiration == state.cached_result_expiration
    assert new_state.cached_inputs == dict.fromkeys(["x", "p"], NoResult)
Esempio n. 4
0
def test_set_task_run_state_serializes(monkeypatch):
    response = {"data": {"setTaskRunState": None}}
    post = MagicMock(return_value=MagicMock(json=MagicMock(
        return_value=response)))

    monkeypatch.setattr("requests.post", post)
    with set_temporary_config({
            "cloud.graphql": "http://my-cloud.foo",
            "cloud.auth_token": "secret_token"
    }):
        client = Client()

    res = SafeResult(lambda: None, result_handler=None)
    with pytest.raises(marshmallow.exceptions.ValidationError) as exc:
        result = client.set_task_run_state(task_run_id="76-salt",
                                           version=0,
                                           state=Pending(result=res))
Esempio n. 5
0
def test_set_task_run_state_serializes(patch_post):
    response = {"data": {"set_task_run_states": {"states": [{"status": "SUCCESS"}]}}}
    post = patch_post(response)

    with set_temporary_config(
        {
            "cloud.api": "http://my-cloud.foo",
            "cloud.auth_token": "secret_token",
            "backend": "cloud",
        }
    ):
        client = Client()

    res = SafeResult(lambda: None, result_handler=None)
    with pytest.raises(marshmallow.exceptions.ValidationError):
        client.set_task_run_state(
            task_run_id="76-salt", version=0, state=Pending(result=res)
        )
Esempio n. 6
0
def test_task_failure_with_upstream_secrets_doesnt_store_secret_value_and_recompute_if_necessary(
    client, ):
    @prefect.task(max_retries=2, retry_delay=timedelta(seconds=100))
    def is_p_three(p):
        if p == 3:
            raise ValueError("No thank you.")
        return p

    with prefect.Flow("test", result_handler=JSONResultHandler()) as f:
        p = prefect.tasks.secrets.Secret("p")
        res = is_p_three(p)

    with prefect.context(secrets=dict(p=3)):
        state = CloudFlowRunner(flow=f).run(return_tasks=[res])

    assert state.is_running()
    assert isinstance(state.result[res], Retrying)

    exp_res = Result(3, result_handler=SecretResultHandler(p))
    assert not state.result[res].cached_inputs["p"] == exp_res
    exp_res.store_safe_value()
    assert state.result[res].cached_inputs["p"] == exp_res

    ## here we set the result of the secret to a saferesult, ensuring
    ## it will get converted to a "true" result;
    ## we expect that the upstream value will actually get recomputed from context
    ## through the SecretResultHandler
    safe = SafeResult("p", result_handler=SecretResultHandler(p))
    state.result[p] = Success(result=safe)
    state.result[res].start_time = pendulum.now("utc")
    state.result[res].cached_inputs = dict(p=safe)

    with prefect.context(secrets=dict(p=4)):
        new_state = CloudFlowRunner(flow=f).run(return_tasks=[res],
                                                task_states=state.result)

    assert new_state.is_successful()
    assert new_state.result[res].result == 4
Esempio n. 7
0
    def test_to_result_returns_self_for_no_results(self):
        assert NoResult.to_result() is NoResult

    def test_to_result_returns_hydrated_result_for_safe(self):
        s = SafeResult("3", result_handler=JSONResultHandler())
        res = s.to_result()
        assert isinstance(res, Result)
        assert res.value == 3
        assert res.safe_value is s
        assert res.result_handler is s.result_handler


@pytest.mark.parametrize(
    "obj",
    [
        Result(3),
        Result(object, result_handler=LocalResultHandler()),
        NoResult,
        SafeResult("3", result_handler=JSONResultHandler()),
    ],
)
def test_everything_is_pickleable_after_init(obj):
    assert cloudpickle.loads(cloudpickle.dumps(obj)) == obj


def test_results_are_pickleable_with_their_safe_values():
    res = Result(3, result_handler=JSONResultHandler())
    res.store_safe_value()
    assert cloudpickle.loads(cloudpickle.dumps(res)) == res
Esempio n. 8
0
 def test_safe_results_are_same(self):
     r = SafeResult("3", result_handler=JSONResultHandler())
     s = SafeResult("3", result_handler=JSONResultHandler())
     assert r == s
Esempio n. 9
0
def test_safe_result_disallows_none_result_handler_at_deserialization_time():
    schema = SafeResultSchema()
    r = SafeResult(value=None, result_handler=None)
    serialized = schema.dump(r)
    with pytest.raises(marshmallow.exceptions.ValidationError):
        schema.load(serialized)
Esempio n. 10
0
def test_value_raises_error_on_dump_if_not_valid_json():
    r = SafeResult(
        value={"x": {"y": {"z": lambda: 1}}}, result_handler=JSONResultHandler()
    )
    with pytest.raises(marshmallow.exceptions.ValidationError):
        StateResultSchema().dump(r)
Esempio n. 11
0
def test_basic_safe_result_repr():
    r = SafeResult(2, result_handler=JSONResultHandler())
    assert repr(r) == "<SafeResult: 2>"
Esempio n. 12
0
 def test_storing_happens_once(self):
     r = Result(value=4, result_handler=JSONResultHandler())
     safe_value = SafeResult(value="123", result_handler=JSONResultHandler())
     r.safe_value = safe_value
     r.store_safe_value()
     assert r.safe_value is safe_value
Esempio n. 13
0
<<<<<<< HEAD
    res1 = results.PrefectResult(value=1)
    res2 = results.PrefectResult(value={"z": 2})
    res3 = results.PrefectResult(location=json.dumps(dict(x=1, y={"z": 2})))
    naive_dt = datetime.datetime(2020, 1, 1)
    utc_dt = pendulum.datetime(2020, 1, 1)
    cached_state = state.Cached(
        hashed_inputs=dict(x="foo", y="bar"),
        result=res3,
        cached_result_expiration=utc_dt,
    )
    cached_state_naive = state.Cached(
        hashed_inputs=dict(x="foo", y="bar"),
        result=res3,
=======
    res1 = SafeResult(1, result_handler=JSONResultHandler())
    res2 = SafeResult({"z": 2}, result_handler=JSONResultHandler())
    res3 = SafeResult(dict(x=1, y={"z": 2}), result_handler=JSONResultHandler())
    naive_dt = datetime.datetime(2020, 1, 1)
    utc_dt = pendulum.datetime(2020, 1, 1)
    complex_result = {"x": res1, "y": res2}
    cached_state = state.Cached(
        cached_inputs=complex_result,
        result=res3,
        cached_parameters={"x": 1, "y": {"z": 2}},
        cached_result_expiration=utc_dt,
    )
    cached_state_naive = state.Cached(
        cached_inputs=complex_result,
        result=res3,
        cached_parameters={"x": 1, "y": {"z": 2}},
Esempio n. 14
0
 def test_store_safe_value_for_safe_results(self):
     r = SafeResult(value=4, result_handler=JSONResultHandler())
     output = r.store_safe_value()
     assert output is None
     assert isinstance(r.safe_value, SafeResult)
     assert r.value == 4
Esempio n. 15
0
def test_serialize_state_with_safe_result(cls):
    res = SafeResult(value="1", result_handler=JSONResultHandler())
Esempio n. 16
0
def test_result_allows_none_value():
    schema = SafeResultSchema()
    r = SafeResult(value=None, result_handler=JSONResultHandler())
    handled = schema.load(schema.dump(r))
    assert handled.value is None
    assert handled.result_handler == JSONResultHandler()


def test_safe_result_disallows_none_result_handler_at_deserialization_time():
    schema = SafeResultSchema()
    r = SafeResult(value=None, result_handler=None)
    serialized = schema.dump(r)
    with pytest.raises(marshmallow.exceptions.ValidationError):
        schema.load(serialized)


@pytest.mark.parametrize(
    "obj", [SafeResult(value=19, result_handler=JSONResultHandler()), NoResult]
)
def test_state_result_schema_chooses_schema(obj):
    schema = StateResultSchema()
    assert type(schema.load(schema.dump(obj))) == type(obj)


def test_value_raises_error_on_dump_if_not_valid_json():
    r = SafeResult(
        value={"x": {"y": {"z": lambda: 1}}}, result_handler=JSONResultHandler()
    )
    with pytest.raises(marshmallow.exceptions.ValidationError):
        StateResultSchema().dump(r)
Esempio n. 17
0
def test_result_must_be_valid_json():
    res = SafeResult({"x": {"y": {"z": 1}}}, result_handler=JSONResultHandler())
Esempio n. 18
0
def test_result_raises_error_on_dump_if_not_valid_json():
    res = SafeResult({"x": {"y": {"z": lambda: 1}}}, result_handler=JSONResultHandler())
Esempio n. 19
0
def test_result_must_be_valid_json():
    res = SafeResult({"x": {"y": {"z": 1}}}, result_handler=JSONResultHandler())
    s = state.Success(result=res)
    serialized = StateSchema().dump(s)
    assert serialized["_result"]["value"] == s.result
Esempio n. 20
0
 def test_safe_results_with_different_handlers_are_not_same(self):
     r = SafeResult("3", result_handler=JSONResultHandler())
     s = SafeResult("3", result_handler=LocalResultHandler())
     assert r != s
Esempio n. 21
0
def test_roundtrip_for_results():
    r = SafeResult(value={"y": 4}, result_handler=JSONResultHandler())
    s = SafeResultSchema().load(SafeResultSchema().dump(r))
    assert r == s
Esempio n. 22
0
 def test_safe_results_to_results_remain_the_same(self):
     r = SafeResult("3", result_handler=JSONResultHandler())
     s = SafeResult("3", result_handler=JSONResultHandler())
     assert r.to_result() == s.to_result()
Esempio n. 23
0
def test_safe_result_serializes_result_handlers():
    r = SafeResult(value=3, result_handler=JSONResultHandler())
    handled = SafeResultSchema().dump(r)
    assert handled["result_handler"]["type"] == "JSONResultHandler"
Esempio n. 24
0
 def test_safe_result_inits_with_both_args(self):
     res = SafeResult(value="3", result_handler=JSONResultHandler())
     assert res.value == "3"
     assert res.result_handler == JSONResultHandler()
     assert res.safe_value is res
Esempio n. 25
0
def test_result_allows_none_value():
    schema = SafeResultSchema()
    r = SafeResult(value=None, result_handler=JSONResultHandler())
    handled = schema.load(schema.dump(r))
    assert handled.value is None
    assert handled.result_handler == JSONResultHandler()
Esempio n. 26
0
def test_basic_safe_result_serializes():
    res = SafeResult("3", result_handler=JSONResultHandler())
    serialized = SafeResultSchema().dump(res)
    assert serialized["__version__"] == prefect.__version__
    assert serialized["value"] == "3"
    assert serialized["result_handler"]["type"] == "JSONResultHandler"
Esempio n. 27
0
def test_result_raises_error_on_dump_if_not_valid_json():
    res = SafeResult({"x": {"y": {"z": lambda: 1}}}, result_handler=JSONResultHandler())
    s = state.Success(result=res)
    with pytest.raises(marshmallow.exceptions.ValidationError):
        StateSchema().dump(s)