def test_client_register_raises_for_keyed_flows_with_no_result( patch_post, compressed, monkeypatch, tmpdir): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow_from_compressed_string": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow": { "id": "long-id" } } } patch_post(response) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) @prefect.task def a(x): pass with set_temporary_config({ "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token", "backend": "cloud", }): client = Client() with prefect.Flow( name="test", storage=prefect.environments.storage.Local(tmpdir)) as flow: a(prefect.Task()) flow.result = None with pytest.warns(UserWarning, match="result handler"): flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), )
def test_client_register_builds_flow(patch_post, compressed, monkeypatch, tmpdir): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow_from_compressed_string": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow": { "id": "long-id" } } } post = patch_post(response) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) with set_temporary_config({ "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token", "backend": "cloud", }): client = Client() flow = prefect.Flow(name="test", storage=prefect.environments.storage.Local(tmpdir)) flow.result = flow.storage.result flow_id = client.register(flow, project_name="my-default-project", compressed=compressed, no_url=True) ## extract POST info if compressed: serialized_flow = decompress( json.loads(post.call_args[1]["json"]["variables"])["input"] ["serialized_flow"]) else: serialized_flow = json.loads( post.call_args[1]["json"]["variables"])["input"]["serialized_flow"] assert serialized_flow["storage"] is not None
def test_client_register_with_flow_that_cant_be_deserialized(patch_post): patch_post({"data": {"project": [{"id": "proj-id"}]}}) with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() task = prefect.Task() # we add a max_retries value to the task without a corresponding retry_delay; this will fail at deserialization task.max_retries = 3 flow = prefect.Flow(name="test", tasks=[task]) flow.result_handler = prefect.engine.result_handlers.ResultHandler() with pytest.raises( ValueError, match=("(Flow could not be deserialized).*" "(`retry_delay` must be provided if max_retries > 0)"), ) as exc: client.register(flow, project_name="my-default-project", build=False)
def test_client_register_doesnt_raise_for_scheduled_params( patch_post, compressed, monkeypatch, tmpdir ): if compressed: response = { "data": { "project": [{"id": "proj-id"}], "create_flow_from_compressed_string": {"id": "long-id"}, } } else: response = { "data": {"project": [{"id": "proj-id"}], "create_flow": {"id": "long-id"}} } patch_post(response) monkeypatch.setattr( "prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug") ) with set_temporary_config( { "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token", "backend": "cloud", } ): client = Client() a = prefect.schedules.clocks.DatesClock( [pendulum.now("UTC").add(seconds=0.1)], parameter_defaults=dict(x=1) ) b = prefect.schedules.clocks.DatesClock( [pendulum.now("UTC").add(seconds=0.25)], parameter_defaults=dict(x=2, y=5) ) x = prefect.Parameter("x", required=True) y = prefect.Parameter("y", default=1) flow = prefect.Flow( "test", schedule=prefect.schedules.Schedule(clocks=[a, b]), tasks=[x, y] ) flow.storage = prefect.environments.storage.Local(tmpdir) flow.result = flow.storage.result flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), ) assert flow_id == "long-id"
def test_client_register_optionally_avoids_building_flow( patch_post, compressed, monkeypatch): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow_from_compressed_string": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow": { "id": "long-id" } } } post = patch_post(response) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) with set_temporary_config({ "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() flow = prefect.Flow(name="test") flow.result = prefect.engine.result.Result() flow_id = client.register(flow, project_name="my-default-project", build=False, compressed=compressed) ## extract POST info if compressed: serialized_flow = decompress( json.loads(post.call_args[1]["json"]["variables"])["input"] ["serialized_flow"]) else: serialized_flow = json.loads( post.call_args[1]["json"]["variables"])["input"]["serialized_flow"] assert serialized_flow["storage"] is None
def test_client_register_flow_id_no_output(patch_post, compressed, monkeypatch, capsys, tmpdir): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow_from_compressed_string": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow": { "id": "long-id" } } } patch_post(response) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) with set_temporary_config({ "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token", "backend": "cloud", }): client = Client() flow = prefect.Flow(name="test", storage=prefect.environments.storage.Local(tmpdir)) flow.result = flow.storage.result flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), no_url=True, ) assert flow_id == "long-id" captured = capsys.readouterr() assert captured.out == "Result check: OK\n"
def test_client_register_raises_if_required_param_isnt_scheduled( patch_post, monkeypatch, tmpdir): response = { "data": { "project": [{ "id": "proj-id" }], "create_flow": { "id": "long-id" } } } patch_post(response) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) with set_temporary_config({ "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token", "backend": "cloud", }): client = Client() a = prefect.schedules.clocks.DatesClock( [pendulum.now("UTC").add(seconds=0.1)], parameter_defaults=dict(x=1)) b = prefect.schedules.clocks.DatesClock( [pendulum.now("UTC").add(seconds=0.25)], parameter_defaults=dict(y=2)) x = prefect.Parameter("x", required=True) flow = prefect.Flow("test", schedule=prefect.schedules.Schedule(clocks=[a, b]), tasks=[x]) flow.storage = prefect.environments.storage.Local(tmpdir) flow.result = flow.storage.result with pytest.raises( ClientError, match= "Flows with required parameters can not be scheduled automatically", ): flow_id = client.register( flow, project_name="my-default-project", compressed=False, version_group_id=str(uuid.uuid4()), no_url=True, )
def test_client_register_with_bad_proj_name(patch_post): patch_post({"data": {"project": []}}) with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() flow = prefect.Flow(name="test") flow.result_handler = prefect.engine.result_handlers.ResultHandler() with pytest.raises(ValueError) as exc: flow_id = client.register(flow, project_name="my-default-project") assert "not found" in str(exc.value) assert "client.create_project" in str(exc.value)
def test_client_register_flow_id_output(patch_post, compressed, monkeypatch, capsys, cloud_api): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow_from_compressed_string": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow": { "id": "long-id" } } } patch_post(response) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) with set_temporary_config({ "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() flow = prefect.Flow(name="test", storage=prefect.environments.storage.Memory()) flow.result_handler = flow.storage.result_handler flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), ) assert flow_id == "long-id" captured = capsys.readouterr() assert captured.out == "Flow: https://cloud.prefect.io/tslug/flow/long-id\n"
def test_client_register_optionally_avoids_building_flow( patch_post, compressed): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "createFlowFromCompressedString": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "createFlow": { "id": "long-id" } } } post = patch_post(response) with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() flow = prefect.Flow(name="test") flow.result_handler = prefect.engine.result_handlers.ResultHandler() flow_id = client.register(flow, project_name="my-default-project", build=False, compressed=compressed) ## extract POST info if compressed: serialized_flow = decompress( json.loads(post.call_args[1]["json"]["variables"])["input"] ["serializedFlow"]) else: serialized_flow = json.loads( post.call_args[1]["json"]["variables"])["input"]["serializedFlow"] assert serialized_flow["storage"] is None
def test_client_register_raises_for_keyed_flows_with_no_result_handler( patch_post, compressed): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "createFlowFromCompressedString": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "createFlow": { "id": "long-id" } } } patch_post(response) @prefect.task def a(x): pass with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() with prefect.Flow(name="test", storage=prefect.environments.storage.Memory()) as flow: a(prefect.Task()) flow.result_handler = None with pytest.warns(UserWarning, match="result handler"): flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), )
def test_client_register_with_bad_proj_name(patch_post, monkeypatch, cloud_api): patch_post({"data": {"project": []}}) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) with set_temporary_config({"cloud.auth_token": "secret_token"}): client = Client() flow = prefect.Flow(name="test") flow.result = prefect.engine.result.Result() with pytest.raises(ValueError) as exc: flow_id = client.register(flow, project_name="my-default-project") assert "not found" in str(exc.value) assert "client.create_project" in str(exc.value)
def test_client_register_doesnt_raise_if_no_keyed_edges( patch_post, compressed, monkeypatch, tmpdir): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow_from_compressed_string": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "create_flow": { "id": "long-id" } } } patch_post(response) monkeypatch.setattr("prefect.client.Client.get_default_tenant_slug", MagicMock(return_value="tslug")) with set_temporary_config({ "cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() flow = prefect.Flow(name="test", storage=prefect.environments.storage.Local(tmpdir)) flow.result = None flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), ) assert flow_id == "long-id"
def test_client_register_doesnt_raise_if_no_keyed_edges( patch_post, compressed): if compressed: response = { "data": { "project": [{ "id": "proj-id" }], "createFlowFromCompressedString": { "id": "long-id" }, } } else: response = { "data": { "project": [{ "id": "proj-id" }], "createFlow": { "id": "long-id" } } } patch_post(response) with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() flow = prefect.Flow(name="test", storage=prefect.environments.storage.Memory()) flow.result_handler = None flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), ) assert flow_id == "long-id"
def test_client_register_raises_for_keyed_flows_with_no_result_handler( patch_post, compressed): @prefect.task def a(x): pass with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() with prefect.Flow(name="test", storage=prefect.environments.storage.Memory()) as flow: a(prefect.Task()) flow.result_handler = None with pytest.raises(ClientError, match="required to have a result handler"): flow_id = client.register( flow, project_name="my-default-project", compressed=compressed, version_group_id=str(uuid.uuid4()), )