-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_server.py
More file actions
360 lines (304 loc) · 12.8 KB
/
Copy pathtest_server.py
File metadata and controls
360 lines (304 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#!/usr/bin/env python3
"""
FORUS Cortex Agent MCP Server - Test Suite
"""
import asyncio
import json
import sys
import time
import requests
from typing import Dict, Any
# Test configuration
SERVER_URL = "http://localhost:8083"
MCP_ENDPOINT = f"{SERVER_URL}/mcp"
class MCPTester:
"""Test suite for FORUS MCP Server"""
def __init__(self):
self.passed = 0
self.failed = 0
self.request_id = 0
def get_next_id(self):
self.request_id += 1
return self.request_id
def test_result(self, test_name: str, success: bool, message: str = ""):
"""Record test result"""
if success:
print(f"✅ {test_name}")
self.passed += 1
else:
print(f"❌ {test_name}: {message}")
self.failed += 1
def make_mcp_request(self, method: str, params: Dict = None) -> Dict[str, Any]:
"""Make MCP JSON-RPC request"""
request = {
"jsonrpc": "2.0",
"id": self.get_next_id(),
"method": method
}
if params:
request["params"] = params
try:
response = requests.post(MCP_ENDPOINT, json=request, timeout=10)
return response.json()
except Exception as e:
return {"error": {"code": -32603, "message": str(e)}}
def test_server_info(self):
"""Test server info endpoint"""
try:
response = requests.get(SERVER_URL, timeout=5)
if response.status_code == 200:
data = response.json()
if "server" in data and "FORUS" in data["server"]:
self.test_result("Server Info Endpoint", True)
return True
else:
self.test_result("Server Info Endpoint", False, "Invalid response format")
return False
else:
self.test_result("Server Info Endpoint", False, f"HTTP {response.status_code}")
return False
except Exception as e:
self.test_result("Server Info Endpoint", False, str(e))
return False
def test_tools_list(self):
"""Test tools/list method"""
response = self.make_mcp_request("tools/list")
if "error" in response:
self.test_result("Tools List", False, response["error"]["message"])
return False
if "result" in response and "tools" in response["result"]:
tools = response["result"]["tools"]
if len(tools) >= 6: # Should have at least 6 tools
self.test_result("Tools List", True)
return True
else:
self.test_result("Tools List", False, f"Only {len(tools)} tools found")
return False
else:
self.test_result("Tools List", False, "Invalid response format")
return False
def test_initialize(self):
"""Test initialize method"""
response = self.make_mcp_request("initialize", {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "test-client", "version": "1.0.0"}
})
if "error" in response:
self.test_result("Initialize", False, response["error"]["message"])
return False
if "result" in response:
result = response["result"]
if "protocolVersion" in result and "capabilities" in result:
self.test_result("Initialize", True)
return True
else:
self.test_result("Initialize", False, "Invalid response format")
return False
else:
self.test_result("Initialize", False, "No result in response")
return False
def test_memory_search(self):
"""Test memory_search tool"""
response = self.make_mcp_request("tools/call", {
"name": "memory_search",
"arguments": {
"query": "test query",
"limit": 5
}
})
if "error" in response:
self.test_result("Memory Search Tool", False, response["error"]["message"])
return False
if "result" in response and "content" in response["result"]:
self.test_result("Memory Search Tool", True)
return True
else:
self.test_result("Memory Search Tool", False, "Invalid response format")
return False
def test_python_execution(self):
"""Test execute_python tool"""
code = "print('Hello from test!'); result = 2 + 2; print(f'2 + 2 = {result}')"
response = self.make_mcp_request("tools/call", {
"name": "execute_python",
"arguments": {
"code": code,
"timeout": 10
}
})
if "error" in response:
self.test_result("Python Execution Tool", False, response["error"]["message"])
return False
if "result" in response and "content" in response["result"]:
# Check if execution was successful
content = response["result"]["content"][0]["text"]
try:
result_data = json.loads(content)
if result_data.get("success") and "Hello from test!" in result_data.get("stdout", ""):
self.test_result("Python Execution Tool", True)
return True
else:
self.test_result("Python Execution Tool", False, "Execution failed or unexpected output")
return False
except json.JSONDecodeError:
self.test_result("Python Execution Tool", False, "Invalid JSON response")
return False
else:
self.test_result("Python Execution Tool", False, "Invalid response format")
return False
def test_shell_execution(self):
"""Test execute_shell tool"""
response = self.make_mcp_request("tools/call", {
"name": "execute_shell",
"arguments": {
"command": "echo 'Test successful'",
"timeout": 5
}
})
if "error" in response:
self.test_result("Shell Execution Tool", False, response["error"]["message"])
return False
if "result" in response and "content" in response["result"]:
content = response["result"]["content"][0]["text"]
try:
result_data = json.loads(content)
if result_data.get("success") and "Test successful" in result_data.get("stdout", ""):
self.test_result("Shell Execution Tool", True)
return True
else:
self.test_result("Shell Execution Tool", False, "Command failed or unexpected output")
return False
except json.JSONDecodeError:
self.test_result("Shell Execution Tool", False, "Invalid JSON response")
return False
else:
self.test_result("Shell Execution Tool", False, "Invalid response format")
return False
def test_system_status(self):
"""Test get_system_status tool"""
response = self.make_mcp_request("tools/call", {
"name": "get_system_status",
"arguments": {}
})
if "error" in response:
self.test_result("System Status Tool", False, response["error"]["message"])
return False
if "result" in response and "content" in response["result"]:
content = response["result"]["content"][0]["text"]
try:
result_data = json.loads(content)
if result_data.get("success") and "server" in result_data:
self.test_result("System Status Tool", True)
return True
else:
self.test_result("System Status Tool", False, "Invalid status data")
return False
except json.JSONDecodeError:
self.test_result("System Status Tool", False, "Invalid JSON response")
return False
else:
self.test_result("System Status Tool", False, "Invalid response format")
return False
def test_invalid_method(self):
"""Test invalid method handling"""
response = self.make_mcp_request("invalid/method")
if "error" in response and response["error"]["code"] == -32601:
self.test_result("Invalid Method Handling", True)
return True
else:
self.test_result("Invalid Method Handling", False, "Should return method not found error")
return False
def test_invalid_tool(self):
"""Test invalid tool handling"""
response = self.make_mcp_request("tools/call", {
"name": "non_existent_tool",
"arguments": {}
})
if "error" in response and response["error"]["code"] == -32601:
self.test_result("Invalid Tool Handling", True)
return True
else:
self.test_result("Invalid Tool Handling", False, "Should return tool not found error")
return False
def run_performance_test(self):
"""Test server performance"""
print(f"\n🚀 Running performance tests...")
# Test response time
start_time = time.time()
response = self.make_mcp_request("tools/list")
end_time = time.time()
response_time = (end_time - start_time) * 1000 # Convert to milliseconds
if response_time < 500: # Should respond within 500ms
self.test_result(f"Response Time ({response_time:.1f}ms)", True)
else:
self.test_result(f"Response Time ({response_time:.1f}ms)", False, "Too slow")
# Test concurrent requests
import threading
import queue
results_queue = queue.Queue()
def make_concurrent_request():
try:
response = self.make_mcp_request("get_system_status")
results_queue.put("error" not in response)
except:
results_queue.put(False)
threads = []
for _ in range(10): # 10 concurrent requests
thread = threading.Thread(target=make_concurrent_request)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
successful_requests = sum(results_queue.get() for _ in range(10))
if successful_requests >= 8: # At least 80% should succeed
self.test_result(f"Concurrent Requests ({successful_requests}/10)", True)
else:
self.test_result(f"Concurrent Requests ({successful_requests}/10)", False, "Too many failed")
def run_all_tests(self):
"""Run all tests"""
print("🧪 FORUS Cortex Agent MCP Server Test Suite")
print("=" * 50)
# Basic connectivity tests
print("\n📡 Testing Basic Connectivity...")
self.test_server_info()
# MCP protocol tests
print("\n🔧 Testing MCP Protocol...")
self.test_initialize()
self.test_tools_list()
# Tool functionality tests
print("\n🛠️ Testing Tool Functions...")
self.test_memory_search()
self.test_python_execution()
self.test_shell_execution()
self.test_system_status()
# Error handling tests
print("\n⚠️ Testing Error Handling...")
self.test_invalid_method()
self.test_invalid_tool()
# Performance tests
self.run_performance_test()
# Summary
print("\n" + "=" * 50)
print("📊 Test Summary")
print("=" * 50)
total_tests = self.passed + self.failed
success_rate = (self.passed / total_tests) * 100 if total_tests > 0 else 0
print(f"✅ Passed: {self.passed}")
print(f"❌ Failed: {self.failed}")
print(f"📈 Success Rate: {success_rate:.1f}%")
if self.failed == 0:
print("\n🎉 All tests passed! MCP Server is working correctly.")
return True
else:
print(f"\n⚠️ {self.failed} test(s) failed. Check server configuration.")
return False
def main():
"""Main test runner"""
print("Starting FORUS MCP Server tests...")
print(f"Server URL: {SERVER_URL}")
print(f"MCP Endpoint: {MCP_ENDPOINT}")
tester = MCPTester()
success = tester.run_all_tests()
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()