Repository navigation
Expand file tree
/
Copy pathtest_api_server.py
More file actions
214 lines (166 loc) · 7.33 KB
/
Copy pathtest_api_server.py
File metadata and controls
214 lines (166 loc) · 7.33 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
"""
Tests for MemEvolve API server.
"""
import pytest
import asyncio
from unittest.mock import Mock, AsyncMock
import json
from fastapi.testclient import TestClient
from memevolve.api.server import app, get_memory_system
from memevolve.memory_system import MemorySystem, MemorySystemConfig
@pytest.fixture
def test_memory_config():
"""Create a test memory configuration using real environment variables."""
from dotenv import load_dotenv
import os
load_dotenv() # Load .env file
# Use real environment variables with proper fallback hierarchy for memory calls
# MEMEVOLVE_MEMORY_BASE_URL if defined, else MEMEVOLVE_UPSTREAM_BASE_URL
llm_base_url = os.getenv("MEMEVOLVE_MEMORY_BASE_URL") or os.getenv(
"MEMEVOLVE_UPSTREAM_BASE_URL")
if not llm_base_url:
raise ValueError(
"LLM base URL must be configured in .env (MEMEVOLVE_MEMORY_BASE_URL or MEMEVOLVE_UPSTREAM_BASE_URL)")
return MemorySystemConfig(
memory_base_url=llm_base_url,
memory_api_key=os.getenv("MEMEVOLVE_MEMORY_API_KEY", ""),
storage_backend=None, # Use default
default_retrieval_top_k=3
)
@pytest.fixture
def mock_memory_system(test_memory_config):
"""Create a mock memory system."""
memory_system = Mock(spec=MemorySystem)
memory_system.config = test_memory_config
# Mock health metrics
health_mock = Mock()
health_mock.total_units = 5
health_mock.newest_unit_timestamp = "2024-01-01T00:00:00Z"
memory_system.get_health_metrics.return_value = health_mock
# Mock operation log
memory_system.get_operation_log.return_value = [
{"op": "encode"}, {"op": "retrieve"}]
# Mock query_memory
memory_system.query_memory.return_value = [
{"content": "Test memory 1", "score": 0.9},
{"content": "Test memory 2", "score": 0.8}
]
# Mock clear_operation_log
memory_system.clear_operation_log = Mock()
return memory_system
@pytest.fixture
def test_client(mock_memory_system):
"""Create a test client with mocked memory system."""
from unittest.mock import patch
# Set global variables for health check
import memevolve.api.server
original_memory = getattr(memevolve.api.server, '_memory_system_instance', None)
memevolve.api.server._memory_system_instance = mock_memory_system
# Mock the get_memory_system function where it's used
with patch('memevolve.api.server.get_memory_system', return_value=mock_memory_system):
client = TestClient(app)
yield client
# Restore
memevolve.api.server._memory_system_instance = original_memory
class TestAPIEndpoints:
"""Test API endpoints."""
def test_health_endpoint(self, test_client):
"""Test health check endpoint."""
response = test_client.get("/health")
assert response.status_code == 200
data = response.json()
assert "status" in data
assert data["memory_enabled"] is True
assert "memory_integration_enabled" in data
assert "upstream_url" in data
def test_memory_stats_endpoint(self, test_client, mock_memory_system):
"""Test memory stats endpoint."""
response = test_client.get("/memory/stats")
assert response.status_code == 200
data = response.json()
assert "total_experiences" in data
assert "retrieval_count" in data
assert data["total_experiences"] == 5
assert data["retrieval_count"] == 2
def test_memory_search_endpoint(self, test_client, mock_memory_system):
"""Test memory search endpoint."""
request_data = {
"query": "test query",
"limit": 5,
"include_metadata": False
}
response = test_client.post("/memory/search", json=request_data)
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
assert len(data) == 2
assert "content" in data[0]
assert "score" in data[0]
def test_memory_clear_endpoint(self, test_client, mock_memory_system):
"""Test memory clear endpoint."""
response = test_client.post("/memory/clear")
assert response.status_code == 200
data = response.json()
assert "message" in data
mock_memory_system.clear_operation_log.assert_called_once()
def test_memory_config_endpoint(self, test_client, mock_memory_system):
"""Test memory config endpoint."""
response = test_client.get("/memory/config")
assert response.status_code == 200
data = response.json()
assert "memory_base_url" in data
# Should match the configured memory LLM base URL from environment
import os
expected_url = os.getenv("MEMEVOLVE_MEMORY_BASE_URL") or os.getenv(
"MEMEVOLVE_UPSTREAM_BASE_URL")
assert data["memory_base_url"] == expected_url
def test_proxy_request_without_memory(self, test_client, monkeypatch):
"""Test proxy request when memory is disabled."""
# Temporarily disable memory
import memevolve.api.server
original_memory = memevolve.api.server._memory_system_instance
memevolve.api.server._memory_system_instance = None
try:
# Mock httpx client
mock_response = Mock()
mock_response.status_code = 200
mock_response.headers = {"content-type": "application/json"}
mock_response.aiter_bytes = AsyncMock(
return_value=[b'{"result": "test"}'])
with monkeypatch.context() as m:
mock_client = AsyncMock()
mock_client.request = AsyncMock(return_value=mock_response)
# Replace the http_client in the lifespan context
m.setattr("memevolve.api.server.http_client", mock_client)
# This would need more complex mocking for the full proxy test
# For now, just ensure the endpoint exists
response = test_client.get("/v1/models")
# Should return 503 since http_client is not initialized in test
assert response.status_code == 503
finally:
memevolve.api.server._memory_system_instance = original_memory
class TestMemoryIntegration:
"""Test memory integration functionality."""
def test_memory_disabled_endpoints(self):
"""Test endpoints when memory is disabled."""
from unittest.mock import patch
import memevolve.api.server as api_server
# Create a test client with no memory system
original_memory = getattr(
api_server, '_memory_system_instance', None)
api_server._memory_system_instance = None
with patch('memevolve.api.server.get_memory_system', return_value=None):
client = TestClient(app)
# Test memory endpoints return 503
response = client.get("/memory/stats")
assert response.status_code == 503
response = client.post("/memory/search", json={"query": "test"})
assert response.status_code == 503
response = client.post("/memory/clear")
assert response.status_code == 503
response = client.get("/memory/config")
assert response.status_code == 503
# Restore
api_server._memory_system_instance = original_memory
if __name__ == "__main__":
pytest.main([__file__])