agentcache / tests /test_migration.py
Yash030's picture
refactor: folder-based memory model replacing session-based storage
fbcb300
Raw
History Blame Contribute Delete
4.14 kB
"""Unit tests for migrate_sessions_to_folders (REQ-058–REQ-062)."""
import sys
import os
import pytest
import datetime
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from db import StateKV
from functions import migrate_sessions_to_folders, KV
def make_kv(tmp_path):
db_path = os.path.join(str(tmp_path), 'test.db')
return StateKV(db_path=db_path)
def seed_session(kv, session_id='sess_001', cwd='/home/user/proj', agent='kiro', obs_count=3):
"""Seed a legacy session with observations into the old schema."""
ts = datetime.datetime.utcnow().isoformat() + 'Z'
session = {
'id': session_id,
'project': cwd,
'cwd': cwd,
'agentId': agent,
'startedAt': ts,
'updatedAt': ts,
'status': 'completed',
}
kv.set(KV.sessions, session_id, session)
obs_ids = []
for i in range(obs_count):
obs_id = f'obs_{i}'
obs = {
'id': obs_id,
'sessionId': session_id,
'timestamp': ts,
'type': 'file_edit',
'title': f'Edit {i}',
'narrative': f'Edited file {i}',
'concepts': ['python'],
'files': [f'src/file_{i}.py'],
'importance': 5,
}
kv.set(KV.observations(session_id), obs_id, obs)
obs_ids.append(obs_id)
return obs_ids
class TestMigrateDryRun:
def test_dry_run_writes_nothing(self, tmp_path):
kv = make_kv(tmp_path)
seed_session(kv)
result = migrate_sessions_to_folders(kv, dry_run=True)
assert result['migrated_sessions'] > 0
assert result['migrated_observations'] > 0
# No folder obs should have been written
fp = 'home/user/proj'
obs = kv.list(KV.folder_obs(fp, 'kiro'))
assert len(obs) == 0
def test_dry_run_returns_counts(self, tmp_path):
kv = make_kv(tmp_path)
seed_session(kv, obs_count=5)
result = migrate_sessions_to_folders(kv, dry_run=True)
assert result['migrated_observations'] == 5
assert result['dry_run'] is True
class TestMigrateActual:
def test_migrates_observations(self, tmp_path):
kv = make_kv(tmp_path)
seed_session(kv, obs_count=3)
migrate_sessions_to_folders(kv, dry_run=False)
fp = 'home/user/proj'
obs = kv.list(KV.folder_obs(fp, 'kiro'))
assert len(obs) == 3
def test_skips_raw_observations(self, tmp_path):
kv = make_kv(tmp_path)
seed_session(kv, obs_count=2)
# Add a raw obs
kv.set(KV.observations('sess_001'), 'obs_0:raw', {
'id': 'obs_0:raw', 'sessionId': 'sess_001',
'timestamp': datetime.datetime.utcnow().isoformat() + 'Z',
})
result = migrate_sessions_to_folders(kv, dry_run=False)
# Raw obs should not be counted
assert result['migrated_observations'] == 2
def test_nondestructive(self, tmp_path):
kv = make_kv(tmp_path)
seed_session(kv)
migrate_sessions_to_folders(kv, dry_run=False)
# Old session data still there
session = kv.get(KV.sessions, 'sess_001')
assert session is not None
def test_unknown_fallback(self, tmp_path):
kv = make_kv(tmp_path)
# Session with no cwd or project
ts = datetime.datetime.utcnow().isoformat() + 'Z'
kv.set(KV.sessions, 'sess_no_path', {
'id': 'sess_no_path', 'startedAt': ts, 'updatedAt': ts, 'status': 'completed',
})
kv.set(KV.observations('sess_no_path'), 'obs_x', {
'id': 'obs_x', 'sessionId': 'sess_no_path',
'timestamp': ts, 'type': 'other', 'title': 'x', 'narrative': 'x',
})
result = migrate_sessions_to_folders(kv, dry_run=False)
# Should succeed with 'unknown' fallback
assert result['migrated_sessions'] >= 1
def test_returns_error_list(self, tmp_path):
kv = make_kv(tmp_path)
seed_session(kv)
result = migrate_sessions_to_folders(kv, dry_run=False)
assert 'errors' in result
assert isinstance(result['errors'], list)