Skip to content

Commit 4a42c82

Browse files
committed
test: fix ChromaDB SharedSystemClient collision in integration tests
Section 0d added anonymized_telemetry=False to ChromaDBAdapter. Three integration tests in test_working_memory_cleanup.py mixed raw chromadb.PersistentClient(path=...) calls (default settings) with ChromaDBAdapter(...) (anonymized_telemetry=False) at the same path. ChromaDB's SharedSystemClient caches (path -> settings) per process and rejects the second construction with "An instance of Chroma already exists for {path} with different settings." Tests passed locally when run in isolation (each test process starts fresh) but CI's full-suite run hit the cache collision. Fix: add a module-level _chroma_client(path) helper that passes the matching Settings(anonymized_telemetry=False). Replace all raw PersistentClient(path=...) calls with the helper so raw clients and adapter clients share identical Settings. Verified locally: 621 passed, 1 skipped, 0 failed (full test tree).
1 parent 2c5a4fd commit 4a42c82

1 file changed

Lines changed: 28 additions & 13 deletions

File tree

ui-implementation/src-tauri/backend/tests/integration/test_working_memory_cleanup.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,25 @@
2121
sys.path.insert(0, str(backend_path))
2222

2323
import chromadb
24+
from chromadb.config import Settings as ChromaSettings
2425
from modules.memory.chromadb_adapter import ChromaDBAdapter
2526
from modules.memory.promotion_service import PromotionService
2627

2728

29+
# v0.3.2 Section 0d added anonymized_telemetry=False to ChromaDBAdapter.
30+
# ChromaDB's SharedSystemClient caches (path -> settings) within a process
31+
# and rejects subsequent clients at the same path with different settings.
32+
# Tests that mix raw chromadb.PersistentClient(...) with ChromaDBAdapter(...)
33+
# must pass the matching Settings on the raw call or the second construction
34+
# raises "An instance of Chroma already exists for {path} with different
35+
# settings." This helper standardizes the raw client to match the adapter.
36+
def _chroma_client(path):
37+
return chromadb.PersistentClient(
38+
path=path,
39+
settings=ChromaSettings(anonymized_telemetry=False),
40+
)
41+
42+
2843
class TestWorkingMemoryCleanupPersistence:
2944
"""Test that working memory cleanup persists to disk."""
3045

@@ -65,7 +80,7 @@ def test_cleanup_deletes_old_working_memories(self, temp_chromadb_path):
6580
Test that working memories >24h old are deleted.
6681
"""
6782
# Step 1: Create ChromaDB with old working memories
68-
client1 = chromadb.PersistentClient(path=temp_chromadb_path)
83+
client1 = _chroma_client(temp_chromadb_path)
6984

7085
# Create test memories - some old, some new
7186
self._create_working_memory_with_age(client1, "roampal_working", "working_old_1", age_hours=30, score=0.5)
@@ -79,7 +94,7 @@ def test_cleanup_deletes_old_working_memories(self, temp_chromadb_path):
7994
del client1
8095

8196
# Step 2: Open new client and run cleanup
82-
client2 = chromadb.PersistentClient(path=temp_chromadb_path)
97+
client2 = _chroma_client(temp_chromadb_path)
8398
working = client2.get_collection("roampal_working", embedding_function=None)
8499

85100
# Simulate what promotion_service does - delete items > 24h old
@@ -104,7 +119,7 @@ def test_cleanup_deletes_old_working_memories(self, temp_chromadb_path):
104119
del client2
105120

106121
# Step 3: Verify deletion persisted
107-
client3 = chromadb.PersistentClient(path=temp_chromadb_path)
122+
client3 = _chroma_client(temp_chromadb_path)
108123
working = client3.get_collection("roampal_working", embedding_function=None)
109124

110125
final_count = working.count()
@@ -129,7 +144,7 @@ def test_cleanup_with_chromadb_adapter(self, temp_chromadb_path):
129144
asyncio.run(adapter.initialize(collection_name="roampal_working"))
130145

131146
# Create test memories directly in ChromaDB
132-
client = chromadb.PersistentClient(path=temp_chromadb_path)
147+
client = _chroma_client(temp_chromadb_path)
133148
self._create_working_memory_with_age(client, "roampal_working", "working_old", age_hours=30, score=0.5)
134149
self._create_working_memory_with_age(client, "roampal_working", "working_new", age_hours=2, score=0.5)
135150
del client
@@ -157,7 +172,7 @@ def test_cleanup_with_chromadb_adapter(self, temp_chromadb_path):
157172
asyncio.run(adapter2.cleanup())
158173

159174
# Verify persistence with new client
160-
client3 = chromadb.PersistentClient(path=temp_chromadb_path)
175+
client3 = _chroma_client(temp_chromadb_path)
161176
working = client3.get_collection("roampal_working", embedding_function=None)
162177
final_count = working.count()
163178
assert final_count == 1, f"Deletion should persist - expected 1, got {final_count}"
@@ -168,7 +183,7 @@ def test_chromadb_1x_auto_persists_deletes(self, temp_chromadb_path):
168183
This is the root cause fix for v0.2.10.
169184
"""
170185
# Create initial data
171-
client1 = chromadb.PersistentClient(path=temp_chromadb_path)
186+
client1 = _chroma_client(temp_chromadb_path)
172187
collection = client1.get_or_create_collection("test_persist", embedding_function=None)
173188

174189
collection.add(
@@ -189,7 +204,7 @@ def test_chromadb_1x_auto_persists_deletes(self, temp_chromadb_path):
189204
del client1
190205

191206
# Reopen and verify deletion persisted
192-
client2 = chromadb.PersistentClient(path=temp_chromadb_path)
207+
client2 = _chroma_client(temp_chromadb_path)
193208
collection = client2.get_collection("test_persist", embedding_function=None)
194209

195210
final_count = collection.count()
@@ -241,7 +256,7 @@ def test_promotion_service_cleanup_on_startup(self, temp_chromadb_path):
241256
import asyncio
242257

243258
# Step 1: Create ChromaDB with old working memories
244-
client1 = chromadb.PersistentClient(path=temp_chromadb_path)
259+
client1 = _chroma_client(temp_chromadb_path)
245260

246261
# Create memories: 2 old (should be cleaned), 1 new (should stay)
247262
self._create_working_memory_with_age(client1, "roampal_working", "working_old_1", age_hours=30, score=0.3)
@@ -294,7 +309,7 @@ async def mock_embed(text):
294309
asyncio.run(history_adapter.cleanup())
295310

296311
# Step 4: Verify deletion persisted to disk
297-
client2 = chromadb.PersistentClient(path=temp_chromadb_path)
312+
client2 = _chroma_client(temp_chromadb_path)
298313
working = client2.get_collection("roampal_working", embedding_function=None)
299314

300315
final_count = working.count()
@@ -313,7 +328,7 @@ def test_promotion_service_promotes_valuable_memories(self, temp_chromadb_path):
313328
import asyncio
314329

315330
# Create working memories with different values
316-
client1 = chromadb.PersistentClient(path=temp_chromadb_path)
331+
client1 = _chroma_client(temp_chromadb_path)
317332

318333
# This one should be PROMOTED (high score, high uses, old)
319334
self._create_working_memory_with_age(client1, "roampal_working", "working_promote_me",
@@ -360,7 +375,7 @@ async def mock_embed(text):
360375
asyncio.run(history_adapter.cleanup())
361376

362377
# Verify persistence
363-
client2 = chromadb.PersistentClient(path=temp_chromadb_path)
378+
client2 = _chroma_client(temp_chromadb_path)
364379
working = client2.get_collection("roampal_working", embedding_function=None)
365380
history = client2.get_collection("roampal_history", embedding_function=None)
366381

@@ -446,7 +461,7 @@ def test_schema_migration_adds_topic_columns(self, temp_chromadb_path):
446461
import sqlite3
447462

448463
# Step 1: Create a ChromaDB database
449-
client1 = chromadb.PersistentClient(path=temp_chromadb_path)
464+
client1 = _chroma_client(temp_chromadb_path)
450465
client1.get_or_create_collection("test", embedding_function=None)
451466
del client1
452467

@@ -473,7 +488,7 @@ def test_schema_migration_adds_topic_columns(self, temp_chromadb_path):
473488
# The key is that opening with ChromaDB 1.x doesn't crash
474489

475490
# Step 4: Verify ChromaDB can still be opened after schema is established
476-
client2 = chromadb.PersistentClient(path=temp_chromadb_path)
491+
client2 = _chroma_client(temp_chromadb_path)
477492
collection = client2.get_collection("test", embedding_function=None)
478493
assert collection is not None, "Should be able to open collection after migration"
479494

0 commit comments

Comments
 (0)