chore: initialize EverOS 1.0.0
md-first memory extraction framework for AI agents. Markdown is the single source of truth; SQLite holds state and LanceDB provides the rebuildable vector + BM25 + scalar index. The codebase follows a single-direction DDD layering (entrypoints -> service -> memory -> infra, with component / core / config cross-cutting) enforced by import-linter. Engineering surface: - Coding conventions in .claude/rules/ (path-scoped) and workflows in .claude/skills/ (/commit, /new-branch, /pr). - GitHub Actions CI runs make lint + test + integration; pre-commit mirrors the gates locally (ruff, hygiene hooks, gitlint commit-msg). - Commit messages follow Conventional Commits, enforced by gitlint. - make lint also enforces datetime two-zone discipline and OpenAPI drift.
This commit is contained in:
144
tests/unit/test_infra/test_ome/test_storage.py
Normal file
144
tests/unit/test_infra/test_ome/test_storage.py
Normal file
@ -0,0 +1,144 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import aiosqlite
|
||||
import pytest
|
||||
|
||||
from everos.infra.ome._stores.storage import OMEStorage
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_creates_db_and_tables(tmp_path: Path) -> None:
|
||||
db = tmp_path / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
|
||||
assert db.exists()
|
||||
async with aiosqlite.connect(db) as conn:
|
||||
cur = await conn.execute(
|
||||
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
|
||||
)
|
||||
names = {row[0] for row in await cur.fetchall()}
|
||||
assert {"counter_store", "idle_store", "run_record"}.issubset(names)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_applies_pragmas(tmp_path: Path) -> None:
|
||||
db = tmp_path / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
|
||||
async with aiosqlite.connect(db) as conn:
|
||||
cur = await conn.execute("PRAGMA journal_mode")
|
||||
mode = (await cur.fetchone())[0]
|
||||
assert mode == "wal"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_init_is_idempotent(tmp_path: Path) -> None:
|
||||
db = tmp_path / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
await storage.init() # second call must not raise
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_creates_parent_dir(tmp_path: Path) -> None:
|
||||
db = tmp_path / "nested" / "dir" / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
assert db.exists()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_connect_applies_per_connection_pragmas(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""``synchronous`` and ``cache_size`` are per-connection PRAGMAs:
|
||||
SQLite resets them to defaults on every new connection. The
|
||||
``OMEStorage.connect`` wrapper must re-apply them or the module
|
||||
docstring's promise is silently broken.
|
||||
"""
|
||||
db = tmp_path / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
|
||||
async with storage.connect() as conn:
|
||||
sync_row = await (await conn.execute("PRAGMA synchronous")).fetchone()
|
||||
cache_row = await (await conn.execute("PRAGMA cache_size")).fetchone()
|
||||
busy_row = await (await conn.execute("PRAGMA busy_timeout")).fetchone()
|
||||
|
||||
# synchronous: 0=OFF, 1=NORMAL, 2=FULL, 3=EXTRA
|
||||
assert sync_row[0] == 1
|
||||
# cache_size: negative value is "kibibytes of memory"
|
||||
assert cache_row[0] == -65536
|
||||
# busy_timeout: ms before SQLITE_BUSY is raised on contended writes
|
||||
assert busy_row[0] == 5000
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_raw_aiosqlite_connect_does_not_carry_per_conn_pragmas(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""Sanity check that documents why :meth:`OMEStorage.connect` exists:
|
||||
opening the same db with raw ``aiosqlite.connect`` yields a connection
|
||||
where ``synchronous`` is at SQLite's default (FULL=2), not NORMAL.
|
||||
"""
|
||||
db = tmp_path / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
|
||||
async with aiosqlite.connect(db) as conn:
|
||||
sync_row = await (await conn.execute("PRAGMA synchronous")).fetchone()
|
||||
|
||||
assert sync_row[0] == 2 # default FULL — confirms scope is per-connection
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_transaction_commits_on_success(tmp_path: Path) -> None:
|
||||
db = tmp_path / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
|
||||
async with storage.transaction() as conn:
|
||||
await conn.execute(
|
||||
"INSERT INTO counter_store (strategy_name, bucket_key, counter) "
|
||||
"VALUES (?, ?, ?)",
|
||||
("s", "u1", 42),
|
||||
)
|
||||
|
||||
async with storage.connect() as conn:
|
||||
cur = await conn.execute(
|
||||
"SELECT counter FROM counter_store WHERE strategy_name=? AND bucket_key=?",
|
||||
("s", "u1"),
|
||||
)
|
||||
row = await cur.fetchone()
|
||||
assert row is not None and row[0] == 42
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_storage_transaction_rolls_back_on_exception(tmp_path: Path) -> None:
|
||||
db = tmp_path / "ome.db"
|
||||
storage = OMEStorage(db_path=db)
|
||||
await storage.init()
|
||||
|
||||
class _BoomError(Exception):
|
||||
pass
|
||||
|
||||
with pytest.raises(_BoomError):
|
||||
async with storage.transaction() as conn:
|
||||
await conn.execute(
|
||||
"INSERT INTO counter_store (strategy_name, bucket_key, counter) "
|
||||
"VALUES (?, ?, ?)",
|
||||
("s", "u1", 42),
|
||||
)
|
||||
raise _BoomError
|
||||
|
||||
async with storage.connect() as conn:
|
||||
cur = await conn.execute(
|
||||
"SELECT counter FROM counter_store WHERE strategy_name=? AND bucket_key=?",
|
||||
("s", "u1"),
|
||||
)
|
||||
row = await cur.fetchone()
|
||||
assert row is None
|
||||
Reference in New Issue
Block a user