feat: add project-scoped operations
This commit is contained in:
@@ -80,6 +80,32 @@ def test_calculation_limit_is_advertised_and_enforced_before_execution(runtime):
|
||||
assert calls == []
|
||||
|
||||
|
||||
def test_calculation_capacity_has_an_explicit_mcp_error(runtime, monkeypatch):
|
||||
from threading import BoundedSemaphore
|
||||
from app.mcp import analysis_service
|
||||
|
||||
app, client, _, _ = runtime
|
||||
monkeypatch.setattr(application, "authorize_query", AsyncMock())
|
||||
slots = BoundedSemaphore(2)
|
||||
monkeypatch.setattr(analysis_service, "_slots", slots)
|
||||
async def execute(*unused):
|
||||
return await analysis_service.bounded_calculation(lambda: pytest.fail("occupied calculation entered"))
|
||||
app.executor = execute
|
||||
assert slots.acquire(blocking=False) and slots.acquire(blocking=False)
|
||||
try:
|
||||
response = request(client, "tools/call", {"name": "run_simulation", "arguments": {
|
||||
"context_handle": binding().context_handle, "start_time": "2026-10-08T12:00:00+08:00",
|
||||
"duration": 3600, "output_node_ids": ["J1"],
|
||||
}}).json()
|
||||
finally:
|
||||
slots.release()
|
||||
slots.release()
|
||||
error = response["result"]["structuredContent"]["error"]
|
||||
assert response["result"]["isError"] is True
|
||||
assert error["code"] == "CALCULATION_CAPACITY_EXCEEDED"
|
||||
assert "not started" in error["message"]
|
||||
|
||||
|
||||
def test_burst_location_default_inputs_pass_protocol_validation(runtime, monkeypatch):
|
||||
app, client, calls, _ = runtime
|
||||
monkeypatch.setattr(application, "authorize_query", AsyncMock())
|
||||
@@ -286,10 +312,10 @@ def test_modern_discovery_catalog_and_metadata(runtime):
|
||||
assert result["result"]["resultType"] == "complete"
|
||||
assert "2026-07-28" in result["result"]["supportedVersions"]
|
||||
listed = request(client).json()["result"]
|
||||
assert len(listed["tools"]) == 35
|
||||
assert len(listed["tools"]) == len(TOOLS)
|
||||
for tool in listed["tools"]:
|
||||
timeout = tool["inputSchema"]["properties"].get("timeout_seconds")
|
||||
assert (timeout is not None) == TOOLS[tool["name"]].computation
|
||||
assert (timeout is not None) == (TOOLS[tool["name"]].computation or TOOLS[tool["name"]].mutating)
|
||||
if timeout:
|
||||
assert timeout["default"] == 120
|
||||
assert timeout["maximum"] == 3600
|
||||
|
||||
Reference in New Issue
Block a user