Skip to main content
Glama

MCP Brain Service

by jomapps
test_performance.py•11 kB
"""Performance tests for MCP Brain Service.""" import asyncio import json import statistics import time import pytest import pytest_asyncio import websockets from typing import List class TestPerformance: """Performance tests for semantic search.""" @pytest_asyncio.fixture async def websocket_client(self): """Create WebSocket client connection.""" uri = "ws://localhost:8002" try: async with websockets.connect(uri) as websocket: yield websocket except ConnectionRefusedError: pytest.skip("WebSocket server not running") @pytest_asyncio.fixture async def test_characters(self, websocket_client) -> List[str]: """Create test characters for performance testing.""" project_id = "performance_test_project" characters = [ { "name": "Aragorn", "personality_description": "Noble ranger and rightful king, skilled in combat and leadership. Brave, loyal, and determined to protect his people.", "appearance_description": "Tall man with dark hair and weathered features, wearing ranger's clothes and carrying a sword." }, { "name": "Gandalf", "personality_description": "Ancient and wise wizard, master of magic and guide to others. Patient, powerful, and deeply caring.", "appearance_description": "Old man with grey robes, a pointed hat, long beard, and a magical staff." }, { "name": "Legolas", "personality_description": "Elven prince and master archer, graceful and deadly in battle. Proud, loyal, and connected to nature.", "appearance_description": "Tall elf with long blonde hair, elegant features, and carries a bow and arrows." }, { "name": "Gimli", "personality_description": "Dwarven warrior with fierce loyalty and brave heart. Gruff exterior but deep friendships.", "appearance_description": "Short, stocky dwarf with red beard, heavy armor, and carries an axe." }, { "name": "Frodo", "personality_description": "Brave hobbit with pure heart and strong will. Innocent but determined to do what's right.", "appearance_description": "Small hobbit with curly hair and large feet, often looks worried but determined." }, { "name": "Boromir", "personality_description": "Proud warrior of Gondor, brave but tempted by power. Ultimately redeems himself through sacrifice.", "appearance_description": "Tall man with noble bearing, armor, and carries a shield and sword." }, { "name": "Saruman", "personality_description": "Corrupted wizard seeking power and control. Intelligent but arrogant and manipulative.", "appearance_description": "Tall wizard in white robes (later many colors), with long hair and piercing eyes." }, { "name": "Sauron", "personality_description": "Dark lord obsessed with domination and control. Pure evil, seeking to rule all of Middle-earth.", "appearance_description": "Appears as a great eye of fire, or as a dark armored figure with immense presence." } ] character_ids = [] for character in characters: message = { "tool": "create_character", "project_id": project_id, **character } await websocket_client.send(json.dumps(message)) response = await websocket_client.recv() response_data = json.loads(response) if response_data["status"] == "success": character_ids.append(response_data["character_id"]) return character_ids @pytest.mark.asyncio async def test_semantic_search_response_time(self, websocket_client, test_characters): """Test that semantic search meets p95 response time requirement (<1 minute).""" project_id = "performance_test_project" # Test queries with different complexities test_queries = [ "brave warrior with sword", "wise magical wizard with ancient knowledge", "small creature with courage", "evil dark lord seeking power", "noble leader and protector", "archer with bow and arrows", "corrupted wizard seeking control", "dwarf with axe and armor" ] response_times = [] for query in test_queries: message = { "tool": "find_similar_characters", "project_id": project_id, "query": query } start_time = time.time() await websocket_client.send(json.dumps(message)) response = await websocket_client.recv() end_time = time.time() response_time = end_time - start_time response_times.append(response_time) # Verify response is valid response_data = json.loads(response) assert response_data["status"] == "success" assert isinstance(response_data["results"], list) # Calculate statistics mean_time = statistics.mean(response_times) median_time = statistics.median(response_times) p95_time = sorted(response_times)[int(0.95 * len(response_times))] max_time = max(response_times) print(f"\nPerformance Results:") print(f"Mean response time: {mean_time:.3f}s") print(f"Median response time: {median_time:.3f}s") print(f"P95 response time: {p95_time:.3f}s") print(f"Max response time: {max_time:.3f}s") print(f"Total queries: {len(test_queries)}") # Performance requirement: p95 response time < 1 minute (60 seconds) assert p95_time < 60.0, f"P95 response time {p95_time:.3f}s exceeds 60s requirement" # Additional performance checks for development assert mean_time < 10.0, f"Mean response time {mean_time:.3f}s is too high for development" assert max_time < 30.0, f"Max response time {max_time:.3f}s is too high" @pytest.mark.asyncio async def test_concurrent_search_performance(self, websocket_client, test_characters): """Test performance under concurrent load.""" project_id = "performance_test_project" async def search_task(query_id: int) -> float: """Single search task.""" uri = "ws://localhost:8002" try: async with websockets.connect(uri) as ws: message = { "tool": "find_similar_characters", "project_id": project_id, "query": f"brave warrior number {query_id}" } start_time = time.time() await ws.send(json.dumps(message)) response = await ws.recv() end_time = time.time() # Verify response response_data = json.loads(response) assert response_data["status"] == "success" return end_time - start_time except Exception as e: print(f"Search task {query_id} failed: {e}") return float('inf') # Run 5 concurrent searches concurrent_tasks = 5 start_time = time.time() tasks = [search_task(i) for i in range(concurrent_tasks)] response_times = await asyncio.gather(*tasks) total_time = time.time() - start_time # Filter out failed requests valid_times = [t for t in response_times if t != float('inf')] print(f"\nConcurrent Performance Results:") print(f"Concurrent tasks: {concurrent_tasks}") print(f"Successful tasks: {len(valid_times)}") print(f"Total time: {total_time:.3f}s") print(f"Mean task time: {statistics.mean(valid_times):.3f}s") print(f"Max task time: {max(valid_times):.3f}s") # All tasks should complete successfully assert len(valid_times) == concurrent_tasks, "Some concurrent tasks failed" # All concurrent tasks should complete within reasonable time assert total_time < 30.0, f"Concurrent tasks took too long: {total_time:.3f}s" assert max(valid_times) < 15.0, f"Slowest task was too slow: {max(valid_times):.3f}s" @pytest.mark.asyncio async def test_character_creation_performance(self, websocket_client): """Test character creation performance.""" project_id = "creation_performance_test" character_data = { "project_id": project_id, "name": "Performance Test Character", "personality_description": "A character created for performance testing purposes. Should be quick to create and process.", "appearance_description": "Standard appearance for testing embedding generation and database operations." } creation_times = [] # Create multiple characters to test consistency for i in range(5): message = { "tool": "create_character", **character_data, "name": f"Performance Test Character {i}" } start_time = time.time() await websocket_client.send(json.dumps(message)) response = await websocket_client.recv() end_time = time.time() creation_time = end_time - start_time creation_times.append(creation_time) # Verify creation succeeded response_data = json.loads(response) assert response_data["status"] == "success" mean_creation_time = statistics.mean(creation_times) max_creation_time = max(creation_times) print(f"\nCharacter Creation Performance:") print(f"Mean creation time: {mean_creation_time:.3f}s") print(f"Max creation time: {max_creation_time:.3f}s") # Character creation should be fast assert mean_creation_time < 5.0, f"Mean creation time too slow: {mean_creation_time:.3f}s" assert max_creation_time < 10.0, f"Max creation time too slow: {max_creation_time:.3f}s"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jomapps/mcp-brain-service'

If you have feedback or need assistance with the MCP directory API, please join our Discord server