This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
recoll-modern/tests/storage/test_database.py
T

88 lines
3.0 KiB
Python

"""Tests for SQLite connection and transaction behavior."""
import sqlite3
from pathlib import Path
import pytest
from recoll_modern.domain.errors import AppError
from recoll_modern.indexing.paths import PathPolicyError
from recoll_modern.storage.database import Database
@pytest.fixture
def database(tmp_path: Path) -> Database:
"""Provide an isolated database for each test."""
return Database(tmp_path / "recoll-modern.sqlite3")
def test_connect_configures_sqlite_policy(database: Database) -> None:
"""Fail if a connection stops enforcing the required SQLite safeguards."""
connection = database.connect()
try:
assert connection.row_factory is sqlite3.Row
assert connection.execute("PRAGMA foreign_keys").fetchone()[0] == 1
assert connection.execute("PRAGMA journal_mode").fetchone()[0] == "wal"
assert connection.execute("PRAGMA busy_timeout").fetchone()[0] == 5000
finally:
connection.close()
def test_transaction_commits_and_closes_connection(database: Database) -> None:
"""Fail if a successful transaction loses data or leaks its connection."""
database.migrate()
with database.transaction() as transaction_connection:
transaction_connection.execute(
"INSERT INTO users VALUES (?, ?, ?, ?, ?, ?)",
("u1", "Ada", "ada", "hash", "2026-09-18T00:00:00+00:00", None),
)
check = database.connect()
try:
assert check.execute("SELECT username FROM users").fetchone()[0] == "Ada"
finally:
check.close()
assert transaction_connection is not None
with pytest.raises(sqlite3.ProgrammingError):
transaction_connection.execute("SELECT 1")
def test_transaction_rolls_back_and_closes_connection(database: Database) -> None:
"""Fail if an exception leaves a partial write or an open connection behind."""
database.migrate()
transaction_connection: sqlite3.Connection | None = None
with pytest.raises(RuntimeError, match="abort"):
with database.transaction() as current_connection:
transaction_connection = current_connection
current_connection.execute(
"INSERT INTO users VALUES (?, ?, ?, ?, ?, ?)",
("u1", "Ada", "ada", "hash", "2026-09-18T00:00:00+00:00", None),
)
raise RuntimeError("abort")
check = database.connect()
try:
assert check.execute("SELECT COUNT(*) FROM users").fetchone()[0] == 0
finally:
check.close()
assert transaction_connection is not None
with pytest.raises(sqlite3.ProgrammingError):
transaction_connection.execute("SELECT 1")
@pytest.mark.parametrize(
"error",
[AppError("example", "Expected error", 422), PathPolicyError("invalid_source")],
)
def test_transaction_preserves_application_exceptions(
database: Database, error: Exception
) -> None:
database.migrate()
with pytest.raises(type(error)) as caught:
with database.transaction():
raise error
assert caught.value is error