mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
55d675e278
Signed-off-by: phernandez <paul@basicmachines.co> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
131 lines
4.4 KiB
Python
131 lines
4.4 KiB
Python
"""Task scheduler semantic indexing tests."""
|
|
|
|
import asyncio
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from basic_memory.config import BasicMemoryConfig, ProjectConfig
|
|
from basic_memory.deps.services import get_task_scheduler
|
|
|
|
|
|
class StubEntityService:
|
|
def __init__(self) -> None:
|
|
self.reindexed: list[int] = []
|
|
|
|
async def reindex_entity(self, entity_id: int) -> None:
|
|
self.reindexed.append(entity_id)
|
|
|
|
|
|
class StubSyncService:
|
|
def __init__(self) -> None:
|
|
self.resolved: list[int] = []
|
|
self.synced: list[tuple[str, str, bool]] = []
|
|
|
|
async def resolve_relations(self, entity_id: int) -> None:
|
|
self.resolved.append(entity_id)
|
|
|
|
async def sync(self, home: Path, name: str, force_full: bool = False) -> None:
|
|
self.synced.append((str(home), name, force_full))
|
|
|
|
|
|
class StubSearchService:
|
|
def __init__(self) -> None:
|
|
self.vector_synced: list[int] = []
|
|
self.reindexed_project = False
|
|
|
|
async def sync_entity_vectors(self, entity_id: int) -> None:
|
|
self.vector_synced.append(entity_id)
|
|
|
|
async def reindex_all(self) -> None:
|
|
self.reindexed_project = True
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_reindex_entity_task_chains_vector_sync_when_semantic_enabled(tmp_path):
|
|
"""Reindex task should enqueue vector sync when semantic mode is enabled."""
|
|
entity_service = StubEntityService()
|
|
sync_service = StubSyncService()
|
|
search_service = StubSearchService()
|
|
app_config = BasicMemoryConfig(
|
|
env="test",
|
|
projects={"test-project": str(tmp_path)},
|
|
default_project="test-project",
|
|
semantic_search_enabled=True,
|
|
)
|
|
project_config = ProjectConfig(name="test-project", home=tmp_path)
|
|
|
|
scheduler = await get_task_scheduler(
|
|
entity_service=entity_service,
|
|
sync_service=sync_service,
|
|
search_service=search_service,
|
|
project_config=project_config,
|
|
app_config=app_config,
|
|
)
|
|
# Enable background tasks for this test — uses stubs, no real DB race risk
|
|
scheduler._test_mode = False # pyright: ignore [reportAttributeAccessIssue]
|
|
scheduler.schedule("reindex_entity", entity_id=42)
|
|
await asyncio.sleep(0.05)
|
|
|
|
assert entity_service.reindexed == [42]
|
|
assert search_service.vector_synced == [42]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_reindex_entity_task_skips_vector_sync_when_semantic_disabled(tmp_path):
|
|
"""Reindex task should not enqueue vector sync when semantic mode is disabled."""
|
|
entity_service = StubEntityService()
|
|
sync_service = StubSyncService()
|
|
search_service = StubSearchService()
|
|
app_config = BasicMemoryConfig(
|
|
env="test",
|
|
projects={"test-project": str(tmp_path)},
|
|
default_project="test-project",
|
|
semantic_search_enabled=False,
|
|
)
|
|
project_config = ProjectConfig(name="test-project", home=tmp_path)
|
|
|
|
scheduler = await get_task_scheduler(
|
|
entity_service=entity_service,
|
|
sync_service=sync_service,
|
|
search_service=search_service,
|
|
project_config=project_config,
|
|
app_config=app_config,
|
|
)
|
|
# Enable background tasks for this test — uses stubs, no real DB race risk
|
|
scheduler._test_mode = False # pyright: ignore [reportAttributeAccessIssue]
|
|
scheduler.schedule("reindex_entity", entity_id=42)
|
|
await asyncio.sleep(0.05)
|
|
|
|
assert entity_service.reindexed == [42]
|
|
assert search_service.vector_synced == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sync_entity_vectors_task_maps_to_search_service(tmp_path):
|
|
"""Explicit sync_entity_vectors task should call SearchService sync method."""
|
|
entity_service = StubEntityService()
|
|
sync_service = StubSyncService()
|
|
search_service = StubSearchService()
|
|
app_config = BasicMemoryConfig(
|
|
env="test",
|
|
projects={"test-project": str(tmp_path)},
|
|
default_project="test-project",
|
|
semantic_search_enabled=True,
|
|
)
|
|
project_config = ProjectConfig(name="test-project", home=tmp_path)
|
|
|
|
scheduler = await get_task_scheduler(
|
|
entity_service=entity_service,
|
|
sync_service=sync_service,
|
|
search_service=search_service,
|
|
project_config=project_config,
|
|
app_config=app_config,
|
|
)
|
|
# Enable background tasks for this test — uses stubs, no real DB race risk
|
|
scheduler._test_mode = False # pyright: ignore [reportAttributeAccessIssue]
|
|
scheduler.schedule("sync_entity_vectors", entity_id=7)
|
|
await asyncio.sleep(0.05)
|
|
|
|
assert search_service.vector_synced == [7]
|