informed-decision/docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py
tegwick e0359bcb6c Prepare purpose image release with bounded custody protocol and owner reviews
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 03:54:35 +02:00

47 lines
2.4 KiB
Python

import hashlib
from pathlib import Path
import sqlite3
import tempfile
import unittest
from sqlite_readonly import inspect_readonly
class PreOpenSchemaGate(unittest.TestCase):
def test_old_and_unknown_schemas_refuse_without_mutation(self):
with tempfile.TemporaryDirectory() as folder:
for version in (0, 1, 2, 3, 4, 6):
db = Path(folder) / (str(version) + '.sqlite')
with sqlite3.connect(db) as connection:
connection.execute('PRAGMA user_version=' + str(version))
before = hashlib.sha256(db.read_bytes()).hexdigest()
with self.assertRaises(ValueError):
inspect_readonly(db)
self.assertEqual(hashlib.sha256(db.read_bytes()).hexdigest(), before)
with sqlite3.connect(db) as connection:
self.assertEqual(connection.execute('PRAGMA user_version').fetchone()[0], version)
def test_schema5_frozen_snapshot_counts_and_integrity(self):
with tempfile.TemporaryDirectory() as folder:
db = Path(folder) / 'snapshot.sqlite'
with sqlite3.connect(db) as connection:
connection.executescript('PRAGMA user_version=5; CREATE TABLE lifecycle_records(x); CREATE TABLE lifecycle_events(x); CREATE TABLE lifecycle_pending(x); CREATE TABLE outbox(state); CREATE TABLE submissions(state); INSERT INTO lifecycle_records VALUES(1); INSERT INTO outbox VALUES("pending"); INSERT INTO submissions VALUES("confirmed");')
before = hashlib.sha256(db.read_bytes()).hexdigest()
proof = inspect_readonly(db)
self.assertEqual(proof['schema_version'], 5)
self.assertEqual(proof['lifecycle']['records'], 1)
self.assertEqual(proof['outbox'], {'pending': 1})
self.assertEqual(proof['submissions'], {'confirmed': 1})
self.assertEqual(proof['integrity'], 'ok')
self.assertFalse(proof['store_constructed'])
self.assertEqual(hashlib.sha256(db.read_bytes()).hexdigest(), before)
def test_missing_database_is_not_created(self):
with tempfile.TemporaryDirectory() as folder:
missing = Path(folder) / 'missing.sqlite'
with self.assertRaises(ValueError):
inspect_readonly(missing)
self.assertFalse(missing.exists())
if __name__ == '__main__':
unittest.main()