"""Readers beside an agent open its files without writing to them (X6).""" import sqlite3 from pathlib import Path import pytest from nisse_core.state import readonly def wal_db(path: Path) -> sqlite3.Connection: conn = sqlite3.connect(path, isolation_level=None) conn.execute("PRAGMA journal_mode=WAL") conn.execute("CREATE TABLE t (v TEXT)") conn.execute("INSERT INTO t VALUES ('one')") return conn def test_a_closed_database_is_read_without_creating_any_file(tmp_path: Path) -> None: wal_db(tmp_path / "a.db").close() assert sorted(p.name for p in tmp_path.iterdir()) == ["a.db"] conn = readonly.connect(tmp_path / "a.db") assert conn.execute("SELECT v FROM t").fetchall()[0]["v"] == "one" conn.close() assert sorted(p.name for p in tmp_path.iterdir()) == ["a.db"] def test_a_live_database_is_read_as_its_writer_commits(tmp_path: Path) -> None: writer = wal_db(tmp_path / "a.db") conn = readonly.connect(tmp_path / "a.db") writer.execute("INSERT INTO t VALUES ('two')") assert [r["v"] for r in conn.execute("SELECT v FROM t")] == ["one", "two"] with pytest.raises(sqlite3.OperationalError): conn.execute("INSERT INTO t VALUES ('three')") conn.close() writer.execute("INSERT INTO t VALUES ('four')") # no lock left behind writer.close() def test_a_missing_file_is_an_error_not_a_new_database(tmp_path: Path) -> None: with pytest.raises(sqlite3.OperationalError): readonly.connect(tmp_path / "none.db") assert not (tmp_path / "none.db").exists()