Record standby subscription events with signed durable receipts

This commit is contained in:
root
2026-10-21 09:57:46 +08:00
parent 9faae09851
commit d6eb25a0f6
13 changed files with 860 additions and 4 deletions
+82
View File
@@ -0,0 +1,82 @@
import importlib.util
from pathlib import Path
import sqlite3
import tempfile
import unittest
import hashlib
spec = importlib.util.spec_from_file_location("migration", Path(__file__).with_name("migrate_subscription_events.py"))
migration = importlib.util.module_from_spec(spec)
spec.loader.exec_module(migration)
class SubscriptionEventsMigrationTest(unittest.TestCase):
def test_explicit_backup_atomic_and_idempotent(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "main.db"
with sqlite3.connect(path) as db:
db.executescript("""
CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT);
CREATE TABLE sub_bind(key TEXT,user TEXT,user_id INTEGER);
CREATE TABLE sub_update_record(id INTEGER PRIMARY KEY,user_id INTEGER,time INTEGER);
INSERT INTO User VALUES(3,'alice');
INSERT INTO sub_bind VALUES('public-test-key','alice',3);
""")
dry = migration.migrate(path)
self.assertEqual(2, len(dry["tables_to_create"]))
with self.assertRaises(ValueError):
migration.migrate(path, True)
first = migration.migrate(path, True, True)
self.assertEqual("ok", first["integrity"])
self.assertEqual(0o600, Path(first["backup"]).stat().st_mode & 0o777)
with sqlite3.connect(first["backup"]) as db:
self.assertEqual(0, db.execute("SELECT count(*) FROM sqlite_master WHERE name='subscription_event_binding'").fetchone()[0])
with sqlite3.connect(path) as db:
row = db.execute("SELECT key_hash,user_id,user_name FROM subscription_event_binding").fetchone()
self.assertEqual((hashlib.sha256(b"public-test-key").hexdigest(), 3, "alice"), row)
db.execute("INSERT INTO subscription_event_receipt VALUES('id','hash','v2',0,'primary',1,'fingerprint','recorded')")
second = migration.migrate(path, True, True)
self.assertEqual([], second["tables_to_create"])
with sqlite3.connect(path) as db:
self.assertEqual(1, db.execute("SELECT count(*) FROM subscription_event_receipt").fetchone()[0])
self.assertEqual(1, db.execute("SELECT count(*) FROM subscription_event_binding").fetchone()[0])
def test_legacy_labels_without_user_ids_remain_null(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "main.db"
with sqlite3.connect(path) as db:
db.executescript("""
CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT);
CREATE TABLE sub_bind(key TEXT,user TEXT,user_id INTEGER);
CREATE TABLE sub_update_record(id INTEGER PRIMARY KEY,user_id INTEGER,time INTEGER);
INSERT INTO sub_bind VALUES('legacy-key','legacy-label',NULL);
""")
result = migration.migrate(path, True, True)
self.assertEqual(1, result["history_bindings"])
with sqlite3.connect(path) as db:
row = db.execute("SELECT key_hash,user_id,user_name FROM subscription_event_binding").fetchone()
self.assertEqual((hashlib.sha256(b"legacy-key").hexdigest(), None, "legacy-label"), row)
self.assertIsNone(db.execute("SELECT user_id FROM sub_bind").fetchone()[0])
self.assertEqual(0, db.execute("SELECT count(*) FROM User").fetchone()[0])
migration.migrate(path, True, True)
with sqlite3.connect(path) as db:
self.assertEqual(1, db.execute("SELECT count(*) FROM subscription_event_binding").fetchone()[0])
def test_orphan_binding_aborts_without_ddl(self):
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "main.db"
with sqlite3.connect(path) as db:
db.executescript("""
CREATE TABLE User(id INTEGER PRIMARY KEY,username TEXT);
CREATE TABLE sub_bind(key TEXT,user TEXT,user_id INTEGER);
CREATE TABLE sub_update_record(id INTEGER PRIMARY KEY,user_id INTEGER,time INTEGER);
INSERT INTO sub_bind VALUES('test','deleted',9);
""")
with self.assertRaises(ValueError):
migration.migrate(path, True, True)
with sqlite3.connect(path) as db:
self.assertEqual(0, db.execute("SELECT count(*) FROM sqlite_master WHERE name LIKE 'subscription_event_%'").fetchone()[0])
if __name__ == "__main__":
unittest.main()