NebulaGraph MCP Server

by PsiACE
Verified
  • tests
import os import time import pytest from dotenv import load_dotenv # Load environment variables load_dotenv() # Ensure correct environment variable settings @pytest.fixture(scope="session", autouse=True) def setup_env(): os.environ["NEBULA_VERSION"] = "v3" os.environ["NEBULA_HOST"] = os.getenv("NEBULA_HOST", "127.0.0.1") os.environ["NEBULA_PORT"] = os.getenv("NEBULA_PORT", "9669") os.environ["NEBULA_USER"] = os.getenv("NEBULA_USER", "root") os.environ["NEBULA_PASSWORD"] = os.getenv("NEBULA_PASSWORD", "nebula") # Setup commands for test data SETUP_COMMANDS = [ # Group 1: Create space ["CREATE SPACE IF NOT EXISTS test_graph(vid_type=FIXED_STRING(30))"], # Group 2: Use space and create tags and edge types [ "USE test_graph", "CREATE TAG IF NOT EXISTS person(name string, age int)", "CREATE EDGE IF NOT EXISTS knows(years int)", "CREATE EDGE IF NOT EXISTS reports_to(department string)", ], # Group 3: Insert vertices [ "USE test_graph", 'INSERT VERTEX person(name, age) VALUES "person1":("Alice", 30)', 'INSERT VERTEX person(name, age) VALUES "person2":("Bob", 32)', 'INSERT VERTEX person(name, age) VALUES "person3":("Charlie", 45)', 'INSERT VERTEX person(name, age) VALUES "person4":("David", 50)', 'INSERT VERTEX person(name, age) VALUES "person5":("Eve", 55)', ], # Group 4: Insert edges [ "USE test_graph", 'INSERT EDGE knows(years) VALUES "person1"->"person2":(5)', 'INSERT EDGE knows(years) VALUES "person2"->"person3":(3)', 'INSERT EDGE knows(years) VALUES "person3"->"person5":(10)', 'INSERT EDGE reports_to(department) VALUES "person1"->"person3":("Engineering")', 'INSERT EDGE reports_to(department) VALUES "person2"->"person3":("Engineering")', 'INSERT EDGE reports_to(department) VALUES "person3"->"person4":("Management")', 'INSERT EDGE reports_to(department) VALUES "person4"->"person5":("Executive")', ], ] # Skip integration tests (unless explicitly enabled) pytestmark = pytest.mark.skipif( os.getenv("RUN_INTEGRATION_TESTS") != "true", reason="Integration tests require a running NebulaGraph instance and specific test data", ) def execute_with_retry(session, command, max_retries=3, retry_interval=2): """Execute command and retry on failure""" for attempt in range(max_retries): try: print(f"Executing: {command}") result = session.execute(command) if result.is_succeeded(): return result else: print( f"Error executing command (attempt {attempt + 1}/{max_retries}): {result.error_msg()}" ) if attempt < max_retries - 1: time.sleep(retry_interval) except Exception as e: print( f"Error executing command (attempt {attempt + 1}/{max_retries}): {e!s}" ) if attempt < max_retries - 1: time.sleep(retry_interval) # final attempt print(f"Final attempt to execute: {command}") return session.execute(command) @pytest.fixture(scope="module", autouse=True) def setup_connection(): """Initialize connection pool and prepare test data""" from nebulagraph_mcp_server.server import config, global_pool # Initialize connection global_pool.init( [ ( os.getenv("NEBULA_HOST", "127.0.0.1"), int(os.getenv("NEBULA_PORT", "9669")), ) ], config, ) # If running integration tests, create test data if os.getenv("RUN_INTEGRATION_TESTS") == "true": session = global_pool.get_session( os.getenv("NEBULA_USER", "root"), os.getenv("NEBULA_PASSWORD", "nebula") ) try: # Execute command groups for group_index, command_group in enumerate(SETUP_COMMANDS): print( f"\nExecuting command group {group_index + 1}/{len(SETUP_COMMANDS)}:" ) # Execute commands in the group for command in command_group: if command.strip(): execute_with_retry(session, command.strip()) # Add appropriate wait time after group type if group_index == 0: # After creating space print("Waiting for space creation to complete (30 seconds)...") time.sleep(30) elif group_index == 1: # After creating tags and edge types print("Waiting for metadata synchronization (10 seconds)...") time.sleep(10) else: # Short wait after other operations print("Short wait (2 seconds)...") time.sleep(2) # Final verification print("\nVerifying data creation:") verify_commands = [ "USE test_graph", "SHOW TAGS", "SHOW EDGES", "MATCH (n:person) RETURN count(n)", ] for command in verify_commands: result = execute_with_retry(session, command) print( f"Verification result: {command} - {'Success' if result.is_succeeded() else 'Failed'}" ) finally: session.release() yield # Clean up connection global_pool.close() # Integration test: get all spaces @pytest.mark.asyncio async def test_integration_list_spaces(): """Test the list spaces function""" from nebulagraph_mcp_server.server import list_spaces # Call the list_spaces tool function result = list_spaces() # Validate the result assert "Available spaces" in result assert "test_graph" in result # Assuming the test space is created # Integration test: execute query @pytest.mark.asyncio async def test_integration_execute_query(): """Test the execute query function""" from nebulagraph_mcp_server.server import execute_query # Execute the query result = execute_query( "MATCH (n:person) RETURN id(n), n.name, n.age LIMIT 3", "test_graph", ) # Validate the result assert "Results" in result assert "id(n) | n.name | n.age" in result # Integration test: find path @pytest.mark.asyncio async def test_integration_find_path(): """Test the find path function""" from nebulagraph_mcp_server.server import find_path # Test finding paths from person1 to person5 result = find_path("person1", "person5", "test_graph", 3, 10) # Validate the result print(f"Find path result: {result}") # Debug assert "Find paths from person1 to person5" in result # Since the test graph, person1 to person5 needs at least 3 steps, # when depth=3, there should be a path, and the result should contain path information # If no path is found, the result should contain "No paths found" assert "Path" in result or "No paths found" in result # Test non-existent path result2 = find_path("person1", "nonexistent", "test_graph", 3, 10) assert "No paths found" in result2 or "Query failed" in result2 # Integration test: get neighbors @pytest.mark.asyncio async def test_integration_get_neighbors(): """Test the get neighbors function""" from nebulagraph_mcp_server.server import find_neighbors # Test getting neighbors of person1 result = find_neighbors("person1", "test_graph", 1) # Validate the result assert "Vertex person1 neighbors (depth 1):" in result assert "person2" in result assert "person3" in result assert "person4" not in result assert "person5" not in result