170 lines
5.0 KiB
Python
170 lines
5.0 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from wf_config import WorkflowConfigFile
|
|
from wf_platform import CapabilityBuckets, CapabilitySource
|
|
from wf_server.config import (
|
|
build_workflow_server_from_legacy_mcp_config,
|
|
build_workflow_server_from_workflow_config,
|
|
)
|
|
from wf_server.context import WorkflowServer
|
|
from wf_server.sources import StaticSourceProvider, collect_static_sources
|
|
|
|
|
|
class FakeSourceProvider:
|
|
def load_sources(self):
|
|
return {
|
|
"fake.ops": CapabilitySource(
|
|
id="fake.ops",
|
|
kind="python",
|
|
capabilities=CapabilityBuckets(),
|
|
)
|
|
}
|
|
|
|
|
|
def test_workflow_config_with_python_source_exposes_capability(tmp_path: Path) -> None:
|
|
config = WorkflowConfigFile.model_validate(
|
|
{
|
|
"version": 1,
|
|
"server": {
|
|
"store": {"kind": "filesystem", "root": str(tmp_path / "store")},
|
|
"sources": [
|
|
{
|
|
"kind": "python",
|
|
"id": "local.ops",
|
|
"module": "tests.fixtures.python_source_ops",
|
|
"registry": "registry",
|
|
}
|
|
],
|
|
},
|
|
}
|
|
)
|
|
|
|
server = build_workflow_server_from_workflow_config(config)
|
|
|
|
assert "local.ops" in server.context.specs.capability_sources
|
|
assert (
|
|
"local.ops.echo"
|
|
in server.context.specs.capability_sources["local.ops"].capabilities.node_specs
|
|
)
|
|
|
|
|
|
def test_static_source_provider_protocol_collects_sources() -> None:
|
|
sources = collect_static_sources([FakeSourceProvider()])
|
|
|
|
assert set(sources) == {"fake.ops"}
|
|
|
|
|
|
def test_static_source_provider_rejects_duplicate_source_ids() -> None:
|
|
provider = StaticSourceProvider(
|
|
{
|
|
"fake.ops": CapabilitySource(
|
|
id="fake.ops",
|
|
kind="python",
|
|
capabilities=CapabilityBuckets(),
|
|
)
|
|
}
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="duplicate workflow source ids"):
|
|
collect_static_sources([provider, FakeSourceProvider()])
|
|
|
|
|
|
def test_static_source_provider_rejects_source_key_mismatch() -> None:
|
|
provider = StaticSourceProvider(
|
|
{
|
|
"fake.alias": CapabilitySource(
|
|
id="fake.ops",
|
|
kind="python",
|
|
capabilities=CapabilityBuckets(),
|
|
)
|
|
}
|
|
)
|
|
|
|
with pytest.raises(ValueError, match="does not match source id"):
|
|
collect_static_sources([provider])
|
|
|
|
|
|
def test_build_workflow_server_from_workflow_config_uses_local_static_for_no_mcp_sources(
|
|
tmp_path: Path,
|
|
) -> None:
|
|
config = WorkflowConfigFile.model_validate(
|
|
{
|
|
"version": 1,
|
|
"server": {
|
|
"store": {"kind": "filesystem", "root": str(tmp_path / "store")},
|
|
"sources": [{"kind": "stdlib", "id": "wf.std"}],
|
|
},
|
|
}
|
|
)
|
|
|
|
server = build_workflow_server_from_workflow_config(config)
|
|
|
|
assert isinstance(server, WorkflowServer)
|
|
assert server.config.store_root == tmp_path / "store"
|
|
assert server.source_registry_admin is None
|
|
|
|
|
|
def test_build_workflow_server_from_workflow_config_uses_mcp_builder_for_mcp_sources(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
captured = {}
|
|
|
|
def fake_builder(config):
|
|
captured["source_kinds"] = [source.kind for source in config.server.sources]
|
|
return "mcp-server"
|
|
|
|
monkeypatch.setattr(
|
|
"wf_server.config._build_mcp_workflow_server_from_workflow_config",
|
|
fake_builder,
|
|
)
|
|
config = WorkflowConfigFile.model_validate(
|
|
{
|
|
"version": 1,
|
|
"server": {
|
|
"store": {"kind": "filesystem", "root": str(tmp_path / "store")},
|
|
"sources": [
|
|
{
|
|
"kind": "mcp",
|
|
"id": "everything.default",
|
|
"provider": "everything",
|
|
"account": "default",
|
|
"transport": {"kind": "stdio", "command": "uvx"},
|
|
}
|
|
],
|
|
},
|
|
}
|
|
)
|
|
|
|
server = build_workflow_server_from_workflow_config(config)
|
|
|
|
assert server == "mcp-server"
|
|
assert captured["source_kinds"] == ["mcp"]
|
|
|
|
|
|
def test_build_workflow_server_from_legacy_mcp_config_delegates_to_mcp_builder(
|
|
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
) -> None:
|
|
captured = {}
|
|
|
|
def fake_builder(path):
|
|
captured["path"] = path
|
|
return "legacy-mcp-server"
|
|
|
|
monkeypatch.setattr(
|
|
"wf_server.config._build_mcp_workflow_server_from_legacy_config",
|
|
fake_builder,
|
|
)
|
|
legacy_path = tmp_path / "wf_mcp.config.json"
|
|
legacy_path.write_text(
|
|
'{"store_root": "store", "connections": []}', encoding="utf-8"
|
|
)
|
|
|
|
server = build_workflow_server_from_legacy_mcp_config(legacy_path)
|
|
|
|
assert server == "legacy-mcp-server"
|
|
assert captured["path"] == legacy_path
|