89 lines
3.0 KiB
Python
89 lines
3.0 KiB
Python
import os
|
|
import shutil
|
|
import tempfile
|
|
import unittest
|
|
|
|
from meshchatx.src.backend.database.provider import DatabaseProvider
|
|
from meshchatx.src.backend.database.schema import DatabaseSchema
|
|
|
|
|
|
class TestDatabaseRobustness(unittest.TestCase):
|
|
def setUp(self):
|
|
self.test_dir = tempfile.mkdtemp()
|
|
self.db_path = os.path.join(self.test_dir, "test_meshchat.db")
|
|
# Ensure we start with a fresh provider instance
|
|
if hasattr(DatabaseProvider, "_instance"):
|
|
DatabaseProvider._instance = None
|
|
self.provider = DatabaseProvider.get_instance(self.db_path)
|
|
self.schema = DatabaseSchema(self.provider)
|
|
|
|
def tearDown(self):
|
|
self.provider.close_all()
|
|
if hasattr(DatabaseProvider, "_instance"):
|
|
DatabaseProvider._instance = None
|
|
shutil.rmtree(self.test_dir)
|
|
|
|
def test_missing_column_healing(self):
|
|
# 1. Create a "legacy" table without the peer_hash column
|
|
self.provider.execute("""
|
|
CREATE TABLE lxmf_messages (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
hash TEXT UNIQUE,
|
|
source_hash TEXT,
|
|
destination_hash TEXT
|
|
)
|
|
""")
|
|
|
|
# 2. Also need the config table so initialize doesn't fail on version check
|
|
self.provider.execute("""
|
|
CREATE TABLE config (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
key TEXT UNIQUE,
|
|
value TEXT
|
|
)
|
|
""")
|
|
self.provider.execute(
|
|
"INSERT INTO config (key, value) VALUES (?, ?)",
|
|
("database_version", "1"),
|
|
)
|
|
|
|
# 3. Attempt initialization.
|
|
# Previously this would crash with OperationalError: no such column: peer_hash
|
|
try:
|
|
self.schema.initialize()
|
|
except Exception as e:
|
|
self.fail(f"Initialization failed with missing column: {e}")
|
|
|
|
# 4. Verify the column was added
|
|
cursor = self.provider.execute("PRAGMA table_info(lxmf_messages)")
|
|
columns = [row[1] for row in cursor.fetchall()]
|
|
self.assertIn("peer_hash", columns)
|
|
self.assertIn("is_spam", columns)
|
|
|
|
def test_corrupt_config_initialization(self):
|
|
# 1. Create a database where the version is missing or garbled
|
|
self.provider.execute("""
|
|
CREATE TABLE config (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
key TEXT UNIQUE,
|
|
value TEXT
|
|
)
|
|
""")
|
|
# No version inserted
|
|
|
|
# 2. Initialization should still work
|
|
try:
|
|
self.schema.initialize()
|
|
except Exception as e:
|
|
self.fail(f"Initialization failed with missing version: {e}")
|
|
|
|
# 3. Version should now be set to LATEST
|
|
row = self.provider.fetchone(
|
|
"SELECT value FROM config WHERE key = 'database_version'",
|
|
)
|
|
self.assertEqual(int(row["value"]), self.schema.LATEST_VERSION)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|