- imptune/db/database.py: deferred SqliteDatabase with WAL + foreign_keys pragmas and init_db() - imptune/db/models.py: full schema (Client, Driver, Printer, Icon) for phases 1-5 - imptune/storage/driver_store.py: SHA256 content-addressed DriverStore with dedup - tests/test_db.py: 7 TDD tests covering all db and storage behaviors
142 lines
3.3 KiB
Python
142 lines
3.3 KiB
Python
"""Tests for database initialization and driver storage."""
|
|
import hashlib
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture
|
|
def db_env(tmp_path, monkeypatch):
|
|
"""Set up temp DATA_DIR and configure db to use temp paths."""
|
|
data_dir = tmp_path / "data"
|
|
data_dir.mkdir()
|
|
drivers_dir = data_dir / "drivers"
|
|
drivers_dir.mkdir()
|
|
db_path = str(data_dir / "imptune.db")
|
|
|
|
monkeypatch.setenv("DATA_DIR", str(data_dir))
|
|
|
|
import imptune.config as cfg
|
|
cfg.DATA_DIR = str(data_dir)
|
|
cfg.DB_PATH = db_path
|
|
cfg.DRIVERS_DIR = str(drivers_dir)
|
|
|
|
# Close and re-init the db with the temp path
|
|
from imptune.db.database import db
|
|
if not db.is_closed():
|
|
db.close()
|
|
|
|
return {
|
|
"data_dir": data_dir,
|
|
"drivers_dir": drivers_dir,
|
|
"db_path": db_path,
|
|
}
|
|
|
|
|
|
def test_create_tables(db_env):
|
|
"""init_db() creates all 4 tables in a fresh SQLite file."""
|
|
from imptune.db.database import db, init_db
|
|
|
|
if not db.is_closed():
|
|
db.close()
|
|
|
|
init_db()
|
|
|
|
tables = db.get_tables()
|
|
assert "client" in tables
|
|
assert "driver" in tables
|
|
assert "printer" in tables
|
|
assert "icon" in tables
|
|
|
|
db.close()
|
|
|
|
|
|
def test_wal_mode(db_env):
|
|
"""After init_db(), PRAGMA journal_mode returns 'wal'."""
|
|
from imptune.db.database import db, init_db
|
|
|
|
if not db.is_closed():
|
|
db.close()
|
|
|
|
init_db()
|
|
|
|
cursor = db.execute_sql("PRAGMA journal_mode;")
|
|
mode = cursor.fetchone()[0]
|
|
assert mode == "wal"
|
|
|
|
db.close()
|
|
|
|
|
|
def test_foreign_keys(db_env):
|
|
"""After init_db(), PRAGMA foreign_keys returns 1."""
|
|
from imptune.db.database import db, init_db
|
|
|
|
if not db.is_closed():
|
|
db.close()
|
|
|
|
init_db()
|
|
|
|
cursor = db.execute_sql("PRAGMA foreign_keys;")
|
|
value = cursor.fetchone()[0]
|
|
assert value == 1
|
|
|
|
db.close()
|
|
|
|
|
|
def test_idempotent(db_env):
|
|
"""Calling init_db() twice does not raise an error."""
|
|
from imptune.db.database import db, init_db
|
|
|
|
if not db.is_closed():
|
|
db.close()
|
|
|
|
init_db()
|
|
db.close()
|
|
init_db() # second call — must not raise
|
|
|
|
db.close()
|
|
|
|
|
|
def test_driver_store_save(db_env, tmp_path):
|
|
"""Saving bytes returns their SHA256 hex digest and creates the file."""
|
|
from imptune.storage.driver_store import DriverStore
|
|
|
|
drivers_dir = db_env["drivers_dir"]
|
|
store = DriverStore(str(drivers_dir))
|
|
|
|
data = b"test driver package content"
|
|
expected_sha256 = hashlib.sha256(data).hexdigest()
|
|
|
|
result = store.save(data)
|
|
|
|
assert result == expected_sha256
|
|
assert (drivers_dir / expected_sha256).exists()
|
|
|
|
|
|
def test_driver_store_dedup(db_env):
|
|
"""Saving the same bytes twice results in one file on disk."""
|
|
from imptune.storage.driver_store import DriverStore
|
|
|
|
drivers_dir = db_env["drivers_dir"]
|
|
store = DriverStore(str(drivers_dir))
|
|
|
|
data = b"duplicate driver data"
|
|
store.save(data)
|
|
store.save(data)
|
|
|
|
files = list(drivers_dir.iterdir())
|
|
assert len(files) == 1
|
|
|
|
|
|
def test_driver_store_get_path(db_env):
|
|
"""get_path(sha256) returns the correct file path."""
|
|
from imptune.storage.driver_store import DriverStore
|
|
|
|
drivers_dir = db_env["drivers_dir"]
|
|
store = DriverStore(str(drivers_dir))
|
|
|
|
sha256 = "abcdef1234567890" * 4 # 64 hex chars
|
|
path = store.get_path(sha256)
|
|
|
|
assert path == Path(str(drivers_dir)) / sha256
|