test: isolate file stores with tmp_path

This commit is contained in:
lda
2026-06-04 18:18:41 +07:00 Unverified
parent 65ac9c5c0f
commit 71a6519658
9 changed files with 153 additions and 149 deletions
+16 -15
View File
@@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio
from dataclasses import replace
from pathlib import Path
from typing import Any
from wf_artifacts import (
@@ -19,7 +20,7 @@ from wf_mcp.storage import FileStore
from wf_mcp.workflow_surface import WorkflowSurfaceHandlers
from wf_mcp.broker.service.workflow_operation_context import context_from_service
from tests.wf_mcp.test_support import echo_tool, local_temp_root
from tests.wf_mcp.test_support import echo_tool
def _echo_draft() -> dict[str, Any]:
@@ -131,8 +132,8 @@ def _artifact_api(
return WorkflowArtifactApi(context), service
def test_save_artifact_stores_and_returns_saved() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "artifacts_save")
def test_save_artifact_stores_and_returns_saved(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "artifacts_save")
api, _service = _artifact_api(artifact_store)
result = asyncio.run(api.save_artifact(_echo_artifact().model_dump(mode="json")))
@@ -144,8 +145,8 @@ def test_save_artifact_stores_and_returns_saved() -> None:
assert saved.id == "echo"
def test_list_artifacts_returns_empty_page_without_artifact_store() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "artifacts_no_store")
def test_list_artifacts_returns_empty_page_without_artifact_store(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "artifacts_no_store")
_api, service = _artifact_api(artifact_store)
context = replace(context_from_service(service), artifact_store=None)
api = WorkflowArtifactApi(context)
@@ -157,9 +158,9 @@ def test_list_artifacts_returns_empty_page_without_artifact_store() -> None:
assert result["total"] == 0
def test_create_artifact_from_plan_saves_with_observed_node_specs() -> None:
def test_create_artifact_from_plan_saves_with_observed_node_specs(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "artifacts_from_plan"
tmp_path / "artifacts_from_plan"
)
api, _service = _artifact_api(artifact_store, register_echo=True)
@@ -179,9 +180,9 @@ def test_create_artifact_from_plan_saves_with_observed_node_specs() -> None:
assert saved.id == "echo"
def test_create_artifact_from_workspace_returns_saved_false_when_invalid() -> None:
def test_create_artifact_from_workspace_returns_saved_false_when_invalid(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "artifacts_workspace_invalid"
tmp_path / "artifacts_workspace_invalid"
)
api, service = _artifact_api(artifact_store, register_echo=True)
draft = _echo_draft()
@@ -211,9 +212,9 @@ def test_create_artifact_from_workspace_returns_saved_false_when_invalid() -> No
assert result["status"] == "invalid"
def test_create_wrapper_from_workspace_saves_kind_wrapper() -> None:
def test_create_wrapper_from_workspace_saves_kind_wrapper(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "artifacts_wrapper_workspace"
tmp_path / "artifacts_wrapper_workspace"
)
api, service = _artifact_api(artifact_store, register_echo=True)
from wf_api.drafts import WorkflowDraftApi
@@ -242,8 +243,8 @@ def test_create_wrapper_from_workspace_saves_kind_wrapper() -> None:
assert saved.kind == "wrapper"
def test_inspect_artifact_returns_stable_fields() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "artifacts_inspect")
def test_inspect_artifact_returns_stable_fields(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "artifacts_inspect")
api, _service = _artifact_api(artifact_store)
artifact_store.save_artifact(_echo_artifact())
@@ -255,10 +256,10 @@ def test_inspect_artifact_returns_stable_fields() -> None:
assert "plan" in result
def test_handler_delegation_for_inspect_artifact() -> None:
def test_handler_delegation_for_inspect_artifact(tmp_path: Path) -> None:
"""WorkflowSurfaceHandlers.inspect_artifact delegates to WorkflowArtifactApi."""
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "artifacts_delegation"
tmp_path / "artifacts_delegation"
)
mcp_root = artifact_store.root / "delegation_mcp"
service = WfMcpService(
+5 -3
View File
@@ -1,5 +1,7 @@
from __future__ import annotations
from pathlib import Path
import pytest
from wf_api.artifact_plans import plan_field, plan_nodes, raw_plan_from_artifact
@@ -63,15 +65,15 @@ def test_required_capability_payloads_sorts_by_name() -> None:
assert "kind" in first
def test_observed_node_specs_projects_enabled_context_specs() -> None:
def test_observed_node_specs_projects_enabled_context_specs(tmp_path: Path) -> None:
from wf_artifacts import FileWorkflowArtifactStore
from wf_mcp.broker import WfMcpService
from wf_mcp.models import ConnectionConfig
from wf_mcp.storage import FileStore
from wf_mcp.broker.service.workflow_operation_context import context_from_service
from tests.wf_mcp.test_support import echo_tool, local_temp_root
from tests.wf_mcp.test_support import echo_tool
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "cap_req_helpers")
artifact_store = FileWorkflowArtifactStore(tmp_path / "cap_req_helpers")
service = WfMcpService(
store=FileStore(artifact_store.root / "mcp"),
artifact_store=artifact_store,
+24 -23
View File
@@ -1,6 +1,7 @@
from __future__ import annotations
import asyncio
from pathlib import Path
import pytest
@@ -12,7 +13,7 @@ from wf_mcp.storage import FileStore
from wf_mcp.workflow_surface import WorkflowSurfaceHandlers
from wf_mcp.broker.service.workflow_operation_context import context_from_service
from tests.wf_mcp.test_support import echo_tool, local_temp_root
from tests.wf_mcp.test_support import echo_tool
from tests.wf_mcp.workflow_surface.conftest import echo_artifact, failing_tool
@@ -42,8 +43,8 @@ def _capability_api(
return WorkflowCapabilityApi(context), service
def test_list_capabilities_returns_planner_visible_sources() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "cap_api_list")
def test_list_capabilities_returns_planner_visible_sources(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "cap_api_list")
api, _service = _capability_api(artifact_store, register_echo=True)
result = asyncio.run(api.list_capabilities())
@@ -62,9 +63,9 @@ def test_list_capabilities_returns_planner_visible_sources() -> None:
assert "output_fields" in first
def test_list_capabilities_filters_by_source() -> None:
def test_list_capabilities_filters_by_source(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "cap_api_list_filter"
tmp_path / "cap_api_list_filter"
)
api, _service = _capability_api(artifact_store, register_echo=True)
@@ -73,8 +74,8 @@ def test_list_capabilities_filters_by_source() -> None:
assert [item["name"] for item in result["capabilities"]] == ["wf.std.truthy"]
def test_inspect_capability_returns_detail_with_wrapper_hints() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "cap_api_inspect")
def test_inspect_capability_returns_detail_with_wrapper_hints(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "cap_api_inspect")
api, _service = _capability_api(artifact_store, register_echo=True)
detail = asyncio.run(
@@ -89,9 +90,9 @@ def test_inspect_capability_returns_detail_with_wrapper_hints() -> None:
assert hints["output_map"] == {"echoed": "state.echoed"}
def test_inspect_capability_raises_on_unknown() -> None:
def test_inspect_capability_raises_on_unknown(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "cap_api_inspect_unknown"
tmp_path / "cap_api_inspect_unknown"
)
api, _service = _capability_api(artifact_store, register_echo=True)
@@ -99,8 +100,8 @@ def test_inspect_capability_raises_on_unknown() -> None:
asyncio.run(api.inspect_capability(qualified_name="no.such.capability"))
def test_call_capability_node_spec_success() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "cap_api_call")
def test_call_capability_node_spec_success(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "cap_api_call")
api, _service = _capability_api(artifact_store, register_echo=True)
result = asyncio.run(
@@ -117,8 +118,8 @@ def test_call_capability_node_spec_success() -> None:
assert result["deployment_id"] is None
def test_call_capability_node_spec_failure() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "cap_api_call_fail")
def test_call_capability_node_spec_failure(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "cap_api_call_fail")
api, _service = _capability_api(artifact_store, register_failing=True)
result = asyncio.run(
@@ -134,9 +135,9 @@ def test_call_capability_node_spec_failure() -> None:
assert result["diagnostics"][0]["code"] == "capability_call_failed"
def test_list_capabilities_includes_saved_wrapper() -> None:
def test_list_capabilities_includes_saved_wrapper(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "cap_api_wrapper_list"
tmp_path / "cap_api_wrapper_list"
)
artifact_store.save_artifact(
echo_artifact().model_copy(
@@ -165,9 +166,9 @@ def test_list_capabilities_includes_saved_wrapper() -> None:
assert row["output_fields"] == ["echoed"]
def test_inspect_capability_saved_wrapper() -> None:
def test_inspect_capability_saved_wrapper(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "cap_api_wrapper_inspect"
tmp_path / "cap_api_wrapper_inspect"
)
artifact_store.save_artifact(
echo_artifact().model_copy(update={"id": "echo_wrapper", "kind": "wrapper"})
@@ -194,9 +195,9 @@ def test_inspect_capability_saved_wrapper() -> None:
assert hints["output_map"] == {"echoed": "state.echoed"}
def test_call_capability_saved_wrapper() -> None:
def test_call_capability_saved_wrapper(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "cap_api_wrapper_call"
tmp_path / "cap_api_wrapper_call"
)
artifact_store.save_artifact(
echo_artifact().model_copy(update={"id": "echo_wrapper", "kind": "wrapper"})
@@ -215,9 +216,9 @@ def test_call_capability_saved_wrapper() -> None:
assert result["diagnostics"] == []
def test_create_draft_workspace_from_capability() -> None:
def test_create_draft_workspace_from_capability(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "cap_api_draft_bootstrap"
tmp_path / "cap_api_draft_bootstrap"
)
api, _service = _capability_api(artifact_store, register_echo=True)
@@ -240,9 +241,9 @@ def test_create_draft_workspace_from_capability() -> None:
assert fetched["draft"]["steps"]["call"]["use"] == "demo.personal.echo_tool"
def test_handler_delegates_to_capability_api() -> None:
def test_handler_delegates_to_capability_api(tmp_path: Path) -> None:
"""WorkflowSurfaceHandlers methods produce the same result as direct API."""
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "cap_api_delegation")
artifact_store = FileWorkflowArtifactStore(tmp_path / "cap_api_delegation")
mcp_root = artifact_store.root / "delegation_mcp"
service = WfMcpService(
store=FileStore(mcp_root),
+16 -15
View File
@@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio
from dataclasses import replace
from pathlib import Path
from typing import Any, cast
from wf_artifacts import (
@@ -21,7 +22,7 @@ from wf_mcp.storage import FileStore
from wf_mcp.workflow_surface import WorkflowSurfaceHandlers
from wf_mcp.broker.service.workflow_operation_context import context_from_service
from tests.wf_mcp.test_support import echo_tool, local_temp_root
from tests.wf_mcp.test_support import echo_tool
def _echo_artifact() -> WorkflowArtifact:
@@ -97,8 +98,8 @@ def _deployment_api(
return WorkflowDeploymentApi(context), service
def test_save_deployment_stores_and_returns_stable_fields() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "deploy_save")
def test_save_deployment_stores_and_returns_stable_fields(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_save")
api, _service = _deployment_api(artifact_store)
result = asyncio.run(
@@ -120,8 +121,8 @@ def test_save_deployment_stores_and_returns_stable_fields() -> None:
assert result["artifact_version"] == 1
def test_list_deployments_returns_compact_summaries() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "deploy_list")
def test_list_deployments_returns_compact_summaries(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_list")
api, _service = _deployment_api(artifact_store)
artifact_store.save_deployment(
WorkflowDeployment(
@@ -140,8 +141,8 @@ def test_list_deployments_returns_compact_summaries() -> None:
assert "bindings" not in result["deployments"][0]
def test_list_deployments_returns_empty_without_artifact_store() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "deploy_no_store")
def test_list_deployments_returns_empty_without_artifact_store(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_no_store")
_api, service = _deployment_api(artifact_store)
context = replace(context_from_service(service), artifact_store=None)
api = WorkflowDeploymentApi(context)
@@ -151,8 +152,8 @@ def test_list_deployments_returns_empty_without_artifact_store() -> None:
assert result["deployments"] == []
def test_delete_deployment_removes_one() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "deploy_delete")
def test_delete_deployment_removes_one(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_delete")
api, _service = _deployment_api(artifact_store)
artifact_store.save_deployment(
WorkflowDeployment(
@@ -170,9 +171,9 @@ def test_delete_deployment_removes_one() -> None:
assert artifact_store.list_deployments() == []
def test_validate_deployment_returns_runnable_for_valid_binding() -> None:
def test_validate_deployment_returns_runnable_for_valid_binding(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "deploy_validate_runnable"
tmp_path / "deploy_validate_runnable"
)
api, service = _deployment_api(artifact_store, register_echo=True)
artifact_store.save_artifact(_echo_artifact())
@@ -202,9 +203,9 @@ class FailingLivenessAdapter:
raise OSError("stdio process exited")
def test_validate_deployment_live_check_calls_live_checker() -> None:
def test_validate_deployment_live_check_calls_live_checker(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "deploy_validate_live"
tmp_path / "deploy_validate_live"
)
api, service = _deployment_api(artifact_store, register_echo=True)
artifact_store.save_artifact(_echo_artifact())
@@ -229,9 +230,9 @@ def test_validate_deployment_live_check_calls_live_checker() -> None:
assert result["diagnostics"][0]["code"] == "source_unreachable"
def test_handler_delegation_for_validate_deployment() -> None:
def test_handler_delegation_for_validate_deployment(tmp_path: Path) -> None:
"""WorkflowSurfaceHandlers.validate_deployment delegates to WorkflowDeploymentApi."""
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "deploy_delegation")
artifact_store = FileWorkflowArtifactStore(tmp_path / "deploy_delegation")
service = WfMcpService(
store=FileStore(artifact_store.root / "delegation_mcp"),
artifact_store=artifact_store,
+9 -9
View File
@@ -1,6 +1,7 @@
from __future__ import annotations
import asyncio
from pathlib import Path
from wf_artifacts import FileWorkflowArtifactStore
from wf_api import WorkflowApi
@@ -14,11 +15,10 @@ from wf_mcp.broker.service.workflow_operation_context import context_from_servic
from wf_mcp.models import ConnectionConfig
from wf_mcp.storage import FileStore
from tests.wf_mcp.test_support import echo_tool, local_temp_root
from tests.wf_mcp.test_support import echo_tool
def _api() -> WorkflowApi:
root = local_temp_root() / "wf_api_direct_composition"
def _api(root: Path) -> WorkflowApi:
service = WfMcpService(
store=FileStore(root / "mcp"),
artifact_store=FileWorkflowArtifactStore(root),
@@ -30,8 +30,8 @@ def _api() -> WorkflowApi:
return WorkflowApi(context_from_service(service))
def test_workflow_api_composes_domain_services() -> None:
api = _api()
def test_workflow_api_composes_domain_services(tmp_path: Path) -> None:
api = _api(tmp_path / "wf_api_direct_composition")
assert isinstance(api.capabilities, WorkflowCapabilityApi)
assert isinstance(api.drafts, WorkflowDraftApi)
@@ -41,8 +41,8 @@ def test_workflow_api_composes_domain_services() -> None:
assert not hasattr(api, "backend")
def test_workflow_api_direct_capability_call() -> None:
api = _api()
def test_workflow_api_direct_capability_call(tmp_path: Path) -> None:
api = _api(tmp_path / "wf_api_direct_composition")
result = asyncio.run(
api.call_capability(
@@ -56,11 +56,11 @@ def test_workflow_api_direct_capability_call() -> None:
assert result["output"] == {"echoed": "hello"}
def test_workflow_surface_handlers_is_compatibility_shim() -> None:
def test_workflow_surface_handlers_is_compatibility_shim(tmp_path: Path) -> None:
from wf_api import WorkflowApi
from wf_mcp.workflow_surface import WorkflowSurfaceHandlers
root = local_temp_root() / "workflow_surface_handler_shim"
root = tmp_path / "workflow_surface_handler_shim"
service = WfMcpService(
store=FileStore(root / "mcp"),
artifact_store=FileWorkflowArtifactStore(root),
+20 -19
View File
@@ -1,6 +1,7 @@
from __future__ import annotations
import asyncio
from pathlib import Path
from typing import Any
from wf_artifacts import FileWorkflowArtifactStore, FileDraftWorkspaceStore
@@ -11,7 +12,7 @@ from wf_mcp.storage import FileStore
from wf_mcp.workflow_surface import WorkflowSurfaceHandlers
from wf_mcp.broker.service.workflow_operation_context import context_from_service
from tests.wf_mcp.test_support import echo_tool, local_temp_root
from tests.wf_mcp.test_support import echo_tool
def _echo_draft() -> dict[str, Any]:
@@ -70,8 +71,8 @@ def _draft_api(
return WorkflowDraftApi(context), service
def test_patch_draft_applies_json_patch() -> None:
artifact_store = FileWorkflowArtifactStore(local_temp_root() / "drafts_patch")
def test_patch_draft_applies_json_patch(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(tmp_path / "drafts_patch")
api, _service = _draft_api(artifact_store)
result = asyncio.run(
@@ -94,9 +95,9 @@ def test_patch_draft_applies_json_patch() -> None:
}
def test_create_draft_workspace_creates_workspace() -> None:
def test_create_draft_workspace_creates_workspace(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_create_workspace"
tmp_path / "drafts_create_workspace"
)
api, _service = _draft_api(artifact_store)
@@ -118,9 +119,9 @@ def test_create_draft_workspace_creates_workspace() -> None:
assert fetched["draft"]["steps"]["echo"]["use"] == "demo.personal.echo_tool"
def test_list_draft_workspaces_returns_sorted_summaries_without_drafts() -> None:
def test_list_draft_workspaces_returns_sorted_summaries_without_drafts(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_list_workspaces"
tmp_path / "drafts_list_workspaces"
)
api, _service = _draft_api(artifact_store)
asyncio.run(
@@ -148,9 +149,9 @@ def test_list_draft_workspaces_returns_sorted_summaries_without_drafts() -> None
assert "draft" not in result["workspaces"][0]
def test_delete_draft_workspace_is_idempotent() -> None:
def test_delete_draft_workspace_is_idempotent(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_delete_workspace"
tmp_path / "drafts_delete_workspace"
)
api, _service = _draft_api(artifact_store)
asyncio.run(
@@ -173,9 +174,9 @@ def test_delete_draft_workspace_is_idempotent() -> None:
assert listed["workspaces"] == []
def test_patch_draft_workspace_updates_revision() -> None:
def test_patch_draft_workspace_updates_revision(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_patch_workspace"
tmp_path / "drafts_patch_workspace"
)
api, _service = _draft_api(artifact_store)
asyncio.run(
@@ -197,9 +198,9 @@ def test_patch_draft_workspace_updates_revision() -> None:
assert patched["status"] == "valid"
def test_draft_workspace_patch_helpers_update_revision_and_bindings() -> None:
def test_draft_workspace_patch_helpers_update_revision_and_bindings(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_patch_helpers"
tmp_path / "drafts_patch_helpers"
)
api, _service = _draft_api(artifact_store)
asyncio.run(
@@ -265,9 +266,9 @@ def test_draft_workspace_patch_helpers_update_revision_and_bindings() -> None:
]
def test_validate_draft_workspace_refreshes_status() -> None:
def test_validate_draft_workspace_refreshes_status(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_validate_workspace"
tmp_path / "drafts_validate_workspace"
)
api, service = _draft_api(artifact_store, register_echo=True)
draft = _echo_draft()
@@ -288,9 +289,9 @@ def test_validate_draft_workspace_refreshes_status() -> None:
assert fetched["status"] == "invalid"
def test_create_minimal_draft_workspace_minimal_success_path() -> None:
def test_create_minimal_draft_workspace_minimal_success_path(tmp_path: Path) -> None:
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_minimal_workspace"
tmp_path / "drafts_minimal_workspace"
)
api, _service = _draft_api(artifact_store, register_echo=True)
@@ -323,10 +324,10 @@ def test_create_minimal_draft_workspace_minimal_success_path() -> None:
assert fetched["draft"]["steps"]["call"]["use"] == "demo.personal.echo_tool"
def test_delegation_smoke_validate_draft_equivalence() -> None:
def test_delegation_smoke_validate_draft_equivalence(tmp_path: Path) -> None:
"""WorkflowSurfaceHandlers.validate_draft delegates to WorkflowDraftApi."""
artifact_store = FileWorkflowArtifactStore(
local_temp_root() / "drafts_delegation_smoke"
tmp_path / "drafts_delegation_smoke"
)
mcp_root = artifact_store.root / "delegation_mcp"
service = WfMcpService(
+15 -15
View File
@@ -17,7 +17,7 @@ from wf_mcp.models import ConnectionConfig
from wf_mcp.storage import FileStore
from wf_mcp.workflow_surface import WorkflowSurfaceHandlers
from tests.wf_mcp.test_support import echo_tool, local_temp_root
from tests.wf_mcp.test_support import echo_tool
from tests.wf_mcp.workflow_surface.conftest import (
echo_artifact,
failing_artifact,
@@ -81,8 +81,8 @@ def _service_with_failing(
return service, artifact_store
def test_run_api_unrunnable_deployment() -> None:
root = local_temp_root() / "run_api_unrunnable"
def test_run_api_unrunnable_deployment(tmp_path: Path) -> None:
root = tmp_path / "run_api_unrunnable"
artifact_store = FileWorkflowArtifactStore(root)
from tests.wf_mcp.workflow_surface.conftest import artifact
@@ -115,8 +115,8 @@ def test_run_api_unrunnable_deployment() -> None:
assert result["diagnostics"][0]["code"]
def test_run_api_completed_run_persists() -> None:
root = local_temp_root() / "run_api_completed"
def test_run_api_completed_run_persists(tmp_path: Path) -> None:
root = tmp_path / "run_api_completed"
service, artifact_store = _service_with_echo(root)
context = context_from_service(service)
api = WorkflowRunApi(context)
@@ -138,8 +138,8 @@ def test_run_api_completed_run_persists() -> None:
assert stored.id == result["run_id"]
def test_run_api_rejects_resume_for_completed_run() -> None:
root = local_temp_root() / "run_api_resume_completed_rejected"
def test_run_api_rejects_resume_for_completed_run(tmp_path: Path) -> None:
root = tmp_path / "run_api_resume_completed_rejected"
service, _ = _service_with_echo(root)
context = context_from_service(service)
api = WorkflowRunApi(context)
@@ -160,8 +160,8 @@ def test_run_api_rejects_resume_for_completed_run() -> None:
)
def test_run_api_inspect_uses_pinned_environment_after_deployment_deleted() -> None:
root = local_temp_root() / "run_api_inspect_after_deployment_deleted"
def test_run_api_inspect_uses_pinned_environment_after_deployment_deleted(tmp_path: Path) -> None:
root = tmp_path / "run_api_inspect_after_deployment_deleted"
service, artifact_store = _service_with_echo(root)
context = context_from_service(service)
api = WorkflowRunApi(context)
@@ -183,8 +183,8 @@ def test_run_api_inspect_uses_pinned_environment_after_deployment_deleted() -> N
assert summary["output"]["echoed"] == "hello"
def test_run_api_inspect_and_bounded_trace() -> None:
root = local_temp_root() / "run_api_inspect_trace"
def test_run_api_inspect_and_bounded_trace(tmp_path: Path) -> None:
root = tmp_path / "run_api_inspect_trace"
service, _ = _service_with_echo(root)
context = context_from_service(service)
api = WorkflowRunApi(context)
@@ -217,8 +217,8 @@ class ExplodingRunStore(FileRunStore):
raise AssertionError("run store must not be read before trace_range validation")
def test_run_api_rejects_invalid_trace_range_before_store_lookup() -> None:
root = local_temp_root() / "run_api_invalid_trace_range"
def test_run_api_rejects_invalid_trace_range_before_store_lookup(tmp_path: Path) -> None:
root = tmp_path / "run_api_invalid_trace_range"
service, _ = _service_with_echo(root)
service.run_store = ExplodingRunStore(root / "exploding_runs")
context = context_from_service(service)
@@ -241,8 +241,8 @@ def test_run_api_rejects_invalid_trace_range_before_store_lookup() -> None:
)
def test_run_api_handler_delegation_matches() -> None:
root = local_temp_root() / "run_api_delegation"
def test_run_api_handler_delegation_matches(tmp_path: Path) -> None:
root = tmp_path / "run_api_delegation"
service, _ = _service_with_echo(root)
context = context_from_service(service)
api = WorkflowRunApi(context)
+4 -4
View File
@@ -1,5 +1,7 @@
from __future__ import annotations
from pathlib import Path
from wf_api.stores import WorkflowStores, file_workflow_stores
from wf_artifacts import (
FileDraftWorkspaceStore,
@@ -7,11 +9,9 @@ from wf_artifacts import (
FileWorkflowArtifactStore,
)
from tests.wf_mcp.test_support import local_temp_root
def test_file_workflow_stores_constructs_all_three_file_stores() -> None:
root = local_temp_root() / "wf_api_file_workflow_stores"
def test_file_workflow_stores_constructs_all_three_file_stores(tmp_path: Path) -> None:
root = tmp_path / "wf_api_file_workflow_stores"
stores = file_workflow_stores(root)
+44 -46
View File
@@ -17,11 +17,9 @@ from wf_mcp.source_registry import (
)
from wf_mcp.storage import FileStore
from ..test_support import local_temp_root
def _source_catalog(service: ConnectionService) -> SourceCatalogService:
store = FileStore(local_temp_root() / "connection_service_catalog")
def _source_catalog(service: ConnectionService, root: Path) -> SourceCatalogService:
store = FileStore(root / "connection_service_catalog")
def _tool_executor_for(_connection: ConnectionConfig) -> ToolExecutor:
raise AssertionError("tool executor should not be needed in these tests")
@@ -39,9 +37,9 @@ def _source_catalog(service: ConnectionService) -> SourceCatalogService:
return catalog
def test_connection_service_rejects_reserved_connection_ids() -> None:
def test_connection_service_rejects_reserved_connection_ids(tmp_path: Path) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
_source_catalog(service)
_source_catalog(service, tmp_path)
for connection_id in ("wf.admin", "wf.mcp"):
try:
@@ -55,9 +53,9 @@ def test_connection_service_rejects_reserved_connection_ids() -> None:
raise AssertionError(f"expected {connection_id!r} to be rejected")
def test_connection_service_registers_connection_and_empty_source() -> None:
def test_connection_service_registers_connection_and_empty_source(tmp_path: Path) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
catalog = _source_catalog(service)
catalog = _source_catalog(service, tmp_path)
service.register_connection(
ConnectionConfig(id="demo.personal", server="demo", account="personal")
@@ -72,15 +70,15 @@ def test_connection_service_registers_connection_and_empty_source() -> None:
assert service.events.list_events()[0].connection_id == "demo.personal"
def test_connection_service_sync_removes_retired_connections_and_sources() -> None:
def test_connection_service_sync_removes_retired_connections_and_sources(tmp_path: Path) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
catalog = _source_catalog(service)
catalog = _source_catalog(service, tmp_path)
service.register_connection(
ConnectionConfig(id="demo.personal", server="demo", account="personal")
)
service.sync_connections_from_config(
BrokerConfig(store_root=local_temp_root(), connections=[])
BrokerConfig(store_root=tmp_path, connections=[])
)
assert service.list_all() == []
@@ -92,16 +90,16 @@ def test_connection_service_sync_removes_retired_connections_and_sources() -> No
assert removed.payload["account"] == "personal"
def test_connection_service_sync_updates_existing_source_enabled_flag() -> None:
def test_connection_service_sync_updates_existing_source_enabled_flag(tmp_path: Path) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
catalog = _source_catalog(service)
catalog = _source_catalog(service, tmp_path)
service.register_connection(
ConnectionConfig(id="demo.personal", server="demo", account="personal")
)
service.sync_connections_from_config(
BrokerConfig(
store_root=local_temp_root(),
store_root=tmp_path,
connections=[
ConnectionConfig(
id="demo.personal",
@@ -121,13 +119,13 @@ def test_connection_service_sync_updates_existing_source_enabled_flag() -> None:
assert updated.payload["enabled"] is False
def test_connection_service_sync_registers_new_connections_with_event() -> None:
def test_connection_service_sync_registers_new_connections_with_event(tmp_path: Path) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
catalog = _source_catalog(service)
catalog = _source_catalog(service, tmp_path)
service.sync_connections_from_config(
BrokerConfig(
store_root=local_temp_root(),
store_root=tmp_path,
connections=[
ConnectionConfig(
id="demo.personal",
@@ -145,8 +143,8 @@ def test_connection_service_sync_registers_new_connections_with_event() -> None:
assert registered.connection_id == "demo.personal"
def test_wfmcpservice_exposes_connection_registry_from_connection_service() -> None:
service = WfMcpService(store=FileStore(local_temp_root() / "connection_facade"))
def test_wfmcpservice_exposes_connection_registry_from_connection_service(tmp_path: Path) -> None:
service = WfMcpService(store=FileStore(tmp_path / "connection_facade"))
service.register_connection(
ConnectionConfig(id="demo.personal", server="demo", account="personal")
@@ -157,15 +155,15 @@ def test_wfmcpservice_exposes_connection_registry_from_connection_service() -> N
assert "demo.personal" in service.capability_sources
def test_wfmcpservice_sync_connections_delegates_to_connection_service() -> None:
service = WfMcpService(store=FileStore(local_temp_root() / "connection_sync"))
def test_wfmcpservice_sync_connections_delegates_to_connection_service(tmp_path: Path) -> None:
service = WfMcpService(store=FileStore(tmp_path / "connection_sync"))
service.register_connection(
ConnectionConfig(id="demo.personal", server="demo", account="personal")
)
service.sync_connections_from_config(
BrokerConfig(
store_root=local_temp_root(),
store_root=tmp_path,
connections=[
ConnectionConfig(
id="demo.work",
@@ -204,14 +202,14 @@ def _registry_entry(
)
def test_connection_service_sync_merges_registry_entries() -> None:
def test_connection_service_sync_merges_registry_entries(tmp_path: Path) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
catalog = _source_catalog(service)
store = FileSourceRegistryStore(local_temp_root() / "registry_merge")
catalog = _source_catalog(service, tmp_path)
store = FileSourceRegistryStore(tmp_path / "registry_merge")
store.save_registry(SourceRegistryFile(sources=[_registry_entry()]))
service.sync_connections_from_config(
BrokerConfig(store_root=local_temp_root(), connections=[]),
BrokerConfig(store_root=tmp_path, connections=[]),
source_registry_store=store,
)
@@ -219,15 +217,15 @@ def test_connection_service_sync_merges_registry_entries() -> None:
assert "demo.registry" in catalog.capability_sources
def test_connection_service_sync_config_shadows_registry_entry() -> None:
def test_connection_service_sync_config_shadows_registry_entry(tmp_path: Path) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
_source_catalog(service)
store = FileSourceRegistryStore(local_temp_root() / "registry_shadow")
_source_catalog(service, tmp_path)
store = FileSourceRegistryStore(tmp_path / "registry_shadow")
store.save_registry(SourceRegistryFile(sources=[_registry_entry("demo.same")]))
service.sync_connections_from_config(
BrokerConfig(
store_root=local_temp_root(),
store_root=tmp_path,
connections=[
ConnectionConfig(id="demo.same", server="demo", account="config"),
],
@@ -243,16 +241,16 @@ def test_connection_service_sync_config_shadows_registry_entry() -> None:
)
def test_connection_service_sync_registry_disabled_entry_hydrates_disabled_source() -> (
None
):
def test_connection_service_sync_registry_disabled_entry_hydrates_disabled_source(
tmp_path: Path,
) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
catalog = _source_catalog(service)
store = FileSourceRegistryStore(local_temp_root() / "registry_disabled")
catalog = _source_catalog(service, tmp_path)
store = FileSourceRegistryStore(tmp_path / "registry_disabled")
store.save_registry(SourceRegistryFile(sources=[_registry_entry(enabled=False)]))
service.sync_connections_from_config(
BrokerConfig(store_root=local_temp_root(), connections=[]),
BrokerConfig(store_root=tmp_path, connections=[]),
source_registry_store=store,
)
@@ -264,7 +262,7 @@ def test_connection_service_sync_locked_config_shadows_registry_entry(
tmp_path: Path,
) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
_source_catalog(service)
_source_catalog(service, tmp_path)
store = FileSourceRegistryStore(tmp_path / "locked_shadow")
store.save_registry(
SourceRegistryFile(
@@ -279,7 +277,7 @@ def test_connection_service_sync_locked_config_shadows_registry_entry(
)
)
config = BrokerConfig(
store_root=local_temp_root(),
store_root=tmp_path,
connections=[
ConnectionConfig(
id="demo.default",
@@ -305,11 +303,11 @@ def test_connection_service_sync_seed_config_materializes_registry_entry(
tmp_path: Path,
) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
_source_catalog(service)
_source_catalog(service, tmp_path)
store_root = tmp_path / "seed_materialized"
store = FileSourceRegistryStore(store_root)
config = BrokerConfig(
store_root=local_temp_root(),
store_root=tmp_path,
connections=[
ConnectionConfig(
id="demo.default",
@@ -339,7 +337,7 @@ def test_connection_service_sync_seed_existing_registry_entry_wins(
tmp_path: Path,
) -> None:
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
_source_catalog(service)
_source_catalog(service, tmp_path)
store = FileSourceRegistryStore(tmp_path / "seed_existing")
store.save_registry(
SourceRegistryFile(
@@ -354,7 +352,7 @@ def test_connection_service_sync_seed_existing_registry_entry_wins(
)
)
config = BrokerConfig(
store_root=local_temp_root(),
store_root=tmp_path,
connections=[
ConnectionConfig(
id="demo.default",
@@ -377,13 +375,13 @@ def test_connection_service_sync_seed_existing_registry_entry_wins(
)
def test_wfmcpservice_sync_connections_delegates_registry_store() -> None:
service = WfMcpService(store=FileStore(local_temp_root() / "facade_registry"))
store = FileSourceRegistryStore(local_temp_root() / "facade_registry_store")
def test_wfmcpservice_sync_connections_delegates_registry_store(tmp_path: Path) -> None:
service = WfMcpService(store=FileStore(tmp_path / "facade_registry"))
store = FileSourceRegistryStore(tmp_path / "facade_registry_store")
store.save_registry(SourceRegistryFile(sources=[_registry_entry()]))
service.sync_connections_from_config(
BrokerConfig(store_root=local_temp_root(), connections=[]),
BrokerConfig(store_root=tmp_path, connections=[]),
source_registry_store=store,
)