174 lines
5.8 KiB
Python
174 lines
5.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for Vultr MCP Server
|
|
"""
|
|
import sys
|
|
import os
|
|
import json
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from src.vultr_mcp.server import app
|
|
from fastapi.testclient import TestClient
|
|
|
|
# Create test client
|
|
client = TestClient(app)
|
|
|
|
def test_root_endpoint():
|
|
"""Test root endpoint"""
|
|
print("Testing root endpoint...")
|
|
response = client.get("/")
|
|
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
|
|
data = response.json()
|
|
assert "name" in data, "Missing 'name' in response"
|
|
assert "Vultr MCP Server" in data["name"], f"Unexpected name: {data.get('name')}"
|
|
print(f" ✓ Root endpoint: {data['name']} v{data.get('version', 'N/A')}")
|
|
return True
|
|
|
|
def test_tools_endpoint():
|
|
"""Test tools endpoint"""
|
|
print("\nTesting tools endpoint...")
|
|
response = client.get("/tools")
|
|
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
|
|
tools = response.json()
|
|
assert isinstance(tools, list), f"Expected list, got {type(tools)}"
|
|
assert len(tools) > 0, "No tools found"
|
|
|
|
print(f" ✓ Found {len(tools)} tools:")
|
|
for i, tool in enumerate(tools[:5], 1): # Show first 5
|
|
print(f" {i}. {tool['name']}: {tool['description'][:50]}...")
|
|
if len(tools) > 5:
|
|
print(f" ... and {len(tools) - 5} more")
|
|
|
|
# Verify some expected tools
|
|
tool_names = [t['name'] for t in tools]
|
|
expected_tools = ['get_account_info', 'list_instances', 'create_instance']
|
|
for expected in expected_tools:
|
|
assert expected in tool_names, f"Missing expected tool: {expected}"
|
|
|
|
return True
|
|
|
|
def test_resources_endpoint():
|
|
"""Test resources endpoint"""
|
|
print("\nTesting resources endpoint...")
|
|
response = client.get("/resources")
|
|
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
|
|
resources = response.json()
|
|
assert isinstance(resources, list), f"Expected list, got {type(resources)}"
|
|
|
|
print(f" ✓ Found {len(resources)} resources:")
|
|
for resource in resources:
|
|
print(f" - {resource['name']}: {resource['uri']}")
|
|
|
|
return True
|
|
|
|
def test_prompts_endpoint():
|
|
"""Test prompts endpoint"""
|
|
print("\nTesting prompts endpoint...")
|
|
response = client.get("/prompts")
|
|
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
|
|
prompts = response.json()
|
|
assert isinstance(prompts, list), f"Expected list, got {type(prompts)}"
|
|
|
|
print(f" ✓ Found {len(prompts)} prompts:")
|
|
for prompt in prompts:
|
|
print(f" - {prompt['name']}: {prompt['description']}")
|
|
|
|
return True
|
|
|
|
def test_tool_call_without_api_key():
|
|
"""Test tool call without API key (should fail gracefully)"""
|
|
print("\nTesting tool call without API key...")
|
|
response = client.post("/tools/call", json={
|
|
"name": "get_account_info",
|
|
"arguments": {}
|
|
})
|
|
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
|
|
result = response.json()
|
|
|
|
# Should either be an error or contain content
|
|
assert "content" in result, "Missing 'content' in response"
|
|
assert isinstance(result["content"], list), "Content should be a list"
|
|
|
|
if result.get("isError", False):
|
|
print(" ✓ Tool call correctly returned error (no API key configured)")
|
|
if result["content"]:
|
|
error_text = result["content"][0].get("text", "")
|
|
print(f" Error message: {error_text[:100]}...")
|
|
else:
|
|
print(" ✓ Tool call succeeded (API key might be configured)")
|
|
|
|
return True
|
|
|
|
def test_server_info_endpoints():
|
|
"""Test that server info endpoints work"""
|
|
print("\nTesting server info endpoints...")
|
|
|
|
# Test that we can get the OpenAPI schema
|
|
response = client.get("/openapi.json")
|
|
assert response.status_code == 200, f"OpenAPI schema failed: {response.status_code}"
|
|
print(" ✓ OpenAPI schema available")
|
|
|
|
# Test docs endpoint
|
|
response = client.get("/docs")
|
|
assert response.status_code == 200, f"Docs endpoint failed: {response.status_code}"
|
|
print(" ✓ API documentation available")
|
|
|
|
return True
|
|
|
|
def main():
|
|
"""Run all tests"""
|
|
print("=" * 60)
|
|
print("Vultr MCP Server - Test Suite")
|
|
print("=" * 60)
|
|
print("Note: These tests don't require a Vultr API key")
|
|
print(" They only test the server structure and endpoints\n")
|
|
|
|
tests = [
|
|
test_root_endpoint,
|
|
test_tools_endpoint,
|
|
test_resources_endpoint,
|
|
test_prompts_endpoint,
|
|
test_tool_call_without_api_key,
|
|
test_server_info_endpoints,
|
|
]
|
|
|
|
passed = 0
|
|
failed = 0
|
|
failed_tests = []
|
|
|
|
for test in tests:
|
|
try:
|
|
if test():
|
|
passed += 1
|
|
except AssertionError as e:
|
|
print(f" ✗ Test failed: {e}")
|
|
failed += 1
|
|
failed_tests.append(test.__name__)
|
|
except Exception as e:
|
|
print(f" ✗ Unexpected error in {test.__name__}: {e}")
|
|
failed += 1
|
|
failed_tests.append(test.__name__)
|
|
|
|
print("\n" + "=" * 60)
|
|
print("TEST RESULTS")
|
|
print("=" * 60)
|
|
print(f"Passed: {passed}")
|
|
print(f"Failed: {failed}")
|
|
|
|
if failed == 0:
|
|
print("\n✅ All tests passed! Server is ready to run.")
|
|
print("\nNext steps:")
|
|
print(" 1. Copy .env.example to .env")
|
|
print(" 2. Add your VULTR_API_KEY to .env")
|
|
print(" 3. Run the server: python main.py")
|
|
print(" 4. Test with example: python examples/basic_usage.py")
|
|
return 0
|
|
else:
|
|
print(f"\n❌ {failed} test(s) failed: {', '.join(failed_tests)}")
|
|
print("\nCheck the implementation and try again.")
|
|
return 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|
|
|