-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_rag.py
More file actions
195 lines (148 loc) Β· 6.07 KB
/
Copy pathtest_rag.py
File metadata and controls
195 lines (148 loc) Β· 6.07 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
"""
Test script for the RAG (vector store) system.
"""
import asyncio
import os
import shutil
# Set mock env vars before importing app modules
os.environ["GEMINI_API_KEYS"] = "fake_key"
os.environ["APP_ID"] = "123"
os.environ["PRIVATE_KEY_PATH"] = "fake_path"
os.environ["WEBHOOK_SECRET"] = "fake_secret"
from app.core.vector_store import VectorStore, get_vector_store
def test_vector_store_basic():
"""Test basic vector store operations."""
print("=" * 60)
print("TEST: Vector Store Basic Operations")
print("=" * 60)
# Clean up test directory
test_dir = "./.test_vector_db"
if os.path.exists(test_dir):
shutil.rmtree(test_dir)
# Create vector store
store = VectorStore("test/repo", persist_dir=test_dir)
# Check initial stats
stats = store.get_stats()
print(f"\nπ Initial stats: {stats}")
assert stats["total_chunks"] == 0
# Add some chunks with mock embeddings
chunks = [
{"content": "def hello(): return 'world'", "type": "function", "name": "hello"},
{"content": "class User: pass", "type": "class", "name": "User"}
]
# Mock 768-dimensional embeddings (Gemini's dimension)
embeddings = [
[0.1] * 768,
[0.2] * 768
]
store.add_chunks("utils.py", chunks, embeddings, "hash123")
# Check stats after adding
stats = store.get_stats()
print(f"π After adding: {stats}")
assert stats["total_chunks"] == 2
assert stats["indexed_files"] == 1
print("\nβ
Basic operations test PASSED!")
# Clean up
shutil.rmtree(test_dir)
def test_vector_store_query():
"""Test vector similarity search."""
print("\n" + "=" * 60)
print("TEST: Vector Store Query")
print("=" * 60)
# Clean up test directory
test_dir = "./.test_vector_db"
if os.path.exists(test_dir):
shutil.rmtree(test_dir)
store = VectorStore("test/repo", persist_dir=test_dir)
# Add chunks with distinct embeddings
chunks = [
{"content": "def calculate_sum(a, b): return a + b", "type": "function", "name": "calculate_sum"},
{"content": "def calculate_product(a, b): return a * b", "type": "function", "name": "calculate_product"},
{"content": "class DatabaseConnection: pass", "type": "class", "name": "DatabaseConnection"}
]
# Create embeddings that make the sum functions similar
embeddings = [
[1.0, 0.0, 0.0] + [0.0] * 765, # calculate_sum
[0.9, 0.1, 0.0] + [0.0] * 765, # calculate_product (similar to sum)
[0.0, 0.0, 1.0] + [0.0] * 765, # DatabaseConnection (different)
]
store.add_chunks("math.py", chunks, embeddings, "hash456")
# Query with embedding similar to calculate_sum
query_embedding = [1.0, 0.0, 0.0] + [0.0] * 765
results = store.query(query_embedding, n_results=2)
print(f"\nπ Query results: {len(results)} found")
for r in results:
print(f" - {r['metadata']['name']}: distance={r['distance']:.4f}")
# The sum function should be first (most similar)
assert len(results) == 2
assert results[0]["metadata"]["name"] == "calculate_sum"
print("\nβ
Query test PASSED!")
# Clean up
shutil.rmtree(test_dir)
def test_incremental_update():
"""Test incremental update (file hash tracking)."""
print("\n" + "=" * 60)
print("TEST: Incremental Update")
print("=" * 60)
test_dir = "./.test_vector_db"
if os.path.exists(test_dir):
shutil.rmtree(test_dir)
store = VectorStore("test/repo", persist_dir=test_dir)
# Check if file needs update (should return True for new file)
content = "def foo(): pass"
needs_update = store.needs_update("new_file.py", content)
print(f"\nπ New file needs update: {needs_update}")
assert needs_update == True
# Add the file
chunks = [{"content": content, "type": "function", "name": "foo"}]
embeddings = [[0.5] * 768]
store.add_chunks("new_file.py", chunks, embeddings, store._compute_hash(content))
# Check if same content needs update (should return False)
needs_update = store.needs_update("new_file.py", content)
print(f"π Same content needs update: {needs_update}")
assert needs_update == False
# Check if modified content needs update (should return True)
modified_content = "def foo(): return 'bar'"
needs_update = store.needs_update("new_file.py", modified_content)
print(f"π Modified content needs update: {needs_update}")
assert needs_update == True
print("\nβ
Incremental update test PASSED!")
# Clean up
shutil.rmtree(test_dir)
def test_persistence():
"""Test that data persists across store instances."""
print("\n" + "=" * 60)
print("TEST: Persistence")
print("=" * 60)
test_dir = "./.test_vector_db"
if os.path.exists(test_dir):
shutil.rmtree(test_dir)
# Create store and add data
store1 = VectorStore("test/repo", persist_dir=test_dir)
chunks = [{"content": "persistent data", "type": "code", "name": "test"}]
embeddings = [[0.3] * 768]
store1.add_chunks("persistent.py", chunks, embeddings, "hash789")
print(f"\nπΎ Store 1 chunks: {store1.get_stats()['total_chunks']}")
# Create new store instance (should load persisted data)
store2 = VectorStore("test/repo", persist_dir=test_dir)
print(f"πΎ Store 2 chunks: {store2.get_stats()['total_chunks']}")
assert store2.get_stats()["total_chunks"] == 1
assert store2.get_stats()["indexed_files"] == 1
print("\nβ
Persistence test PASSED!")
# Clean up
shutil.rmtree(test_dir)
if __name__ == "__main__":
try:
test_vector_store_basic()
test_vector_store_query()
test_incremental_update()
test_persistence()
print("\n" + "=" * 60)
print("π ALL RAG TESTS PASSED!")
print("=" * 60)
except AssertionError as e:
print(f"\nβ TEST FAILED: {e}")
except Exception as e:
print(f"\nβ ERROR: {e}")
import traceback
traceback.print_exc()