summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/mcp_protocol_test.py168
1 files changed, 167 insertions, 1 deletions
diff --git a/tests/mcp_protocol_test.py b/tests/mcp_protocol_test.py
index f5a5c86..c206515 100644
--- a/tests/mcp_protocol_test.py
+++ b/tests/mcp_protocol_test.py
@@ -109,6 +109,7 @@ def main() -> None:
data_dir = Path(tempfile.mkdtemp(prefix="tiny-convmem-p0-"))
server = Server(args.server.resolve(), data_dir)
next_id = 1
+ expected_session_count = 0
try:
response = server.send(
request(
@@ -200,6 +201,9 @@ def main() -> None:
assert tools["search_messages"]["inputSchema"]["properties"]["limit"]["type"] == "integer"
assert tools["delete_message"]["inputSchema"]["required"] == ["message_id"]
assert tools["update_message"]["inputSchema"]["required"] == ["message_id"]
+ empty_health = tool_payload(tool_call(server, next_id, "get_system_health", {}))
+ next_id += 1
+ assert empty_health["session_count"] == 0
message_ids: list[str] = []
for index in range(20):
@@ -213,6 +217,71 @@ def main() -> None:
)
next_id += 1
message_ids.append(payload["message"]["message_id"])
+
+ metadata_regression = tool_payload(
+ tool_call(
+ server,
+ next_id,
+ "write_message",
+ {
+ "session_id": "metadata-regression",
+ "role": "assistant",
+ "content": "metadata combination",
+ "metadata_json": json.dumps(
+ {
+ "tags": ["regression"],
+ "memory_tier": "long",
+ "importance": 90,
+ "summary": "valid metadata combination",
+ }
+ ),
+ },
+ )
+ )["message"]
+ next_id += 1
+ assert metadata_regression["metadata"]["tags"] == ["regression"]
+ assert metadata_regression["metadata"]["memory_tier"] == "long"
+ assert metadata_regression["metadata"]["importance"] == 90
+ assert metadata_regression["metadata"]["summary"] == "valid metadata combination"
+
+ invalid_metadata_cases = [
+ (json.dumps({"unexpected": True}), "unknown field"),
+ (json.dumps({"memory_tier": "archive"}), "memory_tier"),
+ (json.dumps({"importance": 101}), "importance"),
+ (json.dumps({"summary": "x" * 4097}), "summary"),
+ (json.dumps({"tags": [1]}), "tags"),
+ ("{", "JSON object"),
+ ]
+ for metadata_json, expected_diagnostic in invalid_metadata_cases:
+ write_error = tool_payload(
+ tool_call(
+ server,
+ next_id,
+ "write_message",
+ {
+ "session_id": "metadata-invalid",
+ "role": "user",
+ "content": "must not be written",
+ "metadata_json": metadata_json,
+ },
+ ),
+ True,
+ )
+ next_id += 1
+ assert write_error["error"]["code"] == "VALIDATION_ERROR"
+ assert expected_diagnostic in write_error["error"]["message"]
+ update_error = tool_payload(
+ tool_call(
+ server,
+ next_id,
+ "update_message",
+ {"message_id": message_ids[0], "metadata_json": metadata_json},
+ ),
+ True,
+ )
+ next_id += 1
+ assert update_error["error"]["code"] == "VALIDATION_ERROR"
+ assert expected_diagnostic in update_error["error"]["message"]
updated = tool_payload(
tool_call(
server,
@@ -273,6 +342,63 @@ def main() -> None:
io_after_views = tool_payload(tool_call(server, next_id, "get_system_health", {}))["io"]
next_id += 1
assert io_after_views == io_before
+
+ paged_session_ids = ["session-page-a", "session-page-b", "s" * 256]
+ for session_id in paged_session_ids:
+ tool_payload(
+ tool_call(
+ server,
+ next_id,
+ "write_message",
+ {"session_id": session_id, "role": "user", "content": "session page item"},
+ )
+ )
+ next_id += 1
+ complete_sessions = tool_payload(
+ tool_call(server, next_id, "read_messages", {"view": "sessions", "limit": 1000})
+ )["sessions"]
+ next_id += 1
+ expected_session_ids = [item["session_id"] for item in complete_sessions]
+ traversed_session_ids: list[str] = []
+ session_cursor: str | None = None
+ first_session_cursor: str | None = None
+ while True:
+ arguments: dict[str, Any] = {"view": "sessions", "limit": 1}
+ if session_cursor:
+ arguments["cursor"] = session_cursor
+ session_page = tool_payload(
+ tool_call(server, next_id, "read_messages", arguments)
+ )
+ next_id += 1
+ assert len(session_page["sessions"]) == 1
+ traversed_session_ids.append(session_page["sessions"][0]["session_id"])
+ session_cursor = session_page.get("nextCursor")
+ if first_session_cursor is None:
+ first_session_cursor = session_cursor
+ if not session_cursor:
+ break
+ assert len(traversed_session_ids) <= len(expected_session_ids)
+ assert traversed_session_ids == expected_session_ids
+ assert first_session_cursor
+ tampered_cursor = first_session_cursor[:-1] + (
+ "A" if first_session_cursor[-1] != "A" else "B"
+ )
+ assert tool_payload(
+ tool_call(
+ server,
+ next_id,
+ "read_messages",
+ {"view": "sessions", "limit": 1, "cursor": tampered_cursor},
+ ),
+ True,
+ )["error"]["code"] == "VALIDATION_ERROR"
+ next_id += 1
+ health_with_sessions = tool_payload(
+ tool_call(server, next_id, "get_system_health", {})
+ )
+ next_id += 1
+ expected_session_count = len(expected_session_ids)
+ assert health_with_sessions["session_count"] == expected_session_count
relation_message = tool_payload(
tool_call(
server,
@@ -429,6 +555,46 @@ def main() -> None:
next_id += 1
assert 0 < len(large_page["history"]) < 6 and large_page.get("nextCursor")
assert server.last_response_size <= 8 * 1024 * 1024
+
+ large_session_ids = [f"large-session-{index}" for index in range(5)]
+ for session_id in large_session_ids:
+ tool_payload(
+ tool_call(
+ server,
+ next_id,
+ "write_message",
+ {"session_id": session_id, "role": "user", "content": large_content},
+ )
+ )
+ next_id += 1
+ budget_session_ids: list[str] = []
+ budget_cursor: str | None = None
+ budget_page_count = 0
+ while True:
+ arguments = {"view": "sessions", "limit": 1000}
+ if budget_cursor:
+ arguments["cursor"] = budget_cursor
+ budget_page = tool_payload(
+ tool_call(server, next_id, "read_messages", arguments)
+ )
+ next_id += 1
+ budget_page_count += 1
+ assert budget_page["sessions"]
+ assert server.last_response_size <= 8 * 1024 * 1024
+ budget_session_ids.extend(item["session_id"] for item in budget_page["sessions"])
+ budget_cursor = budget_page.get("nextCursor")
+ if not budget_cursor:
+ break
+ assert budget_page_count <= 10
+ assert budget_page_count > 1
+ assert len(budget_session_ids) == len(set(budget_session_ids))
+ assert set(large_session_ids).issubset(budget_session_ids)
+ health_after_budget = tool_payload(
+ tool_call(server, next_id, "get_system_health", {})
+ )
+ next_id += 1
+ expected_session_count = len(budget_session_ids)
+ assert health_after_budget["session_count"] == expected_session_count
assert tool_payload(
tool_call(
server,
@@ -559,6 +725,7 @@ def main() -> None:
)
next_id += 1
assert resumed_health["status"] == "OK"
+ assert resumed_health["session_count"] == expected_session_count
finally:
restarted.close()
finally:
@@ -567,4 +734,3 @@ def main() -> None:
if __name__ == "__main__":
main()
-