test: migrate rpc tests to pytest asyncio

This commit is contained in:
lda
2026-06-04 18:54:42 +07:00 Unverified
parent f764b1717f
commit f9673a4ad0
5 changed files with 865 additions and 949 deletions
+2
View File
@@ -28,12 +28,14 @@ dev = [
"basedpyright>=1.39.6", "basedpyright>=1.39.6",
"pytest>=8", "pytest>=8",
# "pytest-sugar>=1", # "pytest-sugar>=1",
"pytest-asyncio>=1.4.0",
"ruff>=0.15.15", "ruff>=0.15.15",
] ]
[tool.pytest.ini_options] [tool.pytest.ini_options]
addopts = "-p no:cacheprovider" addopts = "-p no:cacheprovider"
pythonpath = ["."] pythonpath = ["."]
asyncio_mode = "auto"
[tool.uv] [tool.uv]
package = true package = true
+7 -29
View File
@@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
import asyncio
from typing import Any from typing import Any
import httpx import httpx
@@ -22,8 +21,7 @@ async def _rpc(
return response.json() return response.json()
def test_rpc_health_and_capability_methods(tmp_path) -> None: async def test_rpc_health_and_capability_methods(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -49,11 +47,8 @@ def test_rpc_health_and_capability_methods(tmp_path) -> None:
assert listed["result"]["capabilities"] assert listed["result"]["capabilities"]
assert inspected["result"]["name"] == "wf.std.constant" assert inspected["result"]["name"] == "wf.std.constant"
asyncio.run(scenario())
async def test_rpc_unknown_method_returns_json_rpc_error(tmp_path) -> None:
def test_rpc_unknown_method_returns_json_rpc_error(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -65,11 +60,8 @@ def test_rpc_unknown_method_returns_json_rpc_error(tmp_path) -> None:
assert payload["error"]["code"] == -32601 assert payload["error"]["code"] == -32601
assert payload["error"]["message"] == "Method not found" assert payload["error"]["message"] == "Method not found"
asyncio.run(scenario())
async def test_rpc_app_mounts_configured_rpc_path(tmp_path) -> None:
def test_rpc_app_mounts_configured_rpc_path(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server, rpc_path="/workflow-rpc") app = create_rpc_app(server, rpc_path="/workflow-rpc")
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -89,11 +81,8 @@ def test_rpc_app_mounts_configured_rpc_path(tmp_path) -> None:
assert response.status_code == 200 assert response.status_code == 200
assert response.json()["result"]["status"] == "ok" assert response.json()["result"]["status"] == "ok"
asyncio.run(scenario())
async def test_rpc_draft_artifact_deployment_lifecycle(tmp_path) -> None:
def test_rpc_draft_artifact_deployment_lifecycle(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -208,11 +197,8 @@ def test_rpc_draft_artifact_deployment_lifecycle(tmp_path) -> None:
assert deployment["result"]["deployment_id"] == "constant_rpc.default" assert deployment["result"]["deployment_id"] == "constant_rpc.default"
assert validate_deployment["result"]["status"] == "runnable" assert validate_deployment["result"]["status"] == "runnable"
asyncio.run(scenario())
async def test_rpc_artifact_and_deployment_catalog_methods(tmp_path) -> None:
def test_rpc_artifact_and_deployment_catalog_methods(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
await server.api.create_artifact_from_plan( await server.api.create_artifact_from_plan(
artifact_id="rpc_lifecycle", artifact_id="rpc_lifecycle",
@@ -260,11 +246,8 @@ def test_rpc_artifact_and_deployment_catalog_methods(tmp_path) -> None:
assert inspected_deployment["result"]["id"] == "rpc_lifecycle.default" assert inspected_deployment["result"]["id"] == "rpc_lifecycle.default"
assert deleted["result"]["deployment_id"] == "rpc_lifecycle.default" assert deleted["result"]["deployment_id"] == "rpc_lifecycle.default"
asyncio.run(scenario())
async def test_rpc_draft_workspace_methods(tmp_path) -> None:
def test_rpc_draft_workspace_methods(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -326,8 +309,6 @@ def test_rpc_draft_workspace_methods(tmp_path) -> None:
assert patched["result"]["revision"] == created["result"]["revision"] + 1 assert patched["result"]["revision"] == created["result"]["revision"] + 1
assert artifact["result"]["artifact_id"] == "remote_artifact" assert artifact["result"]["artifact_id"] == "remote_artifact"
asyncio.run(scenario())
def _constant_plan() -> RawWorkflowPlan: def _constant_plan() -> RawWorkflowPlan:
return RawWorkflowPlan.model_validate( return RawWorkflowPlan.model_validate(
@@ -377,8 +358,7 @@ def _constant_plan() -> RawWorkflowPlan:
) )
def test_rpc_runs_deployment_and_reads_bounded_trace(tmp_path) -> None: async def test_rpc_runs_deployment_and_reads_bounded_trace(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
await server.api.create_artifact_from_plan( await server.api.create_artifact_from_plan(
artifact_id="rpc_constant", artifact_id="rpc_constant",
@@ -432,5 +412,3 @@ def test_rpc_runs_deployment_and_reads_bounded_trace(tmp_path) -> None:
assert trace["result"]["trace_start"] == 0 assert trace["result"]["trace_start"] == 0
assert trace["result"]["trace_limit"] == 1 assert trace["result"]["trace_limit"] == 1
assert len(trace["result"]["trace"]) == 1 assert len(trace["result"]["trace"]) == 1
asyncio.run(scenario())
+8 -34
View File
@@ -1,7 +1,5 @@
from __future__ import annotations from __future__ import annotations
import asyncio
import httpx import httpx
from wf_api.models import RawWorkflowPlan, TraceRange from wf_api.models import RawWorkflowPlan, TraceRange
@@ -58,8 +56,7 @@ def _constant_plan() -> RawWorkflowPlan:
) )
def test_rpc_workflow_client_lists_and_inspects_capabilities(tmp_path) -> None: async def test_rpc_workflow_client_lists_and_inspects_capabilities(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -80,11 +77,8 @@ def test_rpc_workflow_client_lists_and_inspects_capabilities(tmp_path) -> None:
assert listed["capabilities"] assert listed["capabilities"]
assert inspected["name"] == "wf.std.constant" assert inspected["name"] == "wf.std.constant"
asyncio.run(scenario())
async def test_rpc_workflow_client_lists_and_inspects_sources(tmp_path) -> None:
def test_rpc_workflow_client_lists_and_inspects_sources(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -104,11 +98,8 @@ def test_rpc_workflow_client_lists_and_inspects_sources(tmp_path) -> None:
assert "wf.std" in source_ids assert "wf.std" in source_ids
assert inspected["id"] == "wf.std" assert inspected["id"] == "wf.std"
asyncio.run(scenario())
async def test_rpc_workflow_client_reads_admin_state(tmp_path) -> None:
def test_rpc_workflow_client_reads_admin_state(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
server.events.record_workflow_event( server.events.record_workflow_event(
"workflow_test_event", "workflow_test_event",
@@ -135,11 +126,8 @@ def test_rpc_workflow_client_reads_admin_state(tmp_path) -> None:
assert events["total"] == 1 assert events["total"] == 1
assert events["events"][0]["kind"] == "workflow_test_event" assert events["events"][0]["kind"] == "workflow_test_event"
asyncio.run(scenario())
async def test_rpc_workflow_client_runs_and_reads_trace(tmp_path) -> None:
def test_rpc_workflow_client_runs_and_reads_trace(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
await server.api.create_artifact_from_plan( await server.api.create_artifact_from_plan(
artifact_id="client_constant", artifact_id="client_constant",
@@ -184,11 +172,8 @@ def test_rpc_workflow_client_runs_and_reads_trace(tmp_path) -> None:
assert inspected["trace_count"] >= 1 assert inspected["trace_count"] >= 1
assert len(trace["trace"]) == 1 assert len(trace["trace"]) == 1
asyncio.run(scenario())
async def test_rpc_workflow_client_raises_for_rpc_error(tmp_path) -> None:
def test_rpc_workflow_client_raises_for_rpc_error(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -211,11 +196,8 @@ def test_rpc_workflow_client_raises_for_rpc_error(tmp_path) -> None:
assert "Workflow operation failed" in message assert "Workflow operation failed" in message
assert "missing.capability" in message assert "missing.capability" in message
asyncio.run(scenario())
async def test_rpc_workflow_client_lists_and_inspects_artifacts(tmp_path) -> None:
def test_rpc_workflow_client_lists_and_inspects_artifacts(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
await server.api.create_artifact_from_plan( await server.api.create_artifact_from_plan(
artifact_id="client_art", artifact_id="client_art",
@@ -241,13 +223,10 @@ def test_rpc_workflow_client_lists_and_inspects_artifacts(tmp_path) -> None:
assert listed["nodes"] assert listed["nodes"]
assert inspected["id"] == "client_art" assert inspected["id"] == "client_art"
asyncio.run(scenario())
async def test_rpc_workflow_client_lists_inspects_validates_and_deletes_deployments(
def test_rpc_workflow_client_lists_inspects_validates_and_deletes_deployments(
tmp_path, tmp_path,
) -> None: ) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
await server.api.create_artifact_from_plan( await server.api.create_artifact_from_plan(
artifact_id="client_deploy_art", artifact_id="client_deploy_art",
@@ -289,11 +268,8 @@ def test_rpc_workflow_client_lists_inspects_validates_and_deletes_deployments(
assert validated["status"] == "runnable" assert validated["status"] == "runnable"
assert deleted["deployment_id"] == "client_deploy_art.default" assert deleted["deployment_id"] == "client_deploy_art.default"
asyncio.run(scenario())
async def test_rpc_workflow_client_draft_workspace_lifecycle(tmp_path) -> None:
def test_rpc_workflow_client_draft_workspace_lifecycle(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -335,5 +311,3 @@ def test_rpc_workflow_client_draft_workspace_lifecycle(tmp_path) -> None:
assert validated["status"] in {"valid", "invalid"} assert validated["status"] in {"valid", "invalid"}
assert patched["revision"] == created["revision"] + 1 assert patched["revision"] == created["revision"] + 1
assert artifact["artifact_id"] == "client_ws_art" assert artifact["artifact_id"] == "client_ws_art"
asyncio.run(scenario())
@@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
import asyncio
from dataclasses import dataclass, replace from dataclasses import dataclass, replace
from typing import Any from typing import Any
@@ -100,8 +99,7 @@ def _server_with_mutation_provider(tmp_path: Any) -> Any:
# --- read-only tests (unchanged) --- # --- read-only tests (unchanged) ---
def test_rpc_source_registry_list_unavailable_on_local_static(tmp_path) -> None: async def test_rpc_source_registry_list_unavailable_on_local_static(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -115,11 +113,8 @@ def test_rpc_source_registry_list_unavailable_on_local_static(tmp_path) -> None:
assert "error" in payload assert "error" in payload
assert payload["error"]["data"]["code"] == "source_registry_unavailable" assert payload["error"]["data"]["code"] == "source_registry_unavailable"
asyncio.run(scenario())
async def test_rpc_source_registry_inspect_unavailable_on_local_static(tmp_path) -> None:
def test_rpc_source_registry_inspect_unavailable_on_local_static(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -135,11 +130,8 @@ def test_rpc_source_registry_inspect_unavailable_on_local_static(tmp_path) -> No
assert "error" in payload assert "error" in payload
assert payload["error"]["data"]["code"] == "source_registry_unavailable" assert payload["error"]["data"]["code"] == "source_registry_unavailable"
asyncio.run(scenario())
async def test_rpc_source_registry_methods_return_registry_payloads(tmp_path) -> None:
def test_rpc_source_registry_methods_return_registry_payloads(tmp_path) -> None:
async def scenario() -> None:
server = replace( server = replace(
build_local_static_workflow_server(tmp_path / "store"), build_local_static_workflow_server(tmp_path / "store"),
source_registry_admin=WorkflowSourceRegistryApi( source_registry_admin=WorkflowSourceRegistryApi(
@@ -165,14 +157,11 @@ def test_rpc_source_registry_methods_return_registry_payloads(tmp_path) -> None:
assert inspected["result"]["entry"]["transport"]["kind"] == "stdio" assert inspected["result"]["entry"]["transport"]["kind"] == "stdio"
assert inspected["result"]["shadowed_by_config"] is True assert inspected["result"]["shadowed_by_config"] is True
asyncio.run(scenario())
# --- mutation unavailable tests --- # --- mutation unavailable tests ---
def test_rpc_source_registry_add_unavailable_on_local_static(tmp_path) -> None: async def test_rpc_source_registry_add_unavailable_on_local_static(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -188,11 +177,8 @@ def test_rpc_source_registry_add_unavailable_on_local_static(tmp_path) -> None:
assert "error" in payload assert "error" in payload
assert payload["error"]["data"]["code"] == "source_registry_unavailable" assert payload["error"]["data"]["code"] == "source_registry_unavailable"
asyncio.run(scenario())
async def test_rpc_source_registry_update_unavailable_on_local_static(tmp_path) -> None:
def test_rpc_source_registry_update_unavailable_on_local_static(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -208,11 +194,8 @@ def test_rpc_source_registry_update_unavailable_on_local_static(tmp_path) -> Non
assert "error" in payload assert "error" in payload
assert payload["error"]["data"]["code"] == "source_registry_unavailable" assert payload["error"]["data"]["code"] == "source_registry_unavailable"
asyncio.run(scenario())
async def test_rpc_source_registry_enable_unavailable_on_local_static(tmp_path) -> None:
def test_rpc_source_registry_enable_unavailable_on_local_static(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -228,11 +211,8 @@ def test_rpc_source_registry_enable_unavailable_on_local_static(tmp_path) -> Non
assert "error" in payload assert "error" in payload
assert payload["error"]["data"]["code"] == "source_registry_unavailable" assert payload["error"]["data"]["code"] == "source_registry_unavailable"
asyncio.run(scenario())
async def test_rpc_source_registry_disable_unavailable_on_local_static(tmp_path) -> None:
def test_rpc_source_registry_disable_unavailable_on_local_static(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -248,11 +228,8 @@ def test_rpc_source_registry_disable_unavailable_on_local_static(tmp_path) -> No
assert "error" in payload assert "error" in payload
assert payload["error"]["data"]["code"] == "source_registry_unavailable" assert payload["error"]["data"]["code"] == "source_registry_unavailable"
asyncio.run(scenario())
async def test_rpc_source_registry_remove_unavailable_on_local_static(tmp_path) -> None:
def test_rpc_source_registry_remove_unavailable_on_local_static(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -268,14 +245,11 @@ def test_rpc_source_registry_remove_unavailable_on_local_static(tmp_path) -> Non
assert "error" in payload assert "error" in payload
assert payload["error"]["data"]["code"] == "source_registry_unavailable" assert payload["error"]["data"]["code"] == "source_registry_unavailable"
asyncio.run(scenario())
# --- mutation success tests --- # --- mutation success tests ---
def test_rpc_source_registry_add_returns_entry(tmp_path) -> None: async def test_rpc_source_registry_add_returns_entry(tmp_path) -> None:
async def scenario() -> None:
server = _server_with_mutation_provider(tmp_path) server = _server_with_mutation_provider(tmp_path)
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -292,11 +266,8 @@ def test_rpc_source_registry_add_returns_entry(tmp_path) -> None:
assert payload["result"]["entry"]["id"] == "new.mcp" assert payload["result"]["entry"]["id"] == "new.mcp"
assert payload["result"]["entry"]["kind"] == "mcp" assert payload["result"]["entry"]["kind"] == "mcp"
asyncio.run(scenario())
async def test_rpc_source_registry_update_returns_entry(tmp_path) -> None:
def test_rpc_source_registry_update_returns_entry(tmp_path) -> None:
async def scenario() -> None:
server = _server_with_mutation_provider(tmp_path) server = _server_with_mutation_provider(tmp_path)
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -313,11 +284,8 @@ def test_rpc_source_registry_update_returns_entry(tmp_path) -> None:
assert payload["result"]["entry"]["id"] == "github.work" assert payload["result"]["entry"]["id"] == "github.work"
assert payload["result"]["entry"]["enabled"] is False assert payload["result"]["entry"]["enabled"] is False
asyncio.run(scenario())
async def test_rpc_source_registry_enable_returns_entry(tmp_path) -> None:
def test_rpc_source_registry_enable_returns_entry(tmp_path) -> None:
async def scenario() -> None:
mutation = FakeMutationProvider() mutation = FakeMutationProvider()
mutation.entries["github.work"]["enabled"] = False mutation.entries["github.work"]["enabled"] = False
server = replace( server = replace(
@@ -341,11 +309,8 @@ def test_rpc_source_registry_enable_returns_entry(tmp_path) -> None:
assert "result" in payload assert "result" in payload
assert payload["result"]["entry"]["enabled"] is True assert payload["result"]["entry"]["enabled"] is True
asyncio.run(scenario())
async def test_rpc_source_registry_disable_returns_entry(tmp_path) -> None:
def test_rpc_source_registry_disable_returns_entry(tmp_path) -> None:
async def scenario() -> None:
server = _server_with_mutation_provider(tmp_path) server = _server_with_mutation_provider(tmp_path)
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -361,11 +326,8 @@ def test_rpc_source_registry_disable_returns_entry(tmp_path) -> None:
assert "result" in payload assert "result" in payload
assert payload["result"]["entry"]["enabled"] is False assert payload["result"]["entry"]["enabled"] is False
asyncio.run(scenario())
async def test_rpc_source_registry_remove_returns_removed(tmp_path) -> None:
def test_rpc_source_registry_remove_returns_removed(tmp_path) -> None:
async def scenario() -> None:
server = _server_with_mutation_provider(tmp_path) server = _server_with_mutation_provider(tmp_path)
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -382,14 +344,11 @@ def test_rpc_source_registry_remove_returns_removed(tmp_path) -> None:
assert payload["result"]["removed"] is True assert payload["result"]["removed"] is True
assert payload["result"]["source_id"] == "github.work" assert payload["result"]["source_id"] == "github.work"
asyncio.run(scenario())
# --- mutation error tests --- # --- mutation error tests ---
def test_rpc_source_registry_add_missing_entry_raises_error(tmp_path) -> None: async def test_rpc_source_registry_add_missing_entry_raises_error(tmp_path) -> None:
async def scenario() -> None:
server = _server_with_mutation_provider(tmp_path) server = _server_with_mutation_provider(tmp_path)
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -404,11 +363,8 @@ def test_rpc_source_registry_add_missing_entry_raises_error(tmp_path) -> None:
assert "error" in payload assert "error" in payload
asyncio.run(scenario())
async def test_rpc_source_registry_update_missing_source_raises_error(tmp_path) -> None:
def test_rpc_source_registry_update_missing_source_raises_error(tmp_path) -> None:
async def scenario() -> None:
server = _server_with_mutation_provider(tmp_path) server = _server_with_mutation_provider(tmp_path)
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -423,11 +379,8 @@ def test_rpc_source_registry_update_missing_source_raises_error(tmp_path) -> Non
assert "error" in payload assert "error" in payload
asyncio.run(scenario())
async def test_rpc_source_registry_remove_missing_source_raises_error(tmp_path) -> None:
def test_rpc_source_registry_remove_missing_source_raises_error(tmp_path) -> None:
async def scenario() -> None:
server = _server_with_mutation_provider(tmp_path) server = _server_with_mutation_provider(tmp_path)
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -442,14 +395,11 @@ def test_rpc_source_registry_remove_missing_source_raises_error(tmp_path) -> Non
assert "error" in payload assert "error" in payload
asyncio.run(scenario())
# --- client method tests --- # --- client method tests ---
def test_rpc_client_source_registry_calls_correct_methods(tmp_path) -> None: async def test_rpc_client_source_registry_calls_correct_methods(tmp_path) -> None:
async def scenario() -> None:
server = build_local_static_workflow_server(tmp_path / "store") server = build_local_static_workflow_server(tmp_path / "store")
app = create_rpc_app(server) app = create_rpc_app(server)
transport = httpx.ASGITransport(app=app) transport = httpx.ASGITransport(app=app)
@@ -480,10 +430,8 @@ def test_rpc_client_source_registry_calls_correct_methods(tmp_path) -> None:
assert inspect_error is not None assert inspect_error is not None
assert "source registry admin reads are not available" in inspect_error assert "source registry admin reads are not available" in inspect_error
asyncio.run(scenario())
async def test_rpc_client_source_registry_mutation_methods_exist() -> None:
def test_rpc_client_source_registry_mutation_methods_exist() -> None:
from wf_transport_rpc_http.client import RpcWorkflowApiClient from wf_transport_rpc_http.client import RpcWorkflowApiClient
client = RpcWorkflowApiClient.__new__(RpcWorkflowApiClient) client = RpcWorkflowApiClient.__new__(RpcWorkflowApiClient)
@@ -495,31 +443,31 @@ def test_rpc_client_source_registry_mutation_methods_exist() -> None:
client._call = fake_call # type: ignore[assignment] client._call = fake_call # type: ignore[assignment]
asyncio.run(client.add_registry_entry(entry={"id": "x", "kind": "mcp"})) await client.add_registry_entry(entry={"id": "x", "kind": "mcp"})
assert calls[-1] == ( assert calls[-1] == (
"workflow.admin.source_registry.add", "workflow.admin.source_registry.add",
{"entry": {"id": "x", "kind": "mcp"}}, {"entry": {"id": "x", "kind": "mcp"}},
) )
asyncio.run(client.update_registry_entry(source_id="s", patch={"enabled": False})) await client.update_registry_entry(source_id="s", patch={"enabled": False})
assert calls[-1] == ( assert calls[-1] == (
"workflow.admin.source_registry.update", "workflow.admin.source_registry.update",
{"source_id": "s", "patch": {"enabled": False}}, {"source_id": "s", "patch": {"enabled": False}},
) )
asyncio.run(client.enable_registry_entry(source_id="s")) await client.enable_registry_entry(source_id="s")
assert calls[-1] == ( assert calls[-1] == (
"workflow.admin.source_registry.enable", "workflow.admin.source_registry.enable",
{"source_id": "s"}, {"source_id": "s"},
) )
asyncio.run(client.disable_registry_entry(source_id="s")) await client.disable_registry_entry(source_id="s")
assert calls[-1] == ( assert calls[-1] == (
"workflow.admin.source_registry.disable", "workflow.admin.source_registry.disable",
{"source_id": "s"}, {"source_id": "s"},
) )
asyncio.run(client.remove_registry_entry(source_id="s")) await client.remove_registry_entry(source_id="s")
assert calls[-1] == ( assert calls[-1] == (
"workflow.admin.source_registry.remove", "workflow.admin.source_registry.remove",
{"source_id": "s"}, {"source_id": "s"},
Generated
+14
View File
@@ -660,6 +660,7 @@ dependencies = [
dev = [ dev = [
{ name = "basedpyright" }, { name = "basedpyright" },
{ name = "pytest" }, { name = "pytest" },
{ name = "pytest-asyncio" },
{ name = "ruff" }, { name = "ruff" },
] ]
@@ -681,6 +682,7 @@ requires-dist = [
dev = [ dev = [
{ name = "basedpyright", specifier = ">=1.39.6" }, { name = "basedpyright", specifier = ">=1.39.6" },
{ name = "pytest", specifier = ">=8" }, { name = "pytest", specifier = ">=8" },
{ name = "pytest-asyncio", specifier = ">=1.4.0" },
{ name = "ruff", specifier = ">=0.15.15" }, { name = "ruff", specifier = ">=0.15.15" },
] ]
@@ -1065,6 +1067,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" },
] ]
[[package]]
name = "pytest-asyncio"
version = "1.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pytest" },
]
sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42", size = 58514, upload-time = "2026-05-26T09:56:04.083Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" },
]
[[package]] [[package]]
name = "python-dotenv" name = "python-dotenv"
version = "1.2.2" version = "1.2.2"