"""Integration tests for src/my_deepagent/persistence/checkpointer.py.""" from __future__ import annotations import sqlite3 from pathlib import Path from my_deepagent.persistence.checkpointer import get_checkpointer_ctx class TestGetCheckpointerCtx: """Tests for the get_checkpointer_ctx context manager.""" def test_ctx_yields_saver_and_cleans_up(self, tmp_path: Path) -> None: """Entering the context yields a SqliteSaver; exiting releases the connection.""" db_path = tmp_path / "ck.db" with get_checkpointer_ctx(db_path) as saver: assert saver is not None # The DB file must exist while inside the context. assert db_path.exists() # After context exit the file must still exist (not deleted). assert db_path.exists() def test_db_file_created_on_enter(self, tmp_path: Path) -> None: """The sqlite file is created when the context is entered.""" db_path = tmp_path / "nested" / "dir" / "ck.db" assert not db_path.exists() with get_checkpointer_ctx(db_path): assert db_path.exists() def test_parent_dir_created_if_missing(self, tmp_path: Path) -> None: """Parent directory is created automatically even if it does not exist.""" db_path = tmp_path / "a" / "b" / "c" / "ck.db" assert not db_path.parent.exists() with get_checkpointer_ctx(db_path): assert db_path.parent.exists() def test_connection_released_after_ctx_exit(self, tmp_path: Path) -> None: """After exiting the context manager, another process/connection can open the DB.""" db_path = tmp_path / "ck.db" with get_checkpointer_ctx(db_path): pass # enter and exit # If the connection were leaked (not closed), WAL mode can still allow reads, # but we verify by opening with a fresh sqlite3 connection — this must succeed. with sqlite3.connect(str(db_path)) as conn: cur = conn.execute("SELECT name FROM sqlite_master WHERE type='table'") # LangGraph creates its checkpoint tables; result must be a list (not error). tables = [row[0] for row in cur.fetchall()] assert isinstance(tables, list) def test_meta_and_checkpoint_db_no_lock_conflict(self, tmp_path: Path) -> None: """Using two separate DB files in the same directory causes no locking conflict.""" meta_db = tmp_path / "meta.db" ck_db = tmp_path / "checkpoints.db" # Simulate concurrent use: open both within the same scope. with get_checkpointer_ctx(ck_db) as saver: # Write something to the meta DB while the checkpointer holds its connection. with sqlite3.connect(str(meta_db)) as conn: conn.execute("CREATE TABLE IF NOT EXISTS kv (k TEXT PRIMARY KEY, v TEXT)") conn.execute("INSERT OR REPLACE INTO kv VALUES ('key', 'value')") conn.commit() assert saver is not None # Both files must exist and be independently readable. assert meta_db.exists() assert ck_db.exists() with sqlite3.connect(str(meta_db)) as conn: row = conn.execute("SELECT v FROM kv WHERE k='key'").fetchone() assert row is not None assert row[0] == "value"